Merge branch 'genete_master'
[synfig.git] / synfig-osx / launcher / pseudoramiX.c
1 /*
2  * Minimal implementation of PanoramiX/Xinerama
3  *
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.
7  *
8  * This code is largely based on panoramiX.c, which contains the
9  * following copyright notice:
10  */
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.
18
19 The above copyright notice and this permission notice shall be included in
20 all copies or substantial portions of the Software.
21
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.
29
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 $ */
36
37 #include "pseudoramiX.h"
38
39 #include "extnsionst.h"
40 #include "dixstruct.h"
41 #include "window.h"
42 #include "panoramiXproto.h"
43 #include "globals.h"
44
45 extern int ProcPanoramiXQueryVersion (ClientPtr client);
46
47 static void PseudoramiXResetProc(ExtensionEntry *extEntry);
48
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);
56
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);
64
65
66 typedef struct {
67     int x;
68     int y;
69     int w;
70     int h;
71 } PseudoramiXScreenRec;
72
73 static PseudoramiXScreenRec *pseudoramiXScreens = NULL;
74 static int pseudoramiXScreensAllocated = 0;
75 static int pseudoramiXNumScreens = 0;
76 static int pseudoramiXGeneration = -1;
77
78
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.
83 void
84 PseudoramiXAddScreen(int x, int y, int w, int h)
85 {
86     PseudoramiXScreenRec *s;
87
88     if (noPseudoramiXExtension) return;
89
90     if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) {
91         pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1;
92         pseudoramiXScreens = xrealloc(pseudoramiXScreens,
93                                       pseudoramiXScreensAllocated *
94                                       sizeof(PseudoramiXScreenRec));
95     }
96
97     s = &pseudoramiXScreens[pseudoramiXNumScreens++];
98     s->x = x;
99     s->y = y;
100     s->w = w;
101     s->h = h;
102 }
103
104
105 // Initialize PseudoramiX.
106 // Copied from PanoramiXExtensionInit
107 void PseudoramiXExtensionInit(int argc, char *argv[])
108 {
109     Bool                success = FALSE;
110     ExtensionEntry      *extEntry;
111
112     if (noPseudoramiXExtension) return;
113
114 #if 0
115     if (pseudoramiXNumScreens == 1) {
116         // Only one screen - disable Xinerama extension.
117         noPseudoramiXExtension = TRUE;
118         return;
119     }
120 #endif
121
122     // The server must not run the PanoramiX operations.
123     noPanoramiXExtension = TRUE;
124
125     if (pseudoramiXGeneration != serverGeneration) {
126         extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
127                                 ProcPseudoramiXDispatch,
128                                 SProcPseudoramiXDispatch,
129                                 PseudoramiXResetProc,
130                                 StandardMinorOpcode);
131         if (!extEntry) {
132             ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n");
133         } else {
134             pseudoramiXGeneration = serverGeneration;
135             success = TRUE;
136         }
137     }
138
139     if (!success) {
140         ErrorF("%s Extension (PseudoramiX) failed to initialize\n",
141                PANORAMIX_PROTOCOL_NAME);
142         return;
143     }
144 }
145
146
147 static void PseudoramiXResetProc(ExtensionEntry *extEntry)
148 {
149     pseudoramiXNumScreens = 0;
150 }
151
152 void PseudoramiXResetScreens (void)
153 {
154     pseudoramiXNumScreens = 0;
155 }
156
157 // was PanoramiX
158 static int ProcPseudoramiXQueryVersion(ClientPtr client)
159 {
160     return ProcPanoramiXQueryVersion(client);
161 }
162
163
164 // was PanoramiX
165 static int ProcPseudoramiXGetState(ClientPtr client)
166 {
167     REQUEST(xPanoramiXGetStateReq);
168     WindowPtr pWin;
169     xPanoramiXGetStateReply rep;
170     register int n;
171
172     REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
173     pWin = LookupWindow (stuff->window, client);
174     if (!pWin)
175         return BadWindow;
176     rep.type = X_Reply;
177     rep.length = 0;
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);
184     }
185     WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
186     return client->noClientException;
187 }
188
189
190 // was PanoramiX
191 static int ProcPseudoramiXGetScreenCount(ClientPtr client)
192 {
193     REQUEST(xPanoramiXGetScreenCountReq);
194     WindowPtr pWin;
195     xPanoramiXGetScreenCountReply rep;
196     register int n;
197
198     REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
199     pWin = LookupWindow (stuff->window, client);
200     if (!pWin)
201         return BadWindow;
202     rep.type = X_Reply;
203     rep.length = 0;
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);
210     }
211     WriteToClient (client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
212     return client->noClientException;
213 }
214
215
216 // was PanoramiX
217 static int ProcPseudoramiXGetScreenSize(ClientPtr client)
218 {
219     REQUEST(xPanoramiXGetScreenSizeReq);
220     WindowPtr                   pWin;
221     xPanoramiXGetScreenSizeReply        rep;
222     register int                        n;
223
224     REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
225     pWin = LookupWindow (stuff->window, client);
226     if (!pWin)
227         return BadWindow;
228     rep.type = X_Reply;
229     rep.length = 0;
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);
241     }
242     WriteToClient (client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
243     return client->noClientException;
244 }
245
246
247 // was Xinerama
248 static int ProcPseudoramiXIsActive(ClientPtr client)
249 {
250     /* REQUEST(xXineramaIsActiveReq); */
251     xXineramaIsActiveReply      rep;
252
253     REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
254
255     rep.type = X_Reply;
256     rep.length = 0;
257     rep.sequenceNumber = client->sequence;
258     rep.state = !noPseudoramiXExtension;
259     if (client->swapped) {
260         register int n;
261         swaps (&rep.sequenceNumber, n);
262         swapl (&rep.length, n);
263         swapl (&rep.state, n);
264     }
265     WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep);
266     return client->noClientException;
267 }
268
269
270 // was Xinerama
271 static int ProcPseudoramiXQueryScreens(ClientPtr client)
272 {
273     /* REQUEST(xXineramaQueryScreensReq); */
274     xXineramaQueryScreensReply  rep;
275
276     REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
277
278     rep.type = X_Reply;
279     rep.sequenceNumber = client->sequence;
280     rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens;
281     rep.length = rep.number * sz_XineramaScreenInfo >> 2;
282     if (client->swapped) {
283         register int n;
284         swaps (&rep.sequenceNumber, n);
285         swapl (&rep.length, n);
286         swapl (&rep.number, n);
287     }
288     WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep);
289
290     if (!noPseudoramiXExtension) {
291         xXineramaScreenInfo scratch;
292         int i;
293
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;
299
300             if(client->swapped) {
301                 register int n;
302                 swaps (&scratch.x_org, n);
303                 swaps (&scratch.y_org, n);
304                 swaps (&scratch.width, n);
305                 swaps (&scratch.height, n);
306             }
307             WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
308         }
309     }
310
311     return client->noClientException;
312 }
313
314
315 // was PanoramiX
316 static int ProcPseudoramiXDispatch (ClientPtr client)
317 {   REQUEST(xReq);
318     switch (stuff->data)
319     {
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);
332     }
333     return BadRequest;
334 }
335
336
337
338 static int
339 SProcPseudoramiXQueryVersion (ClientPtr client)
340 {
341         REQUEST(xPanoramiXQueryVersionReq);
342         register int n;
343
344         swaps(&stuff->length,n);
345         REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
346         return ProcPseudoramiXQueryVersion(client);
347 }
348
349 static int
350 SProcPseudoramiXGetState(ClientPtr client)
351 {
352         REQUEST(xPanoramiXGetStateReq);
353         register int n;
354
355         swaps (&stuff->length, n);
356         REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
357         return ProcPseudoramiXGetState(client);
358 }
359
360 static int
361 SProcPseudoramiXGetScreenCount(ClientPtr client)
362 {
363         REQUEST(xPanoramiXGetScreenCountReq);
364         register int n;
365
366         swaps (&stuff->length, n);
367         REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
368         return ProcPseudoramiXGetScreenCount(client);
369 }
370
371 static int
372 SProcPseudoramiXGetScreenSize(ClientPtr client)
373 {
374         REQUEST(xPanoramiXGetScreenSizeReq);
375         register int n;
376
377         swaps (&stuff->length, n);
378         REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
379         return ProcPseudoramiXGetScreenSize(client);
380 }
381
382
383 static int
384 SProcPseudoramiXIsActive(ClientPtr client)
385 {
386         REQUEST(xXineramaIsActiveReq);
387         register int n;
388
389         swaps (&stuff->length, n);
390         REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
391         return ProcPseudoramiXIsActive(client);
392 }
393
394
395 static int
396 SProcPseudoramiXQueryScreens(ClientPtr client)
397 {
398         REQUEST(xXineramaQueryScreensReq);
399         register int n;
400
401         swaps (&stuff->length, n);
402         REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
403         return ProcPseudoramiXQueryScreens(client);
404 }
405
406
407 static int
408 SProcPseudoramiXDispatch (ClientPtr client)
409 {   REQUEST(xReq);
410     switch (stuff->data)
411     {
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);
424     }
425     return BadRequest;
426 }