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
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 ******************************************************************/
35 /* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.c,v 1.1 2002/03/28 02:21:18 torrey Exp $ */
37 #include "pseudoramiX.h"
39 #include "extnsionst.h"
40 #include "dixstruct.h"
42 #include "panoramiXproto.h"
45 extern int ProcPanoramiXQueryVersion (ClientPtr client);
47 static void PseudoramiXResetProc(ExtensionEntry *extEntry);
49 static int ProcPseudoramiXQueryVersion(ClientPtr client);
50 static int ProcPseudoramiXGetState(ClientPtr client);
51 static int ProcPseudoramiXGetScreenCount(ClientPtr client);
52 static int ProcPseudoramiXGetScreenSize(ClientPtr client);
53 static int ProcPseudoramiXIsActive(ClientPtr client);
54 static int ProcPseudoramiXQueryScreens(ClientPtr client);
55 static int ProcPseudoramiXDispatch(ClientPtr client);
57 static int SProcPseudoramiXQueryVersion(ClientPtr client);
58 static int SProcPseudoramiXGetState(ClientPtr client);
59 static int SProcPseudoramiXGetScreenCount(ClientPtr client);
60 static int SProcPseudoramiXGetScreenSize(ClientPtr client);
61 static int SProcPseudoramiXIsActive(ClientPtr client);
62 static int SProcPseudoramiXQueryScreens(ClientPtr client);
63 static int SProcPseudoramiXDispatch(ClientPtr client);
71 } PseudoramiXScreenRec;
73 static PseudoramiXScreenRec *pseudoramiXScreens = NULL;
74 static int pseudoramiXScreensAllocated = 0;
75 static int pseudoramiXNumScreens = 0;
76 static int pseudoramiXGeneration = -1;
79 // Add a PseudoramiX screen.
80 // The rest of the X server will know nothing about this screen.
81 // Can be called before or after extension init.
82 // Screens must be re-added once per generation.
84 PseudoramiXAddScreen(int x, int y, int w, int h)
86 PseudoramiXScreenRec *s;
88 if (noPseudoramiXExtension) return;
90 if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) {
91 pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1;
92 pseudoramiXScreens = xrealloc(pseudoramiXScreens,
93 pseudoramiXScreensAllocated *
94 sizeof(PseudoramiXScreenRec));
97 s = &pseudoramiXScreens[pseudoramiXNumScreens++];
105 // Initialize PseudoramiX.
106 // Copied from PanoramiXExtensionInit
107 void PseudoramiXExtensionInit(int argc, char *argv[])
109 Bool success = FALSE;
110 ExtensionEntry *extEntry;
112 if (noPseudoramiXExtension) return;
115 if (pseudoramiXNumScreens == 1) {
116 // Only one screen - disable Xinerama extension.
117 noPseudoramiXExtension = TRUE;
122 // The server must not run the PanoramiX operations.
123 noPanoramiXExtension = TRUE;
125 if (pseudoramiXGeneration != serverGeneration) {
126 extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
127 ProcPseudoramiXDispatch,
128 SProcPseudoramiXDispatch,
129 PseudoramiXResetProc,
130 StandardMinorOpcode);
132 ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n");
134 pseudoramiXGeneration = serverGeneration;
140 ErrorF("%s Extension (PseudoramiX) failed to initialize\n",
141 PANORAMIX_PROTOCOL_NAME);
147 static void PseudoramiXResetProc(ExtensionEntry *extEntry)
149 pseudoramiXNumScreens = 0;
152 void PseudoramiXResetScreens (void)
154 pseudoramiXNumScreens = 0;
158 static int ProcPseudoramiXQueryVersion(ClientPtr client)
160 return ProcPanoramiXQueryVersion(client);
165 static int ProcPseudoramiXGetState(ClientPtr client)
167 REQUEST(xPanoramiXGetStateReq);
169 xPanoramiXGetStateReply rep;
172 REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
173 pWin = LookupWindow (stuff->window, client);
178 rep.sequenceNumber = client->sequence;
179 rep.state = !noPseudoramiXExtension;
180 if (client->swapped) {
181 swaps (&rep.sequenceNumber, n);
182 swapl (&rep.length, n);
183 swaps (&rep.state, n);
185 WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
186 return client->noClientException;
191 static int ProcPseudoramiXGetScreenCount(ClientPtr client)
193 REQUEST(xPanoramiXGetScreenCountReq);
195 xPanoramiXGetScreenCountReply rep;
198 REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
199 pWin = LookupWindow (stuff->window, client);
204 rep.sequenceNumber = client->sequence;
205 rep.ScreenCount = pseudoramiXNumScreens;
206 if (client->swapped) {
207 swaps (&rep.sequenceNumber, n);
208 swapl (&rep.length, n);
209 swaps (&rep.ScreenCount, n);
211 WriteToClient (client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
212 return client->noClientException;
217 static int ProcPseudoramiXGetScreenSize(ClientPtr client)
219 REQUEST(xPanoramiXGetScreenSizeReq);
221 xPanoramiXGetScreenSizeReply rep;
224 REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
225 pWin = LookupWindow (stuff->window, client);
230 rep.sequenceNumber = client->sequence;
231 /* screen dimensions */
232 rep.width = pseudoramiXScreens[stuff->screen].w;
233 // was panoramiXdataPtr[stuff->screen].width;
234 rep.height = pseudoramiXScreens[stuff->screen].h;
235 // was panoramiXdataPtr[stuff->screen].height;
236 if (client->swapped) {
237 swaps (&rep.sequenceNumber, n);
238 swapl (&rep.length, n);
239 swaps (&rep.width, n);
240 swaps (&rep.height, n);
242 WriteToClient (client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
243 return client->noClientException;
248 static int ProcPseudoramiXIsActive(ClientPtr client)
250 /* REQUEST(xXineramaIsActiveReq); */
251 xXineramaIsActiveReply rep;
253 REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
257 rep.sequenceNumber = client->sequence;
258 rep.state = !noPseudoramiXExtension;
259 if (client->swapped) {
261 swaps (&rep.sequenceNumber, n);
262 swapl (&rep.length, n);
263 swapl (&rep.state, n);
265 WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep);
266 return client->noClientException;
271 static int ProcPseudoramiXQueryScreens(ClientPtr client)
273 /* REQUEST(xXineramaQueryScreensReq); */
274 xXineramaQueryScreensReply rep;
276 REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
279 rep.sequenceNumber = client->sequence;
280 rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens;
281 rep.length = rep.number * sz_XineramaScreenInfo >> 2;
282 if (client->swapped) {
284 swaps (&rep.sequenceNumber, n);
285 swapl (&rep.length, n);
286 swapl (&rep.number, n);
288 WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep);
290 if (!noPseudoramiXExtension) {
291 xXineramaScreenInfo scratch;
294 for(i = 0; i < pseudoramiXNumScreens; i++) {
295 scratch.x_org = pseudoramiXScreens[i].x;
296 scratch.y_org = pseudoramiXScreens[i].y;
297 scratch.width = pseudoramiXScreens[i].w;
298 scratch.height = pseudoramiXScreens[i].h;
300 if(client->swapped) {
302 swaps (&scratch.x_org, n);
303 swaps (&scratch.y_org, n);
304 swaps (&scratch.width, n);
305 swaps (&scratch.height, n);
307 WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
311 return client->noClientException;
316 static int ProcPseudoramiXDispatch (ClientPtr client)
320 case X_PanoramiXQueryVersion:
321 return ProcPseudoramiXQueryVersion(client);
322 case X_PanoramiXGetState:
323 return ProcPseudoramiXGetState(client);
324 case X_PanoramiXGetScreenCount:
325 return ProcPseudoramiXGetScreenCount(client);
326 case X_PanoramiXGetScreenSize:
327 return ProcPseudoramiXGetScreenSize(client);
328 case X_XineramaIsActive:
329 return ProcPseudoramiXIsActive(client);
330 case X_XineramaQueryScreens:
331 return ProcPseudoramiXQueryScreens(client);
339 SProcPseudoramiXQueryVersion (ClientPtr client)
341 REQUEST(xPanoramiXQueryVersionReq);
344 swaps(&stuff->length,n);
345 REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
346 return ProcPseudoramiXQueryVersion(client);
350 SProcPseudoramiXGetState(ClientPtr client)
352 REQUEST(xPanoramiXGetStateReq);
355 swaps (&stuff->length, n);
356 REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
357 return ProcPseudoramiXGetState(client);
361 SProcPseudoramiXGetScreenCount(ClientPtr client)
363 REQUEST(xPanoramiXGetScreenCountReq);
366 swaps (&stuff->length, n);
367 REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
368 return ProcPseudoramiXGetScreenCount(client);
372 SProcPseudoramiXGetScreenSize(ClientPtr client)
374 REQUEST(xPanoramiXGetScreenSizeReq);
377 swaps (&stuff->length, n);
378 REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
379 return ProcPseudoramiXGetScreenSize(client);
384 SProcPseudoramiXIsActive(ClientPtr client)
386 REQUEST(xXineramaIsActiveReq);
389 swaps (&stuff->length, n);
390 REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
391 return ProcPseudoramiXIsActive(client);
396 SProcPseudoramiXQueryScreens(ClientPtr client)
398 REQUEST(xXineramaQueryScreensReq);
401 swaps (&stuff->length, n);
402 REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
403 return ProcPseudoramiXQueryScreens(client);
408 SProcPseudoramiXDispatch (ClientPtr client)
412 case X_PanoramiXQueryVersion:
413 return SProcPseudoramiXQueryVersion(client);
414 case X_PanoramiXGetState:
415 return SProcPseudoramiXGetState(client);
416 case X_PanoramiXGetScreenCount:
417 return SProcPseudoramiXGetScreenCount(client);
418 case X_PanoramiXGetScreenSize:
419 return SProcPseudoramiXGetScreenSize(client);
420 case X_XineramaIsActive:
421 return SProcPseudoramiXIsActive(client);
422 case X_XineramaQueryScreens:
423 return SProcPseudoramiXQueryScreens(client);