First import
[xorg_rtime.git] / xorg-server-1.4 / hw / darwin / quartz / pseudoramiX.c
blob7ba6d5a15fb5b81800faa0bc7e4fc4025fa643e8
1 /*
2 * Minimal implementation of PanoramiX/Xinerama
4 * This is used in rootless mode where the underlying window server
5 * already provides an abstracted view of multiple screens as one
6 * large screen area.
8 * This code is largely based on panoramiX.c, which contains the
9 * following copyright notice:
11 /*****************************************************************
12 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software.
19 The above copyright notice and this permission notice shall be included in
20 all copies or substantial portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
26 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
28 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 Except as contained in this notice, the name of Digital Equipment Corporation
31 shall not be used in advertising or otherwise to promote the sale, use or other
32 dealings in this Software without prior written authorization from Digital
33 Equipment Corporation.
34 ******************************************************************/
36 #include "pseudoramiX.h"
37 #ifdef HAVE_XORG_CONFIG_H
38 #include <xorg-config.h>
39 #endif
40 #include "extnsionst.h"
41 #include "dixstruct.h"
42 #include "window.h"
43 #include <X11/extensions/panoramiXproto.h>
44 #include "globals.h"
46 extern int ProcPanoramiXQueryVersion (ClientPtr client);
48 static void PseudoramiXResetProc(ExtensionEntry *extEntry);
50 static int ProcPseudoramiXQueryVersion(ClientPtr client);
51 static int ProcPseudoramiXGetState(ClientPtr client);
52 static int ProcPseudoramiXGetScreenCount(ClientPtr client);
53 static int ProcPseudoramiXGetScreenSize(ClientPtr client);
54 static int ProcPseudoramiXIsActive(ClientPtr client);
55 static int ProcPseudoramiXQueryScreens(ClientPtr client);
56 static int ProcPseudoramiXDispatch(ClientPtr client);
58 static int SProcPseudoramiXQueryVersion(ClientPtr client);
59 static int SProcPseudoramiXGetState(ClientPtr client);
60 static int SProcPseudoramiXGetScreenCount(ClientPtr client);
61 static int SProcPseudoramiXGetScreenSize(ClientPtr client);
62 static int SProcPseudoramiXIsActive(ClientPtr client);
63 static int SProcPseudoramiXQueryScreens(ClientPtr client);
64 static int SProcPseudoramiXDispatch(ClientPtr client);
67 typedef struct {
68 int x;
69 int y;
70 int w;
71 int h;
72 } PseudoramiXScreenRec;
74 static PseudoramiXScreenRec *pseudoramiXScreens = NULL;
75 static int pseudoramiXScreensAllocated = 0;
76 static int pseudoramiXNumScreens = 0;
77 static unsigned long pseudoramiXGeneration = 0;
80 // Add a PseudoramiX screen.
81 // The rest of the X server will know nothing about this screen.
82 // Can be called before or after extension init.
83 // Screens must be re-added once per generation.
84 void
85 PseudoramiXAddScreen(int x, int y, int w, int h)
87 PseudoramiXScreenRec *s;
89 if (noPseudoramiXExtension) return;
91 if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) {
92 pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1;
93 pseudoramiXScreens = xrealloc(pseudoramiXScreens,
94 pseudoramiXScreensAllocated *
95 sizeof(PseudoramiXScreenRec));
98 s = &pseudoramiXScreens[pseudoramiXNumScreens++];
99 s->x = x;
100 s->y = y;
101 s->w = w;
102 s->h = h;
106 // Initialize PseudoramiX.
107 // Copied from PanoramiXExtensionInit
108 void PseudoramiXExtensionInit(int argc, char *argv[])
110 Bool success = FALSE;
111 ExtensionEntry *extEntry;
113 if (noPseudoramiXExtension) return;
115 /* Even with only one screen we need to enable PseudoramiX to allow
116 dynamic screen configuration changes. */
117 #if 0
118 if (pseudoramiXNumScreens == 1) {
119 // Only one screen - disable Xinerama extension.
120 noPseudoramiXExtension = TRUE;
121 return;
123 #endif
125 // The server must not run the PanoramiX operations.
126 noPanoramiXExtension = TRUE;
128 if (pseudoramiXGeneration != serverGeneration) {
129 extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
130 ProcPseudoramiXDispatch,
131 SProcPseudoramiXDispatch,
132 PseudoramiXResetProc,
133 StandardMinorOpcode);
134 if (!extEntry) {
135 ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n");
136 } else {
137 pseudoramiXGeneration = serverGeneration;
138 success = TRUE;
142 if (!success) {
143 ErrorF("%s Extension (PseudoramiX) failed to initialize\n",
144 PANORAMIX_PROTOCOL_NAME);
145 return;
150 void PseudoramiXResetScreens(void)
152 pseudoramiXNumScreens = 0;
156 static void PseudoramiXResetProc(ExtensionEntry *extEntry)
158 PseudoramiXResetScreens();
162 // was PanoramiX
163 static int ProcPseudoramiXQueryVersion(ClientPtr client)
165 return ProcPanoramiXQueryVersion(client);
169 // was PanoramiX
170 static int ProcPseudoramiXGetState(ClientPtr client)
172 REQUEST(xPanoramiXGetStateReq);
173 WindowPtr pWin;
174 xPanoramiXGetStateReply rep;
175 register int n, rc;
177 REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
178 rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess);
179 if (rc != Success)
180 return rc;
182 rep.type = X_Reply;
183 rep.length = 0;
184 rep.sequenceNumber = client->sequence;
185 rep.state = !noPseudoramiXExtension;
186 if (client->swapped) {
187 swaps (&rep.sequenceNumber, n);
188 swapl (&rep.length, n);
189 swaps (&rep.state, n);
191 WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
192 return client->noClientException;
196 // was PanoramiX
197 static int ProcPseudoramiXGetScreenCount(ClientPtr client)
199 REQUEST(xPanoramiXGetScreenCountReq);
200 WindowPtr pWin;
201 xPanoramiXGetScreenCountReply rep;
202 register int n, rc;
204 REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
205 rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess);
206 if (rc != Success)
207 return rc;
209 rep.type = X_Reply;
210 rep.length = 0;
211 rep.sequenceNumber = client->sequence;
212 rep.ScreenCount = pseudoramiXNumScreens;
213 if (client->swapped) {
214 swaps (&rep.sequenceNumber, n);
215 swapl (&rep.length, n);
216 swaps (&rep.ScreenCount, n);
218 WriteToClient (client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
219 return client->noClientException;
223 // was PanoramiX
224 static int ProcPseudoramiXGetScreenSize(ClientPtr client)
226 REQUEST(xPanoramiXGetScreenSizeReq);
227 WindowPtr pWin;
228 xPanoramiXGetScreenSizeReply rep;
229 register int n, rc;
231 REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
232 rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess);
233 if (rc != Success)
234 return rc;
236 rep.type = X_Reply;
237 rep.length = 0;
238 rep.sequenceNumber = client->sequence;
239 /* screen dimensions */
240 rep.width = pseudoramiXScreens[stuff->screen].w;
241 // was panoramiXdataPtr[stuff->screen].width;
242 rep.height = pseudoramiXScreens[stuff->screen].h;
243 // was panoramiXdataPtr[stuff->screen].height;
244 if (client->swapped) {
245 swaps (&rep.sequenceNumber, n);
246 swapl (&rep.length, n);
247 swaps (&rep.width, n);
248 swaps (&rep.height, n);
250 WriteToClient (client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
251 return client->noClientException;
255 // was Xinerama
256 static int ProcPseudoramiXIsActive(ClientPtr client)
258 /* REQUEST(xXineramaIsActiveReq); */
259 xXineramaIsActiveReply rep;
261 REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
263 rep.type = X_Reply;
264 rep.length = 0;
265 rep.sequenceNumber = client->sequence;
266 rep.state = !noPseudoramiXExtension;
267 if (client->swapped) {
268 register int n;
269 swaps (&rep.sequenceNumber, n);
270 swapl (&rep.length, n);
271 swapl (&rep.state, n);
273 WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep);
274 return client->noClientException;
278 // was Xinerama
279 static int ProcPseudoramiXQueryScreens(ClientPtr client)
281 /* REQUEST(xXineramaQueryScreensReq); */
282 xXineramaQueryScreensReply rep;
284 REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
286 rep.type = X_Reply;
287 rep.sequenceNumber = client->sequence;
288 rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens;
289 rep.length = rep.number * sz_XineramaScreenInfo >> 2;
290 if (client->swapped) {
291 register int n;
292 swaps (&rep.sequenceNumber, n);
293 swapl (&rep.length, n);
294 swapl (&rep.number, n);
296 WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep);
298 if (!noPseudoramiXExtension) {
299 xXineramaScreenInfo scratch;
300 int i;
302 for(i = 0; i < pseudoramiXNumScreens; i++) {
303 scratch.x_org = pseudoramiXScreens[i].x;
304 scratch.y_org = pseudoramiXScreens[i].y;
305 scratch.width = pseudoramiXScreens[i].w;
306 scratch.height = pseudoramiXScreens[i].h;
308 if(client->swapped) {
309 register int n;
310 swaps (&scratch.x_org, n);
311 swaps (&scratch.y_org, n);
312 swaps (&scratch.width, n);
313 swaps (&scratch.height, n);
315 WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
319 return client->noClientException;
323 // was PanoramiX
324 static int ProcPseudoramiXDispatch (ClientPtr client)
325 { REQUEST(xReq);
326 switch (stuff->data)
328 case X_PanoramiXQueryVersion:
329 return ProcPseudoramiXQueryVersion(client);
330 case X_PanoramiXGetState:
331 return ProcPseudoramiXGetState(client);
332 case X_PanoramiXGetScreenCount:
333 return ProcPseudoramiXGetScreenCount(client);
334 case X_PanoramiXGetScreenSize:
335 return ProcPseudoramiXGetScreenSize(client);
336 case X_XineramaIsActive:
337 return ProcPseudoramiXIsActive(client);
338 case X_XineramaQueryScreens:
339 return ProcPseudoramiXQueryScreens(client);
341 return BadRequest;
346 static int
347 SProcPseudoramiXQueryVersion (ClientPtr client)
349 REQUEST(xPanoramiXQueryVersionReq);
350 register int n;
352 swaps(&stuff->length,n);
353 REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
354 return ProcPseudoramiXQueryVersion(client);
357 static int
358 SProcPseudoramiXGetState(ClientPtr client)
360 REQUEST(xPanoramiXGetStateReq);
361 register int n;
363 swaps (&stuff->length, n);
364 REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
365 return ProcPseudoramiXGetState(client);
368 static int
369 SProcPseudoramiXGetScreenCount(ClientPtr client)
371 REQUEST(xPanoramiXGetScreenCountReq);
372 register int n;
374 swaps (&stuff->length, n);
375 REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
376 return ProcPseudoramiXGetScreenCount(client);
379 static int
380 SProcPseudoramiXGetScreenSize(ClientPtr client)
382 REQUEST(xPanoramiXGetScreenSizeReq);
383 register int n;
385 swaps (&stuff->length, n);
386 REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
387 return ProcPseudoramiXGetScreenSize(client);
391 static int
392 SProcPseudoramiXIsActive(ClientPtr client)
394 REQUEST(xXineramaIsActiveReq);
395 register int n;
397 swaps (&stuff->length, n);
398 REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
399 return ProcPseudoramiXIsActive(client);
403 static int
404 SProcPseudoramiXQueryScreens(ClientPtr client)
406 REQUEST(xXineramaQueryScreensReq);
407 register int n;
409 swaps (&stuff->length, n);
410 REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
411 return ProcPseudoramiXQueryScreens(client);
415 static int
416 SProcPseudoramiXDispatch (ClientPtr client)
417 { REQUEST(xReq);
418 switch (stuff->data)
420 case X_PanoramiXQueryVersion:
421 return SProcPseudoramiXQueryVersion(client);
422 case X_PanoramiXGetState:
423 return SProcPseudoramiXGetState(client);
424 case X_PanoramiXGetScreenCount:
425 return SProcPseudoramiXGetScreenCount(client);
426 case X_PanoramiXGetScreenSize:
427 return SProcPseudoramiXGetScreenSize(client);
428 case X_XineramaIsActive:
429 return SProcPseudoramiXIsActive(client);
430 case X_XineramaQueryScreens:
431 return SProcPseudoramiXQueryScreens(client);
433 return BadRequest;