1 /*****************************************************************
2 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal
5 in the Software without restriction, including without limitation the rights
6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 copies of the Software.
8 
9 The above copyright notice and this permission notice shall be included in
10 all copies or substantial portions of the Software.
11 
12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
15 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
16 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
17 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
18 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 
20 Except as contained in this notice, the name of Digital Equipment Corporation
21 shall not be used in advertising or otherwise to promote the sale, use or other
22 dealings in this Software without prior written authorization from Digital
23 Equipment Corporation.
24 ******************************************************************/
25 
26 /* Massively rewritten by Mark Vojkovich <markv@valinux.com> */
27 
28 #ifdef HAVE_DIX_CONFIG_H
29 #include <dix-config.h>
30 #endif
31 
32 #include <stdio.h>
33 #include <X11/X.h>
34 #include <X11/Xproto.h>
35 #include "windowstr.h"
36 #include "dixfontstr.h"
37 #include "gcstruct.h"
38 #include "colormapst.h"
39 #include "scrnintstr.h"
40 #include "opaque.h"
41 #include "inputstr.h"
42 #include "migc.h"
43 #include "misc.h"
44 #include "dixstruct.h"
45 #include "panoramiX.h"
46 #include "panoramiXsrv.h"
47 #include "resource.h"
48 #include "panoramiXh.h"
49 
50 #define XINERAMA_IMAGE_BUFSIZE (256*1024)
51 #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
52                               CWDontPropagate | CWOverrideRedirect | CWCursor )
53 
54 int
PanoramiXCreateWindow(ClientPtr client)55 PanoramiXCreateWindow(ClientPtr client)
56 {
57     PanoramiXRes *parent, *newWin;
58     PanoramiXRes *backPix = NULL;
59     PanoramiXRes *bordPix = NULL;
60     PanoramiXRes *cmap = NULL;
61 
62     REQUEST(xCreateWindowReq);
63     int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
64     int result, len, j;
65     int orig_x, orig_y;
66     XID orig_visual, tmp;
67     Bool parentIsRoot;
68 
69     REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
70 
71     len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
72     if (Ones(stuff->mask) != len)
73         return BadLength;
74 
75     result = dixLookupResourceByType((void **) &parent, stuff->parent,
76                                      XRT_WINDOW, client, DixWriteAccess);
77     if (result != Success)
78         return result;
79 
80     if (stuff->class == CopyFromParent)
81         stuff->class = parent->u.win.class;
82 
83     if ((stuff->class == InputOnly) && (stuff->mask & (~INPUTONLY_LEGAL_MASK)))
84         return BadMatch;
85 
86     if ((Mask) stuff->mask & CWBackPixmap) {
87         pback_offset = Ones((Mask) stuff->mask & (CWBackPixmap - 1));
88         tmp = *((CARD32 *) &stuff[1] + pback_offset);
89         if ((tmp != None) && (tmp != ParentRelative)) {
90             result = dixLookupResourceByType((void **) &backPix, tmp,
91                                              XRT_PIXMAP, client, DixReadAccess);
92             if (result != Success)
93                 return result;
94         }
95     }
96     if ((Mask) stuff->mask & CWBorderPixmap) {
97         pbord_offset = Ones((Mask) stuff->mask & (CWBorderPixmap - 1));
98         tmp = *((CARD32 *) &stuff[1] + pbord_offset);
99         if (tmp != CopyFromParent) {
100             result = dixLookupResourceByType((void **) &bordPix, tmp,
101                                              XRT_PIXMAP, client, DixReadAccess);
102             if (result != Success)
103                 return result;
104         }
105     }
106     if ((Mask) stuff->mask & CWColormap) {
107         cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
108         tmp = *((CARD32 *) &stuff[1] + cmap_offset);
109         if (tmp != CopyFromParent) {
110             result = dixLookupResourceByType((void **) &cmap, tmp,
111                                              XRT_COLORMAP, client,
112                                              DixReadAccess);
113             if (result != Success)
114                 return result;
115         }
116     }
117 
118     if (!(newWin = malloc(sizeof(PanoramiXRes))))
119         return BadAlloc;
120 
121     newWin->type = XRT_WINDOW;
122     newWin->u.win.visibility = VisibilityNotViewable;
123     newWin->u.win.class = stuff->class;
124     newWin->u.win.root = FALSE;
125     panoramix_setup_ids(newWin, client, stuff->wid);
126 
127     if (stuff->class == InputOnly)
128         stuff->visual = CopyFromParent;
129     orig_visual = stuff->visual;
130     orig_x = stuff->x;
131     orig_y = stuff->y;
132     parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id)
133         || (stuff->parent == screenInfo.screens[0]->screensaver.wid);
134     FOR_NSCREENS_BACKWARD(j) {
135         stuff->wid = newWin->info[j].id;
136         stuff->parent = parent->info[j].id;
137         if (parentIsRoot) {
138             stuff->x = orig_x - screenInfo.screens[j]->x;
139             stuff->y = orig_y - screenInfo.screens[j]->y;
140         }
141         if (backPix)
142             *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id;
143         if (bordPix)
144             *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id;
145         if (cmap)
146             *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id;
147         if (orig_visual != CopyFromParent)
148             stuff->visual = PanoramiXTranslateVisualID(j, orig_visual);
149         result = (*SavedProcVector[X_CreateWindow]) (client);
150         if (result != Success)
151             break;
152     }
153 
154     if (result == Success)
155         AddResource(newWin->info[0].id, XRT_WINDOW, newWin);
156     else
157         free(newWin);
158 
159     return result;
160 }
161 
162 int
PanoramiXChangeWindowAttributes(ClientPtr client)163 PanoramiXChangeWindowAttributes(ClientPtr client)
164 {
165     PanoramiXRes *win;
166     PanoramiXRes *backPix = NULL;
167     PanoramiXRes *bordPix = NULL;
168     PanoramiXRes *cmap = NULL;
169 
170     REQUEST(xChangeWindowAttributesReq);
171     int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
172     int result, len, j;
173     XID tmp;
174 
175     REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
176 
177     len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
178     if (Ones(stuff->valueMask) != len)
179         return BadLength;
180 
181     result = dixLookupResourceByType((void **) &win, stuff->window,
182                                      XRT_WINDOW, client, DixWriteAccess);
183     if (result != Success)
184         return result;
185 
186     if ((win->u.win.class == InputOnly) &&
187         (stuff->valueMask & (~INPUTONLY_LEGAL_MASK)))
188         return BadMatch;
189 
190     if ((Mask) stuff->valueMask & CWBackPixmap) {
191         pback_offset = Ones((Mask) stuff->valueMask & (CWBackPixmap - 1));
192         tmp = *((CARD32 *) &stuff[1] + pback_offset);
193         if ((tmp != None) && (tmp != ParentRelative)) {
194             result = dixLookupResourceByType((void **) &backPix, tmp,
195                                              XRT_PIXMAP, client, DixReadAccess);
196             if (result != Success)
197                 return result;
198         }
199     }
200     if ((Mask) stuff->valueMask & CWBorderPixmap) {
201         pbord_offset = Ones((Mask) stuff->valueMask & (CWBorderPixmap - 1));
202         tmp = *((CARD32 *) &stuff[1] + pbord_offset);
203         if (tmp != CopyFromParent) {
204             result = dixLookupResourceByType((void **) &bordPix, tmp,
205                                              XRT_PIXMAP, client, DixReadAccess);
206             if (result != Success)
207                 return result;
208         }
209     }
210     if ((Mask) stuff->valueMask & CWColormap) {
211         cmap_offset = Ones((Mask) stuff->valueMask & (CWColormap - 1));
212         tmp = *((CARD32 *) &stuff[1] + cmap_offset);
213         if (tmp != CopyFromParent) {
214             result = dixLookupResourceByType((void **) &cmap, tmp,
215                                              XRT_COLORMAP, client,
216                                              DixReadAccess);
217             if (result != Success)
218                 return result;
219         }
220     }
221 
222     FOR_NSCREENS_BACKWARD(j) {
223         stuff->window = win->info[j].id;
224         if (backPix)
225             *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id;
226         if (bordPix)
227             *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id;
228         if (cmap)
229             *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id;
230         result = (*SavedProcVector[X_ChangeWindowAttributes]) (client);
231     }
232 
233     return result;
234 }
235 
236 int
PanoramiXDestroyWindow(ClientPtr client)237 PanoramiXDestroyWindow(ClientPtr client)
238 {
239     PanoramiXRes *win;
240     int result, j;
241 
242     REQUEST(xResourceReq);
243 
244     REQUEST_SIZE_MATCH(xResourceReq);
245 
246     result = dixLookupResourceByType((void **) &win, stuff->id, XRT_WINDOW,
247                                      client, DixDestroyAccess);
248     if (result != Success)
249         return result;
250 
251     FOR_NSCREENS_BACKWARD(j) {
252         stuff->id = win->info[j].id;
253         result = (*SavedProcVector[X_DestroyWindow]) (client);
254         if (result != Success)
255             break;
256     }
257 
258     /* Since ProcDestroyWindow is using FreeResource, it will free
259        our resource for us on the last pass through the loop above */
260 
261     return result;
262 }
263 
264 int
PanoramiXDestroySubwindows(ClientPtr client)265 PanoramiXDestroySubwindows(ClientPtr client)
266 {
267     PanoramiXRes *win;
268     int result, j;
269 
270     REQUEST(xResourceReq);
271 
272     REQUEST_SIZE_MATCH(xResourceReq);
273 
274     result = dixLookupResourceByType((void **) &win, stuff->id, XRT_WINDOW,
275                                      client, DixDestroyAccess);
276     if (result != Success)
277         return result;
278 
279     FOR_NSCREENS_BACKWARD(j) {
280         stuff->id = win->info[j].id;
281         result = (*SavedProcVector[X_DestroySubwindows]) (client);
282         if (result != Success)
283             break;
284     }
285 
286     /* DestroySubwindows is using FreeResource which will free
287        our resources for us on the last pass through the loop above */
288 
289     return result;
290 }
291 
292 int
PanoramiXChangeSaveSet(ClientPtr client)293 PanoramiXChangeSaveSet(ClientPtr client)
294 {
295     PanoramiXRes *win;
296     int result, j;
297 
298     REQUEST(xChangeSaveSetReq);
299 
300     REQUEST_SIZE_MATCH(xChangeSaveSetReq);
301 
302     result = dixLookupResourceByType((void **) &win, stuff->window,
303                                      XRT_WINDOW, client, DixReadAccess);
304     if (result != Success)
305         return result;
306 
307     FOR_NSCREENS_BACKWARD(j) {
308         stuff->window = win->info[j].id;
309         result = (*SavedProcVector[X_ChangeSaveSet]) (client);
310         if (result != Success)
311             break;
312     }
313 
314     return result;
315 }
316 
317 int
PanoramiXReparentWindow(ClientPtr client)318 PanoramiXReparentWindow(ClientPtr client)
319 {
320     PanoramiXRes *win, *parent;
321     int result, j;
322     int x, y;
323     Bool parentIsRoot;
324 
325     REQUEST(xReparentWindowReq);
326 
327     REQUEST_SIZE_MATCH(xReparentWindowReq);
328 
329     result = dixLookupResourceByType((void **) &win, stuff->window,
330                                      XRT_WINDOW, client, DixWriteAccess);
331     if (result != Success)
332         return result;
333 
334     result = dixLookupResourceByType((void **) &parent, stuff->parent,
335                                      XRT_WINDOW, client, DixWriteAccess);
336     if (result != Success)
337         return result;
338 
339     x = stuff->x;
340     y = stuff->y;
341     parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id)
342         || (stuff->parent == screenInfo.screens[0]->screensaver.wid);
343     FOR_NSCREENS_BACKWARD(j) {
344         stuff->window = win->info[j].id;
345         stuff->parent = parent->info[j].id;
346         if (parentIsRoot) {
347             stuff->x = x - screenInfo.screens[j]->x;
348             stuff->y = y - screenInfo.screens[j]->y;
349         }
350         result = (*SavedProcVector[X_ReparentWindow]) (client);
351         if (result != Success)
352             break;
353     }
354 
355     return result;
356 }
357 
358 int
PanoramiXMapWindow(ClientPtr client)359 PanoramiXMapWindow(ClientPtr client)
360 {
361     PanoramiXRes *win;
362     int result, j;
363 
364     REQUEST(xResourceReq);
365 
366     REQUEST_SIZE_MATCH(xResourceReq);
367 
368     result = dixLookupResourceByType((void **) &win, stuff->id,
369                                      XRT_WINDOW, client, DixReadAccess);
370     if (result != Success)
371         return result;
372 
373     FOR_NSCREENS_FORWARD(j) {
374         stuff->id = win->info[j].id;
375         result = (*SavedProcVector[X_MapWindow]) (client);
376         if (result != Success)
377             break;
378     }
379 
380     return result;
381 }
382 
383 int
PanoramiXMapSubwindows(ClientPtr client)384 PanoramiXMapSubwindows(ClientPtr client)
385 {
386     PanoramiXRes *win;
387     int result, j;
388 
389     REQUEST(xResourceReq);
390 
391     REQUEST_SIZE_MATCH(xResourceReq);
392 
393     result = dixLookupResourceByType((void **) &win, stuff->id,
394                                      XRT_WINDOW, client, DixReadAccess);
395     if (result != Success)
396         return result;
397 
398     FOR_NSCREENS_FORWARD(j) {
399         stuff->id = win->info[j].id;
400         result = (*SavedProcVector[X_MapSubwindows]) (client);
401         if (result != Success)
402             break;
403     }
404 
405     return result;
406 }
407 
408 int
PanoramiXUnmapWindow(ClientPtr client)409 PanoramiXUnmapWindow(ClientPtr client)
410 {
411     PanoramiXRes *win;
412     int result, j;
413 
414     REQUEST(xResourceReq);
415 
416     REQUEST_SIZE_MATCH(xResourceReq);
417 
418     result = dixLookupResourceByType((void **) &win, stuff->id,
419                                      XRT_WINDOW, client, DixReadAccess);
420     if (result != Success)
421         return result;
422 
423     FOR_NSCREENS_FORWARD(j) {
424         stuff->id = win->info[j].id;
425         result = (*SavedProcVector[X_UnmapWindow]) (client);
426         if (result != Success)
427             break;
428     }
429 
430     return result;
431 }
432 
433 int
PanoramiXUnmapSubwindows(ClientPtr client)434 PanoramiXUnmapSubwindows(ClientPtr client)
435 {
436     PanoramiXRes *win;
437     int result, j;
438 
439     REQUEST(xResourceReq);
440 
441     REQUEST_SIZE_MATCH(xResourceReq);
442 
443     result = dixLookupResourceByType((void **) &win, stuff->id,
444                                      XRT_WINDOW, client, DixReadAccess);
445     if (result != Success)
446         return result;
447 
448     FOR_NSCREENS_FORWARD(j) {
449         stuff->id = win->info[j].id;
450         result = (*SavedProcVector[X_UnmapSubwindows]) (client);
451         if (result != Success)
452             break;
453     }
454 
455     return result;
456 }
457 
458 int
PanoramiXConfigureWindow(ClientPtr client)459 PanoramiXConfigureWindow(ClientPtr client)
460 {
461     PanoramiXRes *win;
462     PanoramiXRes *sib = NULL;
463     WindowPtr pWin;
464     int result, j, len, sib_offset = 0, x = 0, y = 0;
465     int x_offset = -1;
466     int y_offset = -1;
467 
468     REQUEST(xConfigureWindowReq);
469 
470     REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
471 
472     len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
473     if (Ones(stuff->mask) != len)
474         return BadLength;
475 
476     /* because we need the parent */
477     result = dixLookupResourceByType((void **) &pWin, stuff->window,
478                                      RT_WINDOW, client, DixWriteAccess);
479     if (result != Success)
480         return result;
481 
482     result = dixLookupResourceByType((void **) &win, stuff->window,
483                                      XRT_WINDOW, client, DixWriteAccess);
484     if (result != Success)
485         return result;
486 
487     if ((Mask) stuff->mask & CWSibling) {
488         XID tmp;
489 
490         sib_offset = Ones((Mask) stuff->mask & (CWSibling - 1));
491         if ((tmp = *((CARD32 *) &stuff[1] + sib_offset))) {
492             result = dixLookupResourceByType((void **) &sib, tmp, XRT_WINDOW,
493                                              client, DixReadAccess);
494             if (result != Success)
495                 return result;
496         }
497     }
498 
499     if (pWin->parent && ((pWin->parent == screenInfo.screens[0]->root) ||
500                          (pWin->parent->drawable.id ==
501                           screenInfo.screens[0]->screensaver.wid))) {
502         if ((Mask) stuff->mask & CWX) {
503             x_offset = 0;
504             x = *((CARD32 *) &stuff[1]);
505         }
506         if ((Mask) stuff->mask & CWY) {
507             y_offset = (x_offset == -1) ? 0 : 1;
508             y = *((CARD32 *) &stuff[1] + y_offset);
509         }
510     }
511 
512     /* have to go forward or you get expose events before
513        ConfigureNotify events */
514     FOR_NSCREENS_FORWARD(j) {
515         stuff->window = win->info[j].id;
516         if (sib)
517             *((CARD32 *) &stuff[1] + sib_offset) = sib->info[j].id;
518         if (x_offset >= 0)
519             *((CARD32 *) &stuff[1] + x_offset) = x - screenInfo.screens[j]->x;
520         if (y_offset >= 0)
521             *((CARD32 *) &stuff[1] + y_offset) = y - screenInfo.screens[j]->y;
522         result = (*SavedProcVector[X_ConfigureWindow]) (client);
523         if (result != Success)
524             break;
525     }
526 
527     return result;
528 }
529 
530 int
PanoramiXCirculateWindow(ClientPtr client)531 PanoramiXCirculateWindow(ClientPtr client)
532 {
533     PanoramiXRes *win;
534     int result, j;
535 
536     REQUEST(xCirculateWindowReq);
537 
538     REQUEST_SIZE_MATCH(xCirculateWindowReq);
539 
540     result = dixLookupResourceByType((void **) &win, stuff->window,
541                                      XRT_WINDOW, client, DixWriteAccess);
542     if (result != Success)
543         return result;
544 
545     FOR_NSCREENS_FORWARD(j) {
546         stuff->window = win->info[j].id;
547         result = (*SavedProcVector[X_CirculateWindow]) (client);
548         if (result != Success)
549             break;
550     }
551 
552     return result;
553 }
554 
555 int
PanoramiXGetGeometry(ClientPtr client)556 PanoramiXGetGeometry(ClientPtr client)
557 {
558     xGetGeometryReply rep;
559     DrawablePtr pDraw;
560     int rc;
561 
562     REQUEST(xResourceReq);
563 
564     REQUEST_SIZE_MATCH(xResourceReq);
565     rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
566     if (rc != Success)
567         return rc;
568 
569     rep = (xGetGeometryReply) {
570         .type = X_Reply,
571         .sequenceNumber = client->sequence,
572         .length = 0,
573         .root = screenInfo.screens[0]->root->drawable.id,
574         .depth = pDraw->depth,
575         .width = pDraw->width,
576         .height = pDraw->height,
577         .x = 0,
578         .y = 0,
579         .borderWidth = 0
580     };
581 
582     if (stuff->id == rep.root) {
583         xWindowRoot *root = (xWindowRoot *)
584             (ConnectionInfo + connBlockScreenStart);
585 
586         rep.width = root->pixWidth;
587         rep.height = root->pixHeight;
588     }
589     else if (WindowDrawable(pDraw->type)) {
590         WindowPtr pWin = (WindowPtr) pDraw;
591 
592         rep.x = pWin->origin.x - wBorderWidth(pWin);
593         rep.y = pWin->origin.y - wBorderWidth(pWin);
594         if ((pWin->parent == screenInfo.screens[0]->root) ||
595             (pWin->parent->drawable.id ==
596              screenInfo.screens[0]->screensaver.wid)) {
597             rep.x += screenInfo.screens[0]->x;
598             rep.y += screenInfo.screens[0]->y;
599         }
600         rep.borderWidth = pWin->borderWidth;
601     }
602 
603     WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
604     return Success;
605 }
606 
607 int
PanoramiXTranslateCoords(ClientPtr client)608 PanoramiXTranslateCoords(ClientPtr client)
609 {
610     INT16 x, y;
611 
612     REQUEST(xTranslateCoordsReq);
613     int rc;
614     WindowPtr pWin, pDst;
615     xTranslateCoordsReply rep;
616 
617     REQUEST_SIZE_MATCH(xTranslateCoordsReq);
618     rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess);
619     if (rc != Success)
620         return rc;
621     rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess);
622     if (rc != Success)
623         return rc;
624     rep = (xTranslateCoordsReply) {
625         .type = X_Reply,
626         .sequenceNumber = client->sequence,
627         .length = 0,
628         .sameScreen = xTrue,
629         .child = None
630     };
631 
632     if ((pWin == screenInfo.screens[0]->root) ||
633         (pWin->drawable.id == screenInfo.screens[0]->screensaver.wid)) {
634         x = stuff->srcX - screenInfo.screens[0]->x;
635         y = stuff->srcY - screenInfo.screens[0]->y;
636     }
637     else {
638         x = pWin->drawable.x + stuff->srcX;
639         y = pWin->drawable.y + stuff->srcY;
640     }
641     pWin = pDst->firstChild;
642     while (pWin) {
643         BoxRec box;
644 
645         if ((pWin->mapped) &&
646             (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
647             (x < pWin->drawable.x + (int) pWin->drawable.width +
648              wBorderWidth(pWin)) &&
649             (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
650             (y < pWin->drawable.y + (int) pWin->drawable.height +
651              wBorderWidth(pWin))
652             /* When a window is shaped, a further check
653              * is made to see if the point is inside
654              * borderSize
655              */
656             && (!wBoundingShape(pWin) ||
657                 RegionContainsPoint(wBoundingShape(pWin),
658                                     x - pWin->drawable.x,
659                                     y - pWin->drawable.y, &box))
660             ) {
661             rep.child = pWin->drawable.id;
662             pWin = (WindowPtr) NULL;
663         }
664         else
665             pWin = pWin->nextSib;
666     }
667     rep.dstX = x - pDst->drawable.x;
668     rep.dstY = y - pDst->drawable.y;
669     if ((pDst == screenInfo.screens[0]->root) ||
670         (pDst->drawable.id == screenInfo.screens[0]->screensaver.wid)) {
671         rep.dstX += screenInfo.screens[0]->x;
672         rep.dstY += screenInfo.screens[0]->y;
673     }
674 
675     WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
676     return Success;
677 }
678 
679 int
PanoramiXCreatePixmap(ClientPtr client)680 PanoramiXCreatePixmap(ClientPtr client)
681 {
682     PanoramiXRes *refDraw, *newPix;
683     int result, j;
684 
685     REQUEST(xCreatePixmapReq);
686 
687     REQUEST_SIZE_MATCH(xCreatePixmapReq);
688     client->errorValue = stuff->pid;
689 
690     result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable,
691                                       XRC_DRAWABLE, client, DixReadAccess);
692     if (result != Success)
693         return (result == BadValue) ? BadDrawable : result;
694 
695     if (!(newPix = malloc(sizeof(PanoramiXRes))))
696         return BadAlloc;
697 
698     newPix->type = XRT_PIXMAP;
699     newPix->u.pix.shared = FALSE;
700     panoramix_setup_ids(newPix, client, stuff->pid);
701 
702     FOR_NSCREENS_BACKWARD(j) {
703         stuff->pid = newPix->info[j].id;
704         stuff->drawable = refDraw->info[j].id;
705         result = (*SavedProcVector[X_CreatePixmap]) (client);
706         if (result != Success)
707             break;
708     }
709 
710     if (result == Success)
711         AddResource(newPix->info[0].id, XRT_PIXMAP, newPix);
712     else
713         free(newPix);
714 
715     return result;
716 }
717 
718 int
PanoramiXFreePixmap(ClientPtr client)719 PanoramiXFreePixmap(ClientPtr client)
720 {
721     PanoramiXRes *pix;
722     int result, j;
723 
724     REQUEST(xResourceReq);
725 
726     REQUEST_SIZE_MATCH(xResourceReq);
727 
728     client->errorValue = stuff->id;
729 
730     result = dixLookupResourceByType((void **) &pix, stuff->id, XRT_PIXMAP,
731                                      client, DixDestroyAccess);
732     if (result != Success)
733         return result;
734 
735     FOR_NSCREENS_BACKWARD(j) {
736         stuff->id = pix->info[j].id;
737         result = (*SavedProcVector[X_FreePixmap]) (client);
738         if (result != Success)
739             break;
740     }
741 
742     /* Since ProcFreePixmap is using FreeResource, it will free
743        our resource for us on the last pass through the loop above */
744 
745     return result;
746 }
747 
748 int
PanoramiXCreateGC(ClientPtr client)749 PanoramiXCreateGC(ClientPtr client)
750 {
751     PanoramiXRes *refDraw;
752     PanoramiXRes *newGC;
753     PanoramiXRes *stip = NULL;
754     PanoramiXRes *tile = NULL;
755     PanoramiXRes *clip = NULL;
756 
757     REQUEST(xCreateGCReq);
758     int tile_offset = 0, stip_offset = 0, clip_offset = 0;
759     int result, len, j;
760     XID tmp;
761 
762     REQUEST_AT_LEAST_SIZE(xCreateGCReq);
763 
764     client->errorValue = stuff->gc;
765     len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
766     if (Ones(stuff->mask) != len)
767         return BadLength;
768 
769     result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable,
770                                       XRC_DRAWABLE, client, DixReadAccess);
771     if (result != Success)
772         return (result == BadValue) ? BadDrawable : result;
773 
774     if ((Mask) stuff->mask & GCTile) {
775         tile_offset = Ones((Mask) stuff->mask & (GCTile - 1));
776         if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
777             result = dixLookupResourceByType((void **) &tile, tmp, XRT_PIXMAP,
778                                              client, DixReadAccess);
779             if (result != Success)
780                 return result;
781         }
782     }
783     if ((Mask) stuff->mask & GCStipple) {
784         stip_offset = Ones((Mask) stuff->mask & (GCStipple - 1));
785         if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
786             result = dixLookupResourceByType((void **) &stip, tmp, XRT_PIXMAP,
787                                              client, DixReadAccess);
788             if (result != Success)
789                 return result;
790         }
791     }
792     if ((Mask) stuff->mask & GCClipMask) {
793         clip_offset = Ones((Mask) stuff->mask & (GCClipMask - 1));
794         if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
795             result = dixLookupResourceByType((void **) &clip, tmp, XRT_PIXMAP,
796                                              client, DixReadAccess);
797             if (result != Success)
798                 return result;
799         }
800     }
801 
802     if (!(newGC = malloc(sizeof(PanoramiXRes))))
803         return BadAlloc;
804 
805     newGC->type = XRT_GC;
806     panoramix_setup_ids(newGC, client, stuff->gc);
807 
808     FOR_NSCREENS_BACKWARD(j) {
809         stuff->gc = newGC->info[j].id;
810         stuff->drawable = refDraw->info[j].id;
811         if (tile)
812             *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id;
813         if (stip)
814             *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id;
815         if (clip)
816             *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id;
817         result = (*SavedProcVector[X_CreateGC]) (client);
818         if (result != Success)
819             break;
820     }
821 
822     if (result == Success)
823         AddResource(newGC->info[0].id, XRT_GC, newGC);
824     else
825         free(newGC);
826 
827     return result;
828 }
829 
830 int
PanoramiXChangeGC(ClientPtr client)831 PanoramiXChangeGC(ClientPtr client)
832 {
833     PanoramiXRes *gc;
834     PanoramiXRes *stip = NULL;
835     PanoramiXRes *tile = NULL;
836     PanoramiXRes *clip = NULL;
837 
838     REQUEST(xChangeGCReq);
839     int tile_offset = 0, stip_offset = 0, clip_offset = 0;
840     int result, len, j;
841     XID tmp;
842 
843     REQUEST_AT_LEAST_SIZE(xChangeGCReq);
844 
845     len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
846     if (Ones(stuff->mask) != len)
847         return BadLength;
848 
849     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
850                                      client, DixReadAccess);
851     if (result != Success)
852         return result;
853 
854     if ((Mask) stuff->mask & GCTile) {
855         tile_offset = Ones((Mask) stuff->mask & (GCTile - 1));
856         if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
857             result = dixLookupResourceByType((void **) &tile, tmp, XRT_PIXMAP,
858                                              client, DixReadAccess);
859             if (result != Success)
860                 return result;
861         }
862     }
863     if ((Mask) stuff->mask & GCStipple) {
864         stip_offset = Ones((Mask) stuff->mask & (GCStipple - 1));
865         if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
866             result = dixLookupResourceByType((void **) &stip, tmp, XRT_PIXMAP,
867                                              client, DixReadAccess);
868             if (result != Success)
869                 return result;
870         }
871     }
872     if ((Mask) stuff->mask & GCClipMask) {
873         clip_offset = Ones((Mask) stuff->mask & (GCClipMask - 1));
874         if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
875             result = dixLookupResourceByType((void **) &clip, tmp, XRT_PIXMAP,
876                                              client, DixReadAccess);
877             if (result != Success)
878                 return result;
879         }
880     }
881 
882     FOR_NSCREENS_BACKWARD(j) {
883         stuff->gc = gc->info[j].id;
884         if (tile)
885             *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id;
886         if (stip)
887             *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id;
888         if (clip)
889             *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id;
890         result = (*SavedProcVector[X_ChangeGC]) (client);
891         if (result != Success)
892             break;
893     }
894 
895     return result;
896 }
897 
898 int
PanoramiXCopyGC(ClientPtr client)899 PanoramiXCopyGC(ClientPtr client)
900 {
901     PanoramiXRes *srcGC, *dstGC;
902     int result, j;
903 
904     REQUEST(xCopyGCReq);
905 
906     REQUEST_SIZE_MATCH(xCopyGCReq);
907 
908     result = dixLookupResourceByType((void **) &srcGC, stuff->srcGC, XRT_GC,
909                                      client, DixReadAccess);
910     if (result != Success)
911         return result;
912 
913     result = dixLookupResourceByType((void **) &dstGC, stuff->dstGC, XRT_GC,
914                                      client, DixWriteAccess);
915     if (result != Success)
916         return result;
917 
918     FOR_NSCREENS(j) {
919         stuff->srcGC = srcGC->info[j].id;
920         stuff->dstGC = dstGC->info[j].id;
921         result = (*SavedProcVector[X_CopyGC]) (client);
922         if (result != Success)
923             break;
924     }
925 
926     return result;
927 }
928 
929 int
PanoramiXSetDashes(ClientPtr client)930 PanoramiXSetDashes(ClientPtr client)
931 {
932     PanoramiXRes *gc;
933     int result, j;
934 
935     REQUEST(xSetDashesReq);
936 
937     REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
938 
939     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
940                                      client, DixWriteAccess);
941     if (result != Success)
942         return result;
943 
944     FOR_NSCREENS_BACKWARD(j) {
945         stuff->gc = gc->info[j].id;
946         result = (*SavedProcVector[X_SetDashes]) (client);
947         if (result != Success)
948             break;
949     }
950 
951     return result;
952 }
953 
954 int
PanoramiXSetClipRectangles(ClientPtr client)955 PanoramiXSetClipRectangles(ClientPtr client)
956 {
957     PanoramiXRes *gc;
958     int result, j;
959 
960     REQUEST(xSetClipRectanglesReq);
961 
962     REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
963 
964     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
965                                      client, DixWriteAccess);
966     if (result != Success)
967         return result;
968 
969     FOR_NSCREENS_BACKWARD(j) {
970         stuff->gc = gc->info[j].id;
971         result = (*SavedProcVector[X_SetClipRectangles]) (client);
972         if (result != Success)
973             break;
974     }
975 
976     return result;
977 }
978 
979 int
PanoramiXFreeGC(ClientPtr client)980 PanoramiXFreeGC(ClientPtr client)
981 {
982     PanoramiXRes *gc;
983     int result, j;
984 
985     REQUEST(xResourceReq);
986 
987     REQUEST_SIZE_MATCH(xResourceReq);
988 
989     result = dixLookupResourceByType((void **) &gc, stuff->id, XRT_GC,
990                                      client, DixDestroyAccess);
991     if (result != Success)
992         return result;
993 
994     FOR_NSCREENS_BACKWARD(j) {
995         stuff->id = gc->info[j].id;
996         result = (*SavedProcVector[X_FreeGC]) (client);
997         if (result != Success)
998             break;
999     }
1000 
1001     /* Since ProcFreeGC is using FreeResource, it will free
1002        our resource for us on the last pass through the loop above */
1003 
1004     return result;
1005 }
1006 
1007 int
PanoramiXClearToBackground(ClientPtr client)1008 PanoramiXClearToBackground(ClientPtr client)
1009 {
1010     PanoramiXRes *win;
1011     int result, j, x, y;
1012     Bool isRoot;
1013 
1014     REQUEST(xClearAreaReq);
1015 
1016     REQUEST_SIZE_MATCH(xClearAreaReq);
1017 
1018     result = dixLookupResourceByType((void **) &win, stuff->window,
1019                                      XRT_WINDOW, client, DixWriteAccess);
1020     if (result != Success)
1021         return result;
1022 
1023     x = stuff->x;
1024     y = stuff->y;
1025     isRoot = win->u.win.root;
1026     FOR_NSCREENS_BACKWARD(j) {
1027         stuff->window = win->info[j].id;
1028         if (isRoot) {
1029             stuff->x = x - screenInfo.screens[j]->x;
1030             stuff->y = y - screenInfo.screens[j]->y;
1031         }
1032         result = (*SavedProcVector[X_ClearArea]) (client);
1033         if (result != Success)
1034             break;
1035     }
1036 
1037     return result;
1038 }
1039 
1040 /*
1041     For Window to Pixmap copies you're screwed since each screen's
1042     pixmap will look like what it sees on its screen.  Unless the
1043     screens overlap and the window lies on each, the two copies
1044     will be out of sync.  To remedy this we do a GetImage and PutImage
1045     in place of the copy.  Doing this as a single Image isn't quite
1046     correct since it will include the obscured areas but we will
1047     have to fix this later. (MArk).
1048 */
1049 
1050 int
PanoramiXCopyArea(ClientPtr client)1051 PanoramiXCopyArea(ClientPtr client)
1052 {
1053     int j, result, srcx, srcy, dstx, dsty, width, height;
1054     PanoramiXRes *gc, *src, *dst;
1055     Bool srcIsRoot = FALSE;
1056     Bool dstIsRoot = FALSE;
1057     Bool srcShared, dstShared;
1058 
1059     REQUEST(xCopyAreaReq);
1060 
1061     REQUEST_SIZE_MATCH(xCopyAreaReq);
1062 
1063     result = dixLookupResourceByClass((void **) &src, stuff->srcDrawable,
1064                                       XRC_DRAWABLE, client, DixReadAccess);
1065     if (result != Success)
1066         return (result == BadValue) ? BadDrawable : result;
1067 
1068     srcShared = IS_SHARED_PIXMAP(src);
1069 
1070     result = dixLookupResourceByClass((void **) &dst, stuff->dstDrawable,
1071                                       XRC_DRAWABLE, client, DixWriteAccess);
1072     if (result != Success)
1073         return (result == BadValue) ? BadDrawable : result;
1074 
1075     dstShared = IS_SHARED_PIXMAP(dst);
1076 
1077     if (dstShared && srcShared)
1078         return (*SavedProcVector[X_CopyArea]) (client);
1079 
1080     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1081                                      client, DixReadAccess);
1082     if (result != Success)
1083         return result;
1084 
1085     if ((dst->type == XRT_WINDOW) && dst->u.win.root)
1086         dstIsRoot = TRUE;
1087     if ((src->type == XRT_WINDOW) && src->u.win.root)
1088         srcIsRoot = TRUE;
1089 
1090     srcx = stuff->srcX;
1091     srcy = stuff->srcY;
1092     dstx = stuff->dstX;
1093     dsty = stuff->dstY;
1094     width = stuff->width;
1095     height = stuff->height;
1096     if ((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) {
1097         DrawablePtr drawables[MAXSCREENS];
1098         DrawablePtr pDst;
1099         GCPtr pGC;
1100         char *data;
1101         int pitch, rc;
1102 
1103         FOR_NSCREENS(j) {
1104             rc = dixLookupDrawable(drawables + j, src->info[j].id, client, 0,
1105                                    DixGetAttrAccess);
1106             if (rc != Success)
1107                 return rc;
1108             drawables[j]->pScreen->SourceValidate(drawables[j], 0, 0,
1109                                                   drawables[j]->width,
1110                                                   drawables[j]->height,
1111                                                   IncludeInferiors);
1112         }
1113 
1114         pitch = PixmapBytePad(width, drawables[0]->depth);
1115         if (!(data = calloc(height, pitch)))
1116             return BadAlloc;
1117 
1118         XineramaGetImageData(drawables, srcx, srcy, width, height, ZPixmap, ~0,
1119                              data, pitch, srcIsRoot);
1120 
1121         FOR_NSCREENS_BACKWARD(j) {
1122             stuff->gc = gc->info[j].id;
1123             VALIDATE_DRAWABLE_AND_GC(dst->info[j].id, pDst, DixWriteAccess);
1124             if (drawables[0]->depth != pDst->depth) {
1125                 client->errorValue = stuff->dstDrawable;
1126                 free(data);
1127                 return BadMatch;
1128             }
1129 
1130             (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty,
1131                                    width, height, 0, ZPixmap, data);
1132             if (dstShared)
1133                 break;
1134         }
1135         free(data);
1136 
1137         if (pGC->graphicsExposures) {
1138             RegionRec rgn;
1139             int dx, dy;
1140             BoxRec sourceBox;
1141 
1142             dx = drawables[0]->x;
1143             dy = drawables[0]->y;
1144             if (srcIsRoot) {
1145                 dx += screenInfo.screens[0]->x;
1146                 dy += screenInfo.screens[0]->y;
1147             }
1148 
1149             sourceBox.x1 = min(srcx + dx, 0);
1150             sourceBox.y1 = min(srcy + dy, 0);
1151             sourceBox.x2 = max(sourceBox.x1 + width, 32767);
1152             sourceBox.y2 = max(sourceBox.y1 + height, 32767);
1153 
1154             RegionInit(&rgn, &sourceBox, 1);
1155 
1156             /* subtract the (screen-space) clips of the source drawables */
1157             FOR_NSCREENS(j) {
1158                 ScreenPtr screen = screenInfo.screens[j];
1159                 RegionPtr sd;
1160 
1161                 if (pGC->subWindowMode == IncludeInferiors)
1162                     sd = NotClippedByChildren((WindowPtr)drawables[j]);
1163                 else
1164                     sd = &((WindowPtr)drawables[j])->clipList;
1165 
1166                 if (srcIsRoot)
1167                     RegionTranslate(&rgn, -screen->x, -screen->y);
1168 
1169                 RegionSubtract(&rgn, &rgn, sd);
1170 
1171                 if (srcIsRoot)
1172                     RegionTranslate(&rgn, screen->x, screen->y);
1173 
1174                 if (pGC->subWindowMode == IncludeInferiors)
1175                     RegionDestroy(sd);
1176             }
1177 
1178             /* -dx/-dy to get back to dest-relative, plus request offsets */
1179             RegionTranslate(&rgn, -dx + dstx, -dy + dsty);
1180 
1181             /* intersect with gc clip; just one screen is fine because pixmap */
1182             RegionIntersect(&rgn, &rgn, pGC->pCompositeClip);
1183 
1184             /* and expose */
1185             SendGraphicsExpose(client, &rgn, dst->info[0].id, X_CopyArea, 0);
1186             RegionUninit(&rgn);
1187         }
1188     }
1189     else {
1190         DrawablePtr pDst = NULL, pSrc = NULL;
1191         GCPtr pGC = NULL;
1192         RegionRec totalReg;
1193         int rc;
1194 
1195         RegionNull(&totalReg);
1196         FOR_NSCREENS_BACKWARD(j) {
1197             RegionPtr pRgn;
1198 
1199             stuff->dstDrawable = dst->info[j].id;
1200             stuff->srcDrawable = src->info[j].id;
1201             stuff->gc = gc->info[j].id;
1202             if (srcIsRoot) {
1203                 stuff->srcX = srcx - screenInfo.screens[j]->x;
1204                 stuff->srcY = srcy - screenInfo.screens[j]->y;
1205             }
1206             if (dstIsRoot) {
1207                 stuff->dstX = dstx - screenInfo.screens[j]->x;
1208                 stuff->dstY = dsty - screenInfo.screens[j]->y;
1209             }
1210 
1211             VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
1212 
1213             if (stuff->dstDrawable != stuff->srcDrawable) {
1214                 rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
1215                                        DixReadAccess);
1216                 if (rc != Success)
1217                     return rc;
1218 
1219                 if ((pDst->pScreen != pSrc->pScreen) ||
1220                     (pDst->depth != pSrc->depth)) {
1221                     client->errorValue = stuff->dstDrawable;
1222                     return BadMatch;
1223                 }
1224             }
1225             else
1226                 pSrc = pDst;
1227 
1228             pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
1229                                           stuff->srcX, stuff->srcY,
1230                                           stuff->width, stuff->height,
1231                                           stuff->dstX, stuff->dstY);
1232             if (pGC->graphicsExposures && pRgn) {
1233                 if (srcIsRoot) {
1234                     RegionTranslate(pRgn,
1235                                     screenInfo.screens[j]->x,
1236                                     screenInfo.screens[j]->y);
1237                 }
1238                 RegionAppend(&totalReg, pRgn);
1239                 RegionDestroy(pRgn);
1240             }
1241 
1242             if (dstShared)
1243                 break;
1244         }
1245 
1246         if (pGC->graphicsExposures) {
1247             Bool overlap;
1248 
1249             RegionValidate(&totalReg, &overlap);
1250             SendGraphicsExpose(client, &totalReg, stuff->dstDrawable,
1251                                X_CopyArea, 0);
1252             RegionUninit(&totalReg);
1253         }
1254     }
1255 
1256     return Success;
1257 }
1258 
1259 int
PanoramiXCopyPlane(ClientPtr client)1260 PanoramiXCopyPlane(ClientPtr client)
1261 {
1262     int j, srcx, srcy, dstx, dsty, rc;
1263     PanoramiXRes *gc, *src, *dst;
1264     Bool srcIsRoot = FALSE;
1265     Bool dstIsRoot = FALSE;
1266     Bool srcShared, dstShared;
1267     DrawablePtr psrcDraw, pdstDraw = NULL;
1268     GCPtr pGC = NULL;
1269     RegionRec totalReg;
1270 
1271     REQUEST(xCopyPlaneReq);
1272 
1273     REQUEST_SIZE_MATCH(xCopyPlaneReq);
1274 
1275     rc = dixLookupResourceByClass((void **) &src, stuff->srcDrawable,
1276                                   XRC_DRAWABLE, client, DixReadAccess);
1277     if (rc != Success)
1278         return (rc == BadValue) ? BadDrawable : rc;
1279 
1280     srcShared = IS_SHARED_PIXMAP(src);
1281 
1282     rc = dixLookupResourceByClass((void **) &dst, stuff->dstDrawable,
1283                                   XRC_DRAWABLE, client, DixWriteAccess);
1284     if (rc != Success)
1285         return (rc == BadValue) ? BadDrawable : rc;
1286 
1287     dstShared = IS_SHARED_PIXMAP(dst);
1288 
1289     if (dstShared && srcShared)
1290         return (*SavedProcVector[X_CopyPlane]) (client);
1291 
1292     rc = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1293                                  client, DixReadAccess);
1294     if (rc != Success)
1295         return rc;
1296 
1297     if ((dst->type == XRT_WINDOW) && dst->u.win.root)
1298         dstIsRoot = TRUE;
1299     if ((src->type == XRT_WINDOW) && src->u.win.root)
1300         srcIsRoot = TRUE;
1301 
1302     srcx = stuff->srcX;
1303     srcy = stuff->srcY;
1304     dstx = stuff->dstX;
1305     dsty = stuff->dstY;
1306 
1307     RegionNull(&totalReg);
1308     FOR_NSCREENS_BACKWARD(j) {
1309         RegionPtr pRgn;
1310 
1311         stuff->dstDrawable = dst->info[j].id;
1312         stuff->srcDrawable = src->info[j].id;
1313         stuff->gc = gc->info[j].id;
1314         if (srcIsRoot) {
1315             stuff->srcX = srcx - screenInfo.screens[j]->x;
1316             stuff->srcY = srcy - screenInfo.screens[j]->y;
1317         }
1318         if (dstIsRoot) {
1319             stuff->dstX = dstx - screenInfo.screens[j]->x;
1320             stuff->dstY = dsty - screenInfo.screens[j]->y;
1321         }
1322 
1323         VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
1324         if (stuff->dstDrawable != stuff->srcDrawable) {
1325             rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
1326                                    DixReadAccess);
1327             if (rc != Success)
1328                 return rc;
1329 
1330             if (pdstDraw->pScreen != psrcDraw->pScreen) {
1331                 client->errorValue = stuff->dstDrawable;
1332                 return BadMatch;
1333             }
1334         }
1335         else
1336             psrcDraw = pdstDraw;
1337 
1338         if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
1339             (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
1340             client->errorValue = stuff->bitPlane;
1341             return BadValue;
1342         }
1343 
1344         pRgn = (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC,
1345                                        stuff->srcX, stuff->srcY,
1346                                        stuff->width, stuff->height,
1347                                        stuff->dstX, stuff->dstY,
1348                                        stuff->bitPlane);
1349         if (pGC->graphicsExposures && pRgn) {
1350             RegionAppend(&totalReg, pRgn);
1351             RegionDestroy(pRgn);
1352         }
1353 
1354         if (dstShared)
1355             break;
1356     }
1357 
1358     if (pGC->graphicsExposures) {
1359         Bool overlap;
1360 
1361         RegionValidate(&totalReg, &overlap);
1362         SendGraphicsExpose(client, &totalReg, stuff->dstDrawable,
1363                            X_CopyPlane, 0);
1364         RegionUninit(&totalReg);
1365     }
1366 
1367     return Success;
1368 }
1369 
1370 int
PanoramiXPolyPoint(ClientPtr client)1371 PanoramiXPolyPoint(ClientPtr client)
1372 {
1373     PanoramiXRes *gc, *draw;
1374     int result, npoint, j;
1375     xPoint *origPts;
1376     Bool isRoot;
1377 
1378     REQUEST(xPolyPointReq);
1379 
1380     REQUEST_AT_LEAST_SIZE(xPolyPointReq);
1381 
1382     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1383                                       XRC_DRAWABLE, client, DixWriteAccess);
1384     if (result != Success)
1385         return (result == BadValue) ? BadDrawable : result;
1386 
1387     if (IS_SHARED_PIXMAP(draw))
1388         return (*SavedProcVector[X_PolyPoint]) (client);
1389 
1390     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1391                                      client, DixReadAccess);
1392     if (result != Success)
1393         return result;
1394 
1395     isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1396     npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
1397     if (npoint > 0) {
1398         origPts = xallocarray(npoint, sizeof(xPoint));
1399         memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
1400         FOR_NSCREENS_FORWARD(j) {
1401 
1402             if (j)
1403                 memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
1404 
1405             if (isRoot) {
1406                 int x_off = screenInfo.screens[j]->x;
1407                 int y_off = screenInfo.screens[j]->y;
1408 
1409                 if (x_off || y_off) {
1410                     xPoint *pnts = (xPoint *) &stuff[1];
1411                     int i =
1412                         (stuff->coordMode == CoordModePrevious) ? 1 : npoint;
1413 
1414                     while (i--) {
1415                         pnts->x -= x_off;
1416                         pnts->y -= y_off;
1417                         pnts++;
1418                     }
1419                 }
1420             }
1421 
1422             stuff->drawable = draw->info[j].id;
1423             stuff->gc = gc->info[j].id;
1424             result = (*SavedProcVector[X_PolyPoint]) (client);
1425             if (result != Success)
1426                 break;
1427         }
1428         free(origPts);
1429         return result;
1430     }
1431     else
1432         return Success;
1433 }
1434 
1435 int
PanoramiXPolyLine(ClientPtr client)1436 PanoramiXPolyLine(ClientPtr client)
1437 {
1438     PanoramiXRes *gc, *draw;
1439     int result, npoint, j;
1440     xPoint *origPts;
1441     Bool isRoot;
1442 
1443     REQUEST(xPolyLineReq);
1444 
1445     REQUEST_AT_LEAST_SIZE(xPolyLineReq);
1446 
1447     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1448                                       XRC_DRAWABLE, client, DixWriteAccess);
1449     if (result != Success)
1450         return (result == BadValue) ? BadDrawable : result;
1451 
1452     if (IS_SHARED_PIXMAP(draw))
1453         return (*SavedProcVector[X_PolyLine]) (client);
1454 
1455     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1456                                      client, DixReadAccess);
1457     if (result != Success)
1458         return result;
1459 
1460     isRoot = IS_ROOT_DRAWABLE(draw);
1461     npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
1462     if (npoint > 0) {
1463         origPts = xallocarray(npoint, sizeof(xPoint));
1464         memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
1465         FOR_NSCREENS_FORWARD(j) {
1466 
1467             if (j)
1468                 memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
1469 
1470             if (isRoot) {
1471                 int x_off = screenInfo.screens[j]->x;
1472                 int y_off = screenInfo.screens[j]->y;
1473 
1474                 if (x_off || y_off) {
1475                     xPoint *pnts = (xPoint *) &stuff[1];
1476                     int i =
1477                         (stuff->coordMode == CoordModePrevious) ? 1 : npoint;
1478 
1479                     while (i--) {
1480                         pnts->x -= x_off;
1481                         pnts->y -= y_off;
1482                         pnts++;
1483                     }
1484                 }
1485             }
1486 
1487             stuff->drawable = draw->info[j].id;
1488             stuff->gc = gc->info[j].id;
1489             result = (*SavedProcVector[X_PolyLine]) (client);
1490             if (result != Success)
1491                 break;
1492         }
1493         free(origPts);
1494         return result;
1495     }
1496     else
1497         return Success;
1498 }
1499 
1500 int
PanoramiXPolySegment(ClientPtr client)1501 PanoramiXPolySegment(ClientPtr client)
1502 {
1503     int result, nsegs, i, j;
1504     PanoramiXRes *gc, *draw;
1505     xSegment *origSegs;
1506     Bool isRoot;
1507 
1508     REQUEST(xPolySegmentReq);
1509 
1510     REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
1511 
1512     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1513                                       XRC_DRAWABLE, client, DixWriteAccess);
1514     if (result != Success)
1515         return (result == BadValue) ? BadDrawable : result;
1516 
1517     if (IS_SHARED_PIXMAP(draw))
1518         return (*SavedProcVector[X_PolySegment]) (client);
1519 
1520     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1521                                      client, DixReadAccess);
1522     if (result != Success)
1523         return result;
1524 
1525     isRoot = IS_ROOT_DRAWABLE(draw);
1526 
1527     nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
1528     if (nsegs & 4)
1529         return BadLength;
1530     nsegs >>= 3;
1531     if (nsegs > 0) {
1532         origSegs = xallocarray(nsegs, sizeof(xSegment));
1533         memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment));
1534         FOR_NSCREENS_FORWARD(j) {
1535 
1536             if (j)
1537                 memcpy(&stuff[1], origSegs, nsegs * sizeof(xSegment));
1538 
1539             if (isRoot) {
1540                 int x_off = screenInfo.screens[j]->x;
1541                 int y_off = screenInfo.screens[j]->y;
1542 
1543                 if (x_off || y_off) {
1544                     xSegment *segs = (xSegment *) &stuff[1];
1545 
1546                     for (i = nsegs; i--; segs++) {
1547                         segs->x1 -= x_off;
1548                         segs->x2 -= x_off;
1549                         segs->y1 -= y_off;
1550                         segs->y2 -= y_off;
1551                     }
1552                 }
1553             }
1554 
1555             stuff->drawable = draw->info[j].id;
1556             stuff->gc = gc->info[j].id;
1557             result = (*SavedProcVector[X_PolySegment]) (client);
1558             if (result != Success)
1559                 break;
1560         }
1561         free(origSegs);
1562         return result;
1563     }
1564     else
1565         return Success;
1566 }
1567 
1568 int
PanoramiXPolyRectangle(ClientPtr client)1569 PanoramiXPolyRectangle(ClientPtr client)
1570 {
1571     int result, nrects, i, j;
1572     PanoramiXRes *gc, *draw;
1573     Bool isRoot;
1574     xRectangle *origRecs;
1575 
1576     REQUEST(xPolyRectangleReq);
1577 
1578     REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
1579 
1580     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1581                                       XRC_DRAWABLE, client, DixWriteAccess);
1582     if (result != Success)
1583         return (result == BadValue) ? BadDrawable : result;
1584 
1585     if (IS_SHARED_PIXMAP(draw))
1586         return (*SavedProcVector[X_PolyRectangle]) (client);
1587 
1588     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1589                                      client, DixReadAccess);
1590     if (result != Success)
1591         return result;
1592 
1593     isRoot = IS_ROOT_DRAWABLE(draw);
1594 
1595     nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
1596     if (nrects & 4)
1597         return BadLength;
1598     nrects >>= 3;
1599     if (nrects > 0) {
1600         origRecs = xallocarray(nrects, sizeof(xRectangle));
1601         memcpy((char *) origRecs, (char *) &stuff[1],
1602                nrects * sizeof(xRectangle));
1603         FOR_NSCREENS_FORWARD(j) {
1604 
1605             if (j)
1606                 memcpy(&stuff[1], origRecs, nrects * sizeof(xRectangle));
1607 
1608             if (isRoot) {
1609                 int x_off = screenInfo.screens[j]->x;
1610                 int y_off = screenInfo.screens[j]->y;
1611 
1612                 if (x_off || y_off) {
1613                     xRectangle *rects = (xRectangle *) &stuff[1];
1614 
1615                     for (i = nrects; i--; rects++) {
1616                         rects->x -= x_off;
1617                         rects->y -= y_off;
1618                     }
1619                 }
1620             }
1621 
1622             stuff->drawable = draw->info[j].id;
1623             stuff->gc = gc->info[j].id;
1624             result = (*SavedProcVector[X_PolyRectangle]) (client);
1625             if (result != Success)
1626                 break;
1627         }
1628         free(origRecs);
1629         return result;
1630     }
1631     else
1632         return Success;
1633 }
1634 
1635 int
PanoramiXPolyArc(ClientPtr client)1636 PanoramiXPolyArc(ClientPtr client)
1637 {
1638     int result, narcs, i, j;
1639     PanoramiXRes *gc, *draw;
1640     Bool isRoot;
1641     xArc *origArcs;
1642 
1643     REQUEST(xPolyArcReq);
1644 
1645     REQUEST_AT_LEAST_SIZE(xPolyArcReq);
1646 
1647     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1648                                       XRC_DRAWABLE, client, DixWriteAccess);
1649     if (result != Success)
1650         return (result == BadValue) ? BadDrawable : result;
1651 
1652     if (IS_SHARED_PIXMAP(draw))
1653         return (*SavedProcVector[X_PolyArc]) (client);
1654 
1655     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1656                                      client, DixReadAccess);
1657     if (result != Success)
1658         return result;
1659 
1660     isRoot = IS_ROOT_DRAWABLE(draw);
1661 
1662     narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
1663     if (narcs % sizeof(xArc))
1664         return BadLength;
1665     narcs /= sizeof(xArc);
1666     if (narcs > 0) {
1667         origArcs = xallocarray(narcs, sizeof(xArc));
1668         memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
1669         FOR_NSCREENS_FORWARD(j) {
1670 
1671             if (j)
1672                 memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
1673 
1674             if (isRoot) {
1675                 int x_off = screenInfo.screens[j]->x;
1676                 int y_off = screenInfo.screens[j]->y;
1677 
1678                 if (x_off || y_off) {
1679                     xArc *arcs = (xArc *) &stuff[1];
1680 
1681                     for (i = narcs; i--; arcs++) {
1682                         arcs->x -= x_off;
1683                         arcs->y -= y_off;
1684                     }
1685                 }
1686             }
1687             stuff->drawable = draw->info[j].id;
1688             stuff->gc = gc->info[j].id;
1689             result = (*SavedProcVector[X_PolyArc]) (client);
1690             if (result != Success)
1691                 break;
1692         }
1693         free(origArcs);
1694         return result;
1695     }
1696     else
1697         return Success;
1698 }
1699 
1700 int
PanoramiXFillPoly(ClientPtr client)1701 PanoramiXFillPoly(ClientPtr client)
1702 {
1703     int result, count, j;
1704     PanoramiXRes *gc, *draw;
1705     Bool isRoot;
1706     DDXPointPtr locPts;
1707 
1708     REQUEST(xFillPolyReq);
1709 
1710     REQUEST_AT_LEAST_SIZE(xFillPolyReq);
1711 
1712     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1713                                       XRC_DRAWABLE, client, DixWriteAccess);
1714     if (result != Success)
1715         return (result == BadValue) ? BadDrawable : result;
1716 
1717     if (IS_SHARED_PIXMAP(draw))
1718         return (*SavedProcVector[X_FillPoly]) (client);
1719 
1720     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1721                                      client, DixReadAccess);
1722     if (result != Success)
1723         return result;
1724 
1725     isRoot = IS_ROOT_DRAWABLE(draw);
1726 
1727     count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
1728     if (count > 0) {
1729         locPts = xallocarray(count, sizeof(DDXPointRec));
1730         memcpy((char *) locPts, (char *) &stuff[1],
1731                count * sizeof(DDXPointRec));
1732         FOR_NSCREENS_FORWARD(j) {
1733 
1734             if (j)
1735                 memcpy(&stuff[1], locPts, count * sizeof(DDXPointRec));
1736 
1737             if (isRoot) {
1738                 int x_off = screenInfo.screens[j]->x;
1739                 int y_off = screenInfo.screens[j]->y;
1740 
1741                 if (x_off || y_off) {
1742                     DDXPointPtr pnts = (DDXPointPtr) &stuff[1];
1743                     int i = (stuff->coordMode == CoordModePrevious) ? 1 : count;
1744 
1745                     while (i--) {
1746                         pnts->x -= x_off;
1747                         pnts->y -= y_off;
1748                         pnts++;
1749                     }
1750                 }
1751             }
1752 
1753             stuff->drawable = draw->info[j].id;
1754             stuff->gc = gc->info[j].id;
1755             result = (*SavedProcVector[X_FillPoly]) (client);
1756             if (result != Success)
1757                 break;
1758         }
1759         free(locPts);
1760         return result;
1761     }
1762     else
1763         return Success;
1764 }
1765 
1766 int
PanoramiXPolyFillRectangle(ClientPtr client)1767 PanoramiXPolyFillRectangle(ClientPtr client)
1768 {
1769     int result, things, i, j;
1770     PanoramiXRes *gc, *draw;
1771     Bool isRoot;
1772     xRectangle *origRects;
1773 
1774     REQUEST(xPolyFillRectangleReq);
1775 
1776     REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
1777 
1778     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1779                                       XRC_DRAWABLE, client, DixWriteAccess);
1780     if (result != Success)
1781         return (result == BadValue) ? BadDrawable : result;
1782 
1783     if (IS_SHARED_PIXMAP(draw))
1784         return (*SavedProcVector[X_PolyFillRectangle]) (client);
1785 
1786     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1787                                      client, DixReadAccess);
1788     if (result != Success)
1789         return result;
1790 
1791     isRoot = IS_ROOT_DRAWABLE(draw);
1792 
1793     things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
1794     if (things & 4)
1795         return BadLength;
1796     things >>= 3;
1797     if (things > 0) {
1798         origRects = xallocarray(things, sizeof(xRectangle));
1799         memcpy((char *) origRects, (char *) &stuff[1],
1800                things * sizeof(xRectangle));
1801         FOR_NSCREENS_FORWARD(j) {
1802 
1803             if (j)
1804                 memcpy(&stuff[1], origRects, things * sizeof(xRectangle));
1805 
1806             if (isRoot) {
1807                 int x_off = screenInfo.screens[j]->x;
1808                 int y_off = screenInfo.screens[j]->y;
1809 
1810                 if (x_off || y_off) {
1811                     xRectangle *rects = (xRectangle *) &stuff[1];
1812 
1813                     for (i = things; i--; rects++) {
1814                         rects->x -= x_off;
1815                         rects->y -= y_off;
1816                     }
1817                 }
1818             }
1819 
1820             stuff->drawable = draw->info[j].id;
1821             stuff->gc = gc->info[j].id;
1822             result = (*SavedProcVector[X_PolyFillRectangle]) (client);
1823             if (result != Success)
1824                 break;
1825         }
1826         free(origRects);
1827         return result;
1828     }
1829     else
1830         return Success;
1831 }
1832 
1833 int
PanoramiXPolyFillArc(ClientPtr client)1834 PanoramiXPolyFillArc(ClientPtr client)
1835 {
1836     PanoramiXRes *gc, *draw;
1837     Bool isRoot;
1838     int result, narcs, i, j;
1839     xArc *origArcs;
1840 
1841     REQUEST(xPolyFillArcReq);
1842 
1843     REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
1844 
1845     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1846                                       XRC_DRAWABLE, client, DixWriteAccess);
1847     if (result != Success)
1848         return (result == BadValue) ? BadDrawable : result;
1849 
1850     if (IS_SHARED_PIXMAP(draw))
1851         return (*SavedProcVector[X_PolyFillArc]) (client);
1852 
1853     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1854                                      client, DixReadAccess);
1855     if (result != Success)
1856         return result;
1857 
1858     isRoot = IS_ROOT_DRAWABLE(draw);
1859 
1860     narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
1861     if (narcs % sizeof(xArc))
1862         return BadLength;
1863     narcs /= sizeof(xArc);
1864     if (narcs > 0) {
1865         origArcs = xallocarray(narcs, sizeof(xArc));
1866         memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
1867         FOR_NSCREENS_FORWARD(j) {
1868 
1869             if (j)
1870                 memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
1871 
1872             if (isRoot) {
1873                 int x_off = screenInfo.screens[j]->x;
1874                 int y_off = screenInfo.screens[j]->y;
1875 
1876                 if (x_off || y_off) {
1877                     xArc *arcs = (xArc *) &stuff[1];
1878 
1879                     for (i = narcs; i--; arcs++) {
1880                         arcs->x -= x_off;
1881                         arcs->y -= y_off;
1882                     }
1883                 }
1884             }
1885 
1886             stuff->drawable = draw->info[j].id;
1887             stuff->gc = gc->info[j].id;
1888             result = (*SavedProcVector[X_PolyFillArc]) (client);
1889             if (result != Success)
1890                 break;
1891         }
1892         free(origArcs);
1893         return result;
1894     }
1895     else
1896         return Success;
1897 }
1898 
1899 int
PanoramiXPutImage(ClientPtr client)1900 PanoramiXPutImage(ClientPtr client)
1901 {
1902     PanoramiXRes *gc, *draw;
1903     Bool isRoot;
1904     int j, result, orig_x, orig_y;
1905 
1906     REQUEST(xPutImageReq);
1907 
1908     REQUEST_AT_LEAST_SIZE(xPutImageReq);
1909 
1910     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1911                                       XRC_DRAWABLE, client, DixWriteAccess);
1912     if (result != Success)
1913         return (result == BadValue) ? BadDrawable : result;
1914 
1915     if (IS_SHARED_PIXMAP(draw))
1916         return (*SavedProcVector[X_PutImage]) (client);
1917 
1918     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1919                                      client, DixReadAccess);
1920     if (result != Success)
1921         return result;
1922 
1923     isRoot = IS_ROOT_DRAWABLE(draw);
1924 
1925     orig_x = stuff->dstX;
1926     orig_y = stuff->dstY;
1927     FOR_NSCREENS_BACKWARD(j) {
1928         if (isRoot) {
1929             stuff->dstX = orig_x - screenInfo.screens[j]->x;
1930             stuff->dstY = orig_y - screenInfo.screens[j]->y;
1931         }
1932         stuff->drawable = draw->info[j].id;
1933         stuff->gc = gc->info[j].id;
1934         result = (*SavedProcVector[X_PutImage]) (client);
1935         if (result != Success)
1936             break;
1937     }
1938     return result;
1939 }
1940 
1941 int
PanoramiXGetImage(ClientPtr client)1942 PanoramiXGetImage(ClientPtr client)
1943 {
1944     DrawablePtr drawables[MAXSCREENS];
1945     DrawablePtr pDraw;
1946     PanoramiXRes *draw;
1947     xGetImageReply xgi;
1948     Bool isRoot;
1949     char *pBuf;
1950     int i, x, y, w, h, format, rc;
1951     Mask plane = 0, planemask;
1952     int linesDone, nlines, linesPerBuf;
1953     long widthBytesLine, length;
1954 
1955     REQUEST(xGetImageReq);
1956 
1957     REQUEST_SIZE_MATCH(xGetImageReq);
1958 
1959     if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
1960         client->errorValue = stuff->format;
1961         return BadValue;
1962     }
1963 
1964     rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1965                                   XRC_DRAWABLE, client, DixReadAccess);
1966     if (rc != Success)
1967         return (rc == BadValue) ? BadDrawable : rc;
1968 
1969     if (draw->type == XRT_PIXMAP)
1970         return (*SavedProcVector[X_GetImage]) (client);
1971 
1972     rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess);
1973     if (rc != Success)
1974         return rc;
1975 
1976     if (!((WindowPtr) pDraw)->realized)
1977         return BadMatch;
1978 
1979     x = stuff->x;
1980     y = stuff->y;
1981     w = stuff->width;
1982     h = stuff->height;
1983     format = stuff->format;
1984     planemask = stuff->planeMask;
1985 
1986     isRoot = IS_ROOT_DRAWABLE(draw);
1987 
1988     if (isRoot) {
1989         /* check for being onscreen */
1990         if (x < 0 || x + w > PanoramiXPixWidth ||
1991             y < 0 || y + h > PanoramiXPixHeight)
1992             return BadMatch;
1993     }
1994     else {
1995         /* check for being onscreen and inside of border */
1996         if (screenInfo.screens[0]->x + pDraw->x + x < 0 ||
1997             screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth ||
1998             screenInfo.screens[0]->y + pDraw->y + y < 0 ||
1999             screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight ||
2000             x < -wBorderWidth((WindowPtr) pDraw) ||
2001             x + w > wBorderWidth((WindowPtr) pDraw) + (int) pDraw->width ||
2002             y < -wBorderWidth((WindowPtr) pDraw) ||
2003             y + h > wBorderWidth((WindowPtr) pDraw) + (int) pDraw->height)
2004             return BadMatch;
2005     }
2006 
2007     drawables[0] = pDraw;
2008     FOR_NSCREENS_FORWARD_SKIP(i) {
2009         rc = dixLookupDrawable(drawables + i, draw->info[i].id, client, 0,
2010                                DixGetAttrAccess);
2011         if (rc != Success)
2012             return rc;
2013     }
2014     FOR_NSCREENS_FORWARD(i) {
2015         drawables[i]->pScreen->SourceValidate(drawables[i], 0, 0,
2016                                               drawables[i]->width,
2017                                               drawables[i]->height,
2018                                               IncludeInferiors);
2019     }
2020 
2021     xgi = (xGetImageReply) {
2022         .type = X_Reply,
2023         .sequenceNumber = client->sequence,
2024         .visual = wVisual(((WindowPtr) pDraw)),
2025         .depth = pDraw->depth
2026     };
2027     if (format == ZPixmap) {
2028         widthBytesLine = PixmapBytePad(w, pDraw->depth);
2029         length = widthBytesLine * h;
2030 
2031     }
2032     else {
2033         widthBytesLine = BitmapBytePad(w);
2034         plane = ((Mask) 1) << (pDraw->depth - 1);
2035         /* only planes asked for */
2036         length = widthBytesLine * h * Ones(planemask & (plane | (plane - 1)));
2037 
2038     }
2039 
2040     xgi.length = bytes_to_int32(length);
2041 
2042     if (widthBytesLine == 0 || h == 0)
2043         linesPerBuf = 0;
2044     else if (widthBytesLine >= XINERAMA_IMAGE_BUFSIZE)
2045         linesPerBuf = 1;
2046     else {
2047         linesPerBuf = XINERAMA_IMAGE_BUFSIZE / widthBytesLine;
2048         if (linesPerBuf > h)
2049             linesPerBuf = h;
2050     }
2051     if (!(pBuf = xallocarray(linesPerBuf, widthBytesLine)))
2052         return BadAlloc;
2053 
2054     WriteReplyToClient(client, sizeof(xGetImageReply), &xgi);
2055 
2056     if (linesPerBuf == 0) {
2057         /* nothing to do */
2058     }
2059     else if (format == ZPixmap) {
2060         linesDone = 0;
2061         while (h - linesDone > 0) {
2062             nlines = min(linesPerBuf, h - linesDone);
2063 
2064             if (pDraw->depth == 1)
2065                 memset(pBuf, 0, nlines * widthBytesLine);
2066 
2067             XineramaGetImageData(drawables, x, y + linesDone, w, nlines,
2068                                  format, planemask, pBuf, widthBytesLine,
2069                                  isRoot);
2070 
2071             WriteToClient(client, (int) (nlines * widthBytesLine), pBuf);
2072             linesDone += nlines;
2073         }
2074     }
2075     else {                      /* XYPixmap */
2076         for (; plane; plane >>= 1) {
2077             if (planemask & plane) {
2078                 linesDone = 0;
2079                 while (h - linesDone > 0) {
2080                     nlines = min(linesPerBuf, h - linesDone);
2081 
2082                     memset(pBuf, 0, nlines * widthBytesLine);
2083 
2084                     XineramaGetImageData(drawables, x, y + linesDone, w,
2085                                          nlines, format, plane, pBuf,
2086                                          widthBytesLine, isRoot);
2087 
2088                     WriteToClient(client, (int)(nlines * widthBytesLine), pBuf);
2089 
2090                     linesDone += nlines;
2091                 }
2092             }
2093         }
2094     }
2095     free(pBuf);
2096     return Success;
2097 }
2098 
2099 /* The text stuff should be rewritten so that duplication happens
2100    at the GlyphBlt level.  That is, loading the font and getting
2101    the glyphs should only happen once */
2102 
2103 int
PanoramiXPolyText8(ClientPtr client)2104 PanoramiXPolyText8(ClientPtr client)
2105 {
2106     PanoramiXRes *gc, *draw;
2107     Bool isRoot;
2108     int result, j;
2109     int orig_x, orig_y;
2110 
2111     REQUEST(xPolyTextReq);
2112 
2113     REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2114 
2115     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
2116                                       XRC_DRAWABLE, client, DixWriteAccess);
2117     if (result != Success)
2118         return (result == BadValue) ? BadDrawable : result;
2119 
2120     if (IS_SHARED_PIXMAP(draw))
2121         return (*SavedProcVector[X_PolyText8]) (client);
2122 
2123     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
2124                                      client, DixReadAccess);
2125     if (result != Success)
2126         return result;
2127 
2128     isRoot = IS_ROOT_DRAWABLE(draw);
2129 
2130     orig_x = stuff->x;
2131     orig_y = stuff->y;
2132     FOR_NSCREENS_BACKWARD(j) {
2133         stuff->drawable = draw->info[j].id;
2134         stuff->gc = gc->info[j].id;
2135         if (isRoot) {
2136             stuff->x = orig_x - screenInfo.screens[j]->x;
2137             stuff->y = orig_y - screenInfo.screens[j]->y;
2138         }
2139         result = (*SavedProcVector[X_PolyText8]) (client);
2140         if (result != Success)
2141             break;
2142     }
2143     return result;
2144 }
2145 
2146 int
PanoramiXPolyText16(ClientPtr client)2147 PanoramiXPolyText16(ClientPtr client)
2148 {
2149     PanoramiXRes *gc, *draw;
2150     Bool isRoot;
2151     int result, j;
2152     int orig_x, orig_y;
2153 
2154     REQUEST(xPolyTextReq);
2155 
2156     REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2157 
2158     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
2159                                       XRC_DRAWABLE, client, DixWriteAccess);
2160     if (result != Success)
2161         return (result == BadValue) ? BadDrawable : result;
2162 
2163     if (IS_SHARED_PIXMAP(draw))
2164         return (*SavedProcVector[X_PolyText16]) (client);
2165 
2166     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
2167                                      client, DixReadAccess);
2168     if (result != Success)
2169         return result;
2170 
2171     isRoot = IS_ROOT_DRAWABLE(draw);
2172 
2173     orig_x = stuff->x;
2174     orig_y = stuff->y;
2175     FOR_NSCREENS_BACKWARD(j) {
2176         stuff->drawable = draw->info[j].id;
2177         stuff->gc = gc->info[j].id;
2178         if (isRoot) {
2179             stuff->x = orig_x - screenInfo.screens[j]->x;
2180             stuff->y = orig_y - screenInfo.screens[j]->y;
2181         }
2182         result = (*SavedProcVector[X_PolyText16]) (client);
2183         if (result != Success)
2184             break;
2185     }
2186     return result;
2187 }
2188 
2189 int
PanoramiXImageText8(ClientPtr client)2190 PanoramiXImageText8(ClientPtr client)
2191 {
2192     int result, j;
2193     PanoramiXRes *gc, *draw;
2194     Bool isRoot;
2195     int orig_x, orig_y;
2196 
2197     REQUEST(xImageTextReq);
2198 
2199     REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
2200 
2201     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
2202                                       XRC_DRAWABLE, client, DixWriteAccess);
2203     if (result != Success)
2204         return (result == BadValue) ? BadDrawable : result;
2205 
2206     if (IS_SHARED_PIXMAP(draw))
2207         return (*SavedProcVector[X_ImageText8]) (client);
2208 
2209     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
2210                                      client, DixReadAccess);
2211     if (result != Success)
2212         return result;
2213 
2214     isRoot = IS_ROOT_DRAWABLE(draw);
2215 
2216     orig_x = stuff->x;
2217     orig_y = stuff->y;
2218     FOR_NSCREENS_BACKWARD(j) {
2219         stuff->drawable = draw->info[j].id;
2220         stuff->gc = gc->info[j].id;
2221         if (isRoot) {
2222             stuff->x = orig_x - screenInfo.screens[j]->x;
2223             stuff->y = orig_y - screenInfo.screens[j]->y;
2224         }
2225         result = (*SavedProcVector[X_ImageText8]) (client);
2226         if (result != Success)
2227             break;
2228     }
2229     return result;
2230 }
2231 
2232 int
PanoramiXImageText16(ClientPtr client)2233 PanoramiXImageText16(ClientPtr client)
2234 {
2235     int result, j;
2236     PanoramiXRes *gc, *draw;
2237     Bool isRoot;
2238     int orig_x, orig_y;
2239 
2240     REQUEST(xImageTextReq);
2241 
2242     REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
2243 
2244     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
2245                                       XRC_DRAWABLE, client, DixWriteAccess);
2246     if (result != Success)
2247         return (result == BadValue) ? BadDrawable : result;
2248 
2249     if (IS_SHARED_PIXMAP(draw))
2250         return (*SavedProcVector[X_ImageText16]) (client);
2251 
2252     result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
2253                                      client, DixReadAccess);
2254     if (result != Success)
2255         return result;
2256 
2257     isRoot = IS_ROOT_DRAWABLE(draw);
2258 
2259     orig_x = stuff->x;
2260     orig_y = stuff->y;
2261     FOR_NSCREENS_BACKWARD(j) {
2262         stuff->drawable = draw->info[j].id;
2263         stuff->gc = gc->info[j].id;
2264         if (isRoot) {
2265             stuff->x = orig_x - screenInfo.screens[j]->x;
2266             stuff->y = orig_y - screenInfo.screens[j]->y;
2267         }
2268         result = (*SavedProcVector[X_ImageText16]) (client);
2269         if (result != Success)
2270             break;
2271     }
2272     return result;
2273 }
2274 
2275 int
PanoramiXCreateColormap(ClientPtr client)2276 PanoramiXCreateColormap(ClientPtr client)
2277 {
2278     PanoramiXRes *win, *newCmap;
2279     int result, j, orig_visual;
2280 
2281     REQUEST(xCreateColormapReq);
2282 
2283     REQUEST_SIZE_MATCH(xCreateColormapReq);
2284 
2285     result = dixLookupResourceByType((void **) &win, stuff->window,
2286                                      XRT_WINDOW, client, DixReadAccess);
2287     if (result != Success)
2288         return result;
2289 
2290     if (!(newCmap = malloc(sizeof(PanoramiXRes))))
2291         return BadAlloc;
2292 
2293     newCmap->type = XRT_COLORMAP;
2294     panoramix_setup_ids(newCmap, client, stuff->mid);
2295 
2296     orig_visual = stuff->visual;
2297     FOR_NSCREENS_BACKWARD(j) {
2298         stuff->mid = newCmap->info[j].id;
2299         stuff->window = win->info[j].id;
2300         stuff->visual = PanoramiXTranslateVisualID(j, orig_visual);
2301         result = (*SavedProcVector[X_CreateColormap]) (client);
2302         if (result != Success)
2303             break;
2304     }
2305 
2306     if (result == Success)
2307         AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
2308     else
2309         free(newCmap);
2310 
2311     return result;
2312 }
2313 
2314 int
PanoramiXFreeColormap(ClientPtr client)2315 PanoramiXFreeColormap(ClientPtr client)
2316 {
2317     PanoramiXRes *cmap;
2318     int result, j;
2319 
2320     REQUEST(xResourceReq);
2321 
2322     REQUEST_SIZE_MATCH(xResourceReq);
2323 
2324     client->errorValue = stuff->id;
2325 
2326     result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
2327                                      client, DixDestroyAccess);
2328     if (result != Success)
2329         return result;
2330 
2331     FOR_NSCREENS_BACKWARD(j) {
2332         stuff->id = cmap->info[j].id;
2333         result = (*SavedProcVector[X_FreeColormap]) (client);
2334         if (result != Success)
2335             break;
2336     }
2337 
2338     /* Since ProcFreeColormap is using FreeResource, it will free
2339        our resource for us on the last pass through the loop above */
2340 
2341     return result;
2342 }
2343 
2344 int
PanoramiXCopyColormapAndFree(ClientPtr client)2345 PanoramiXCopyColormapAndFree(ClientPtr client)
2346 {
2347     PanoramiXRes *cmap, *newCmap;
2348     int result, j;
2349 
2350     REQUEST(xCopyColormapAndFreeReq);
2351 
2352     REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
2353 
2354     client->errorValue = stuff->srcCmap;
2355 
2356     result = dixLookupResourceByType((void **) &cmap, stuff->srcCmap,
2357                                      XRT_COLORMAP, client,
2358                                      DixReadAccess | DixWriteAccess);
2359     if (result != Success)
2360         return result;
2361 
2362     if (!(newCmap = malloc(sizeof(PanoramiXRes))))
2363         return BadAlloc;
2364 
2365     newCmap->type = XRT_COLORMAP;
2366     panoramix_setup_ids(newCmap, client, stuff->mid);
2367 
2368     FOR_NSCREENS_BACKWARD(j) {
2369         stuff->srcCmap = cmap->info[j].id;
2370         stuff->mid = newCmap->info[j].id;
2371         result = (*SavedProcVector[X_CopyColormapAndFree]) (client);
2372         if (result != Success)
2373             break;
2374     }
2375 
2376     if (result == Success)
2377         AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
2378     else
2379         free(newCmap);
2380 
2381     return result;
2382 }
2383 
2384 int
PanoramiXInstallColormap(ClientPtr client)2385 PanoramiXInstallColormap(ClientPtr client)
2386 {
2387     REQUEST(xResourceReq);
2388     int result, j;
2389     PanoramiXRes *cmap;
2390 
2391     REQUEST_SIZE_MATCH(xResourceReq);
2392 
2393     client->errorValue = stuff->id;
2394 
2395     result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
2396                                      client, DixReadAccess);
2397     if (result != Success)
2398         return result;
2399 
2400     FOR_NSCREENS_BACKWARD(j) {
2401         stuff->id = cmap->info[j].id;
2402         result = (*SavedProcVector[X_InstallColormap]) (client);
2403         if (result != Success)
2404             break;
2405     }
2406     return result;
2407 }
2408 
2409 int
PanoramiXUninstallColormap(ClientPtr client)2410 PanoramiXUninstallColormap(ClientPtr client)
2411 {
2412     REQUEST(xResourceReq);
2413     int result, j;
2414     PanoramiXRes *cmap;
2415 
2416     REQUEST_SIZE_MATCH(xResourceReq);
2417 
2418     client->errorValue = stuff->id;
2419 
2420     result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
2421                                      client, DixReadAccess);
2422     if (result != Success)
2423         return result;
2424 
2425     FOR_NSCREENS_BACKWARD(j) {
2426         stuff->id = cmap->info[j].id;
2427         result = (*SavedProcVector[X_UninstallColormap]) (client);
2428         if (result != Success)
2429             break;
2430     }
2431     return result;
2432 }
2433 
2434 int
PanoramiXAllocColor(ClientPtr client)2435 PanoramiXAllocColor(ClientPtr client)
2436 {
2437     int result, j;
2438     PanoramiXRes *cmap;
2439 
2440     REQUEST(xAllocColorReq);
2441 
2442     REQUEST_SIZE_MATCH(xAllocColorReq);
2443 
2444     client->errorValue = stuff->cmap;
2445 
2446     result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2447                                      XRT_COLORMAP, client, DixWriteAccess);
2448     if (result != Success)
2449         return result;
2450 
2451     FOR_NSCREENS_BACKWARD(j) {
2452         stuff->cmap = cmap->info[j].id;
2453         result = (*SavedProcVector[X_AllocColor]) (client);
2454         if (result != Success)
2455             break;
2456     }
2457     return result;
2458 }
2459 
2460 int
PanoramiXAllocNamedColor(ClientPtr client)2461 PanoramiXAllocNamedColor(ClientPtr client)
2462 {
2463     int result, j;
2464     PanoramiXRes *cmap;
2465 
2466     REQUEST(xAllocNamedColorReq);
2467 
2468     REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2469 
2470     client->errorValue = stuff->cmap;
2471 
2472     result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2473                                      XRT_COLORMAP, client, DixWriteAccess);
2474     if (result != Success)
2475         return result;
2476 
2477     FOR_NSCREENS_BACKWARD(j) {
2478         stuff->cmap = cmap->info[j].id;
2479         result = (*SavedProcVector[X_AllocNamedColor]) (client);
2480         if (result != Success)
2481             break;
2482     }
2483     return result;
2484 }
2485 
2486 int
PanoramiXAllocColorCells(ClientPtr client)2487 PanoramiXAllocColorCells(ClientPtr client)
2488 {
2489     int result, j;
2490     PanoramiXRes *cmap;
2491 
2492     REQUEST(xAllocColorCellsReq);
2493 
2494     REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2495 
2496     client->errorValue = stuff->cmap;
2497 
2498     result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2499                                      XRT_COLORMAP, client, DixWriteAccess);
2500     if (result != Success)
2501         return result;
2502 
2503     FOR_NSCREENS_BACKWARD(j) {
2504         stuff->cmap = cmap->info[j].id;
2505         result = (*SavedProcVector[X_AllocColorCells]) (client);
2506         if (result != Success)
2507             break;
2508     }
2509     return result;
2510 }
2511 
2512 int
PanoramiXAllocColorPlanes(ClientPtr client)2513 PanoramiXAllocColorPlanes(ClientPtr client)
2514 {
2515     int result, j;
2516     PanoramiXRes *cmap;
2517 
2518     REQUEST(xAllocColorPlanesReq);
2519 
2520     REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2521 
2522     client->errorValue = stuff->cmap;
2523 
2524     result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2525                                      XRT_COLORMAP, client, DixWriteAccess);
2526     if (result != Success)
2527         return result;
2528 
2529     FOR_NSCREENS_BACKWARD(j) {
2530         stuff->cmap = cmap->info[j].id;
2531         result = (*SavedProcVector[X_AllocColorPlanes]) (client);
2532         if (result != Success)
2533             break;
2534     }
2535     return result;
2536 }
2537 
2538 int
PanoramiXFreeColors(ClientPtr client)2539 PanoramiXFreeColors(ClientPtr client)
2540 {
2541     int result, j;
2542     PanoramiXRes *cmap;
2543 
2544     REQUEST(xFreeColorsReq);
2545 
2546     REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2547 
2548     client->errorValue = stuff->cmap;
2549 
2550     result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2551                                      XRT_COLORMAP, client, DixWriteAccess);
2552     if (result != Success)
2553         return result;
2554 
2555     FOR_NSCREENS_BACKWARD(j) {
2556         stuff->cmap = cmap->info[j].id;
2557         result = (*SavedProcVector[X_FreeColors]) (client);
2558     }
2559     return result;
2560 }
2561 
2562 int
PanoramiXStoreColors(ClientPtr client)2563 PanoramiXStoreColors(ClientPtr client)
2564 {
2565     int result, j;
2566     PanoramiXRes *cmap;
2567 
2568     REQUEST(xStoreColorsReq);
2569 
2570     REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2571 
2572     client->errorValue = stuff->cmap;
2573 
2574     result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2575                                      XRT_COLORMAP, client, DixWriteAccess);
2576     if (result != Success)
2577         return result;
2578 
2579     FOR_NSCREENS_BACKWARD(j) {
2580         stuff->cmap = cmap->info[j].id;
2581         result = (*SavedProcVector[X_StoreColors]) (client);
2582         if (result != Success)
2583             break;
2584     }
2585     return result;
2586 }
2587 
2588 int
PanoramiXStoreNamedColor(ClientPtr client)2589 PanoramiXStoreNamedColor(ClientPtr client)
2590 {
2591     int result, j;
2592     PanoramiXRes *cmap;
2593 
2594     REQUEST(xStoreNamedColorReq);
2595 
2596     REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2597 
2598     client->errorValue = stuff->cmap;
2599 
2600     result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2601                                      XRT_COLORMAP, client, DixWriteAccess);
2602     if (result != Success)
2603         return result;
2604 
2605     FOR_NSCREENS_BACKWARD(j) {
2606         stuff->cmap = cmap->info[j].id;
2607         result = (*SavedProcVector[X_StoreNamedColor]) (client);
2608         if (result != Success)
2609             break;
2610     }
2611     return result;
2612 }
2613