panoramiXprocs.c revision 35c4bbdf
1/*****************************************************************
2Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
3Permission is hereby granted, free of charge, to any person obtaining a copy
4of this software and associated documentation files (the "Software"), to deal
5in the Software without restriction, including without limitation the rights
6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7copies of the Software.
8
9The above copyright notice and this permission notice shall be included in
10all copies or substantial portions of the Software.
11
12THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
15DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
16BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
17WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
18IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20Except as contained in this notice, the name of Digital Equipment Corporation
21shall not be used in advertising or otherwise to promote the sale, use or other
22dealings in this Software without prior written authorization from Digital
23Equipment 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
54int
55PanoramiXCreateWindow(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
162int
163PanoramiXChangeWindowAttributes(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
236int
237PanoramiXDestroyWindow(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
264int
265PanoramiXDestroySubwindows(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
292int
293PanoramiXChangeSaveSet(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
317int
318PanoramiXReparentWindow(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
358int
359PanoramiXMapWindow(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
383int
384PanoramiXMapSubwindows(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
408int
409PanoramiXUnmapWindow(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
433int
434PanoramiXUnmapSubwindows(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
458int
459PanoramiXConfigureWindow(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
530int
531PanoramiXCirculateWindow(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
555int
556PanoramiXGetGeometry(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
607int
608PanoramiXTranslateCoords(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
679int
680PanoramiXCreatePixmap(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
718int
719PanoramiXFreePixmap(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
748int
749PanoramiXCreateGC(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
830int
831PanoramiXChangeGC(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
898int
899PanoramiXCopyGC(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
929int
930PanoramiXSetDashes(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
954int
955PanoramiXSetClipRectangles(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
979int
980PanoramiXFreeGC(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
1007int
1008PanoramiXClearToBackground(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
1050int
1051PanoramiXCopyArea(ClientPtr client)
1052{
1053    int j, result, srcx, srcy, dstx, dsty;
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    if ((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) {
1095        DrawablePtr drawables[MAXSCREENS];
1096        DrawablePtr pDst;
1097        GCPtr pGC;
1098        char *data;
1099        int pitch, rc;
1100
1101        FOR_NSCREENS(j) {
1102            rc = dixLookupDrawable(drawables + j, src->info[j].id, client, 0,
1103                                   DixGetAttrAccess);
1104            if (rc != Success)
1105                return rc;
1106        }
1107
1108        pitch = PixmapBytePad(stuff->width, drawables[0]->depth);
1109        if (!(data = calloc(stuff->height, pitch)))
1110            return BadAlloc;
1111
1112        XineramaGetImageData(drawables, srcx, srcy,
1113                             stuff->width, stuff->height, ZPixmap, ~0, data,
1114                             pitch, srcIsRoot);
1115
1116        FOR_NSCREENS_BACKWARD(j) {
1117            stuff->gc = gc->info[j].id;
1118            VALIDATE_DRAWABLE_AND_GC(dst->info[j].id, pDst, DixWriteAccess);
1119            if (drawables[0]->depth != pDst->depth) {
1120                client->errorValue = stuff->dstDrawable;
1121                free(data);
1122                return BadMatch;
1123            }
1124
1125            (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty,
1126                                   stuff->width, stuff->height,
1127                                   0, ZPixmap, data);
1128
1129            if (dstShared)
1130                break;
1131        }
1132
1133        free(data);
1134    }
1135    else {
1136        DrawablePtr pDst = NULL, pSrc = NULL;
1137        GCPtr pGC = NULL;
1138        RegionRec totalReg;
1139        int rc;
1140
1141        RegionNull(&totalReg);
1142        FOR_NSCREENS_BACKWARD(j) {
1143            RegionPtr pRgn;
1144
1145            stuff->dstDrawable = dst->info[j].id;
1146            stuff->srcDrawable = src->info[j].id;
1147            stuff->gc = gc->info[j].id;
1148            if (srcIsRoot) {
1149                stuff->srcX = srcx - screenInfo.screens[j]->x;
1150                stuff->srcY = srcy - screenInfo.screens[j]->y;
1151            }
1152            if (dstIsRoot) {
1153                stuff->dstX = dstx - screenInfo.screens[j]->x;
1154                stuff->dstY = dsty - screenInfo.screens[j]->y;
1155            }
1156
1157            VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
1158
1159            if (stuff->dstDrawable != stuff->srcDrawable) {
1160                rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
1161                                       DixReadAccess);
1162                if (rc != Success)
1163                    return rc;
1164
1165                if ((pDst->pScreen != pSrc->pScreen) ||
1166                    (pDst->depth != pSrc->depth)) {
1167                    client->errorValue = stuff->dstDrawable;
1168                    return BadMatch;
1169                }
1170            }
1171            else
1172                pSrc = pDst;
1173
1174            pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
1175                                          stuff->srcX, stuff->srcY,
1176                                          stuff->width, stuff->height,
1177                                          stuff->dstX, stuff->dstY);
1178            if (pGC->graphicsExposures && pRgn) {
1179                if (srcIsRoot) {
1180                    RegionTranslate(pRgn,
1181                                    screenInfo.screens[j]->x,
1182                                    screenInfo.screens[j]->y);
1183                }
1184                RegionAppend(&totalReg, pRgn);
1185                RegionDestroy(pRgn);
1186            }
1187
1188            if (dstShared)
1189                break;
1190        }
1191
1192        if (pGC->graphicsExposures) {
1193            Bool overlap;
1194
1195            RegionValidate(&totalReg, &overlap);
1196            SendGraphicsExpose(client, &totalReg, stuff->dstDrawable,
1197                               X_CopyArea, 0);
1198            RegionUninit(&totalReg);
1199        }
1200    }
1201
1202    return Success;
1203}
1204
1205int
1206PanoramiXCopyPlane(ClientPtr client)
1207{
1208    int j, srcx, srcy, dstx, dsty, rc;
1209    PanoramiXRes *gc, *src, *dst;
1210    Bool srcIsRoot = FALSE;
1211    Bool dstIsRoot = FALSE;
1212    Bool srcShared, dstShared;
1213    DrawablePtr psrcDraw, pdstDraw = NULL;
1214    GCPtr pGC = NULL;
1215    RegionRec totalReg;
1216
1217    REQUEST(xCopyPlaneReq);
1218
1219    REQUEST_SIZE_MATCH(xCopyPlaneReq);
1220
1221    rc = dixLookupResourceByClass((void **) &src, stuff->srcDrawable,
1222                                  XRC_DRAWABLE, client, DixReadAccess);
1223    if (rc != Success)
1224        return (rc == BadValue) ? BadDrawable : rc;
1225
1226    srcShared = IS_SHARED_PIXMAP(src);
1227
1228    rc = dixLookupResourceByClass((void **) &dst, stuff->dstDrawable,
1229                                  XRC_DRAWABLE, client, DixWriteAccess);
1230    if (rc != Success)
1231        return (rc == BadValue) ? BadDrawable : rc;
1232
1233    dstShared = IS_SHARED_PIXMAP(dst);
1234
1235    if (dstShared && srcShared)
1236        return (*SavedProcVector[X_CopyPlane]) (client);
1237
1238    rc = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1239                                 client, DixReadAccess);
1240    if (rc != Success)
1241        return rc;
1242
1243    if ((dst->type == XRT_WINDOW) && dst->u.win.root)
1244        dstIsRoot = TRUE;
1245    if ((src->type == XRT_WINDOW) && src->u.win.root)
1246        srcIsRoot = TRUE;
1247
1248    srcx = stuff->srcX;
1249    srcy = stuff->srcY;
1250    dstx = stuff->dstX;
1251    dsty = stuff->dstY;
1252
1253    RegionNull(&totalReg);
1254    FOR_NSCREENS_BACKWARD(j) {
1255        RegionPtr pRgn;
1256
1257        stuff->dstDrawable = dst->info[j].id;
1258        stuff->srcDrawable = src->info[j].id;
1259        stuff->gc = gc->info[j].id;
1260        if (srcIsRoot) {
1261            stuff->srcX = srcx - screenInfo.screens[j]->x;
1262            stuff->srcY = srcy - screenInfo.screens[j]->y;
1263        }
1264        if (dstIsRoot) {
1265            stuff->dstX = dstx - screenInfo.screens[j]->x;
1266            stuff->dstY = dsty - screenInfo.screens[j]->y;
1267        }
1268
1269        VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
1270        if (stuff->dstDrawable != stuff->srcDrawable) {
1271            rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
1272                                   DixReadAccess);
1273            if (rc != Success)
1274                return rc;
1275
1276            if (pdstDraw->pScreen != psrcDraw->pScreen) {
1277                client->errorValue = stuff->dstDrawable;
1278                return BadMatch;
1279            }
1280        }
1281        else
1282            psrcDraw = pdstDraw;
1283
1284        if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
1285            (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
1286            client->errorValue = stuff->bitPlane;
1287            return BadValue;
1288        }
1289
1290        pRgn = (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC,
1291                                       stuff->srcX, stuff->srcY,
1292                                       stuff->width, stuff->height,
1293                                       stuff->dstX, stuff->dstY,
1294                                       stuff->bitPlane);
1295        if (pGC->graphicsExposures && pRgn) {
1296            RegionAppend(&totalReg, pRgn);
1297            RegionDestroy(pRgn);
1298        }
1299
1300        if (dstShared)
1301            break;
1302    }
1303
1304    if (pGC->graphicsExposures) {
1305        Bool overlap;
1306
1307        RegionValidate(&totalReg, &overlap);
1308        SendGraphicsExpose(client, &totalReg, stuff->dstDrawable,
1309                           X_CopyPlane, 0);
1310        RegionUninit(&totalReg);
1311    }
1312
1313    return Success;
1314}
1315
1316int
1317PanoramiXPolyPoint(ClientPtr client)
1318{
1319    PanoramiXRes *gc, *draw;
1320    int result, npoint, j;
1321    xPoint *origPts;
1322    Bool isRoot;
1323
1324    REQUEST(xPolyPointReq);
1325
1326    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
1327
1328    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1329                                      XRC_DRAWABLE, client, DixWriteAccess);
1330    if (result != Success)
1331        return (result == BadValue) ? BadDrawable : result;
1332
1333    if (IS_SHARED_PIXMAP(draw))
1334        return (*SavedProcVector[X_PolyPoint]) (client);
1335
1336    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1337                                     client, DixReadAccess);
1338    if (result != Success)
1339        return result;
1340
1341    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1342    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
1343    if (npoint > 0) {
1344        origPts = xallocarray(npoint, sizeof(xPoint));
1345        memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
1346        FOR_NSCREENS_FORWARD(j) {
1347
1348            if (j)
1349                memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
1350
1351            if (isRoot) {
1352                int x_off = screenInfo.screens[j]->x;
1353                int y_off = screenInfo.screens[j]->y;
1354
1355                if (x_off || y_off) {
1356                    xPoint *pnts = (xPoint *) &stuff[1];
1357                    int i =
1358                        (stuff->coordMode == CoordModePrevious) ? 1 : npoint;
1359
1360                    while (i--) {
1361                        pnts->x -= x_off;
1362                        pnts->y -= y_off;
1363                        pnts++;
1364                    }
1365                }
1366            }
1367
1368            stuff->drawable = draw->info[j].id;
1369            stuff->gc = gc->info[j].id;
1370            result = (*SavedProcVector[X_PolyPoint]) (client);
1371            if (result != Success)
1372                break;
1373        }
1374        free(origPts);
1375        return result;
1376    }
1377    else
1378        return Success;
1379}
1380
1381int
1382PanoramiXPolyLine(ClientPtr client)
1383{
1384    PanoramiXRes *gc, *draw;
1385    int result, npoint, j;
1386    xPoint *origPts;
1387    Bool isRoot;
1388
1389    REQUEST(xPolyLineReq);
1390
1391    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
1392
1393    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1394                                      XRC_DRAWABLE, client, DixWriteAccess);
1395    if (result != Success)
1396        return (result == BadValue) ? BadDrawable : result;
1397
1398    if (IS_SHARED_PIXMAP(draw))
1399        return (*SavedProcVector[X_PolyLine]) (client);
1400
1401    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1402                                     client, DixReadAccess);
1403    if (result != Success)
1404        return result;
1405
1406    isRoot = IS_ROOT_DRAWABLE(draw);
1407    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
1408    if (npoint > 0) {
1409        origPts = xallocarray(npoint, sizeof(xPoint));
1410        memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
1411        FOR_NSCREENS_FORWARD(j) {
1412
1413            if (j)
1414                memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
1415
1416            if (isRoot) {
1417                int x_off = screenInfo.screens[j]->x;
1418                int y_off = screenInfo.screens[j]->y;
1419
1420                if (x_off || y_off) {
1421                    xPoint *pnts = (xPoint *) &stuff[1];
1422                    int i =
1423                        (stuff->coordMode == CoordModePrevious) ? 1 : npoint;
1424
1425                    while (i--) {
1426                        pnts->x -= x_off;
1427                        pnts->y -= y_off;
1428                        pnts++;
1429                    }
1430                }
1431            }
1432
1433            stuff->drawable = draw->info[j].id;
1434            stuff->gc = gc->info[j].id;
1435            result = (*SavedProcVector[X_PolyLine]) (client);
1436            if (result != Success)
1437                break;
1438        }
1439        free(origPts);
1440        return result;
1441    }
1442    else
1443        return Success;
1444}
1445
1446int
1447PanoramiXPolySegment(ClientPtr client)
1448{
1449    int result, nsegs, i, j;
1450    PanoramiXRes *gc, *draw;
1451    xSegment *origSegs;
1452    Bool isRoot;
1453
1454    REQUEST(xPolySegmentReq);
1455
1456    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
1457
1458    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1459                                      XRC_DRAWABLE, client, DixWriteAccess);
1460    if (result != Success)
1461        return (result == BadValue) ? BadDrawable : result;
1462
1463    if (IS_SHARED_PIXMAP(draw))
1464        return (*SavedProcVector[X_PolySegment]) (client);
1465
1466    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1467                                     client, DixReadAccess);
1468    if (result != Success)
1469        return result;
1470
1471    isRoot = IS_ROOT_DRAWABLE(draw);
1472
1473    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
1474    if (nsegs & 4)
1475        return BadLength;
1476    nsegs >>= 3;
1477    if (nsegs > 0) {
1478        origSegs = xallocarray(nsegs, sizeof(xSegment));
1479        memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment));
1480        FOR_NSCREENS_FORWARD(j) {
1481
1482            if (j)
1483                memcpy(&stuff[1], origSegs, nsegs * sizeof(xSegment));
1484
1485            if (isRoot) {
1486                int x_off = screenInfo.screens[j]->x;
1487                int y_off = screenInfo.screens[j]->y;
1488
1489                if (x_off || y_off) {
1490                    xSegment *segs = (xSegment *) &stuff[1];
1491
1492                    for (i = nsegs; i--; segs++) {
1493                        segs->x1 -= x_off;
1494                        segs->x2 -= x_off;
1495                        segs->y1 -= y_off;
1496                        segs->y2 -= y_off;
1497                    }
1498                }
1499            }
1500
1501            stuff->drawable = draw->info[j].id;
1502            stuff->gc = gc->info[j].id;
1503            result = (*SavedProcVector[X_PolySegment]) (client);
1504            if (result != Success)
1505                break;
1506        }
1507        free(origSegs);
1508        return result;
1509    }
1510    else
1511        return Success;
1512}
1513
1514int
1515PanoramiXPolyRectangle(ClientPtr client)
1516{
1517    int result, nrects, i, j;
1518    PanoramiXRes *gc, *draw;
1519    Bool isRoot;
1520    xRectangle *origRecs;
1521
1522    REQUEST(xPolyRectangleReq);
1523
1524    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
1525
1526    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1527                                      XRC_DRAWABLE, client, DixWriteAccess);
1528    if (result != Success)
1529        return (result == BadValue) ? BadDrawable : result;
1530
1531    if (IS_SHARED_PIXMAP(draw))
1532        return (*SavedProcVector[X_PolyRectangle]) (client);
1533
1534    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1535                                     client, DixReadAccess);
1536    if (result != Success)
1537        return result;
1538
1539    isRoot = IS_ROOT_DRAWABLE(draw);
1540
1541    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
1542    if (nrects & 4)
1543        return BadLength;
1544    nrects >>= 3;
1545    if (nrects > 0) {
1546        origRecs = xallocarray(nrects, sizeof(xRectangle));
1547        memcpy((char *) origRecs, (char *) &stuff[1],
1548               nrects * sizeof(xRectangle));
1549        FOR_NSCREENS_FORWARD(j) {
1550
1551            if (j)
1552                memcpy(&stuff[1], origRecs, nrects * sizeof(xRectangle));
1553
1554            if (isRoot) {
1555                int x_off = screenInfo.screens[j]->x;
1556                int y_off = screenInfo.screens[j]->y;
1557
1558                if (x_off || y_off) {
1559                    xRectangle *rects = (xRectangle *) &stuff[1];
1560
1561                    for (i = nrects; i--; rects++) {
1562                        rects->x -= x_off;
1563                        rects->y -= y_off;
1564                    }
1565                }
1566            }
1567
1568            stuff->drawable = draw->info[j].id;
1569            stuff->gc = gc->info[j].id;
1570            result = (*SavedProcVector[X_PolyRectangle]) (client);
1571            if (result != Success)
1572                break;
1573        }
1574        free(origRecs);
1575        return result;
1576    }
1577    else
1578        return Success;
1579}
1580
1581int
1582PanoramiXPolyArc(ClientPtr client)
1583{
1584    int result, narcs, i, j;
1585    PanoramiXRes *gc, *draw;
1586    Bool isRoot;
1587    xArc *origArcs;
1588
1589    REQUEST(xPolyArcReq);
1590
1591    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
1592
1593    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1594                                      XRC_DRAWABLE, client, DixWriteAccess);
1595    if (result != Success)
1596        return (result == BadValue) ? BadDrawable : result;
1597
1598    if (IS_SHARED_PIXMAP(draw))
1599        return (*SavedProcVector[X_PolyArc]) (client);
1600
1601    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1602                                     client, DixReadAccess);
1603    if (result != Success)
1604        return result;
1605
1606    isRoot = IS_ROOT_DRAWABLE(draw);
1607
1608    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
1609    if (narcs % sizeof(xArc))
1610        return BadLength;
1611    narcs /= sizeof(xArc);
1612    if (narcs > 0) {
1613        origArcs = xallocarray(narcs, sizeof(xArc));
1614        memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
1615        FOR_NSCREENS_FORWARD(j) {
1616
1617            if (j)
1618                memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
1619
1620            if (isRoot) {
1621                int x_off = screenInfo.screens[j]->x;
1622                int y_off = screenInfo.screens[j]->y;
1623
1624                if (x_off || y_off) {
1625                    xArc *arcs = (xArc *) &stuff[1];
1626
1627                    for (i = narcs; i--; arcs++) {
1628                        arcs->x -= x_off;
1629                        arcs->y -= y_off;
1630                    }
1631                }
1632            }
1633            stuff->drawable = draw->info[j].id;
1634            stuff->gc = gc->info[j].id;
1635            result = (*SavedProcVector[X_PolyArc]) (client);
1636            if (result != Success)
1637                break;
1638        }
1639        free(origArcs);
1640        return result;
1641    }
1642    else
1643        return Success;
1644}
1645
1646int
1647PanoramiXFillPoly(ClientPtr client)
1648{
1649    int result, count, j;
1650    PanoramiXRes *gc, *draw;
1651    Bool isRoot;
1652    DDXPointPtr locPts;
1653
1654    REQUEST(xFillPolyReq);
1655
1656    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
1657
1658    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1659                                      XRC_DRAWABLE, client, DixWriteAccess);
1660    if (result != Success)
1661        return (result == BadValue) ? BadDrawable : result;
1662
1663    if (IS_SHARED_PIXMAP(draw))
1664        return (*SavedProcVector[X_FillPoly]) (client);
1665
1666    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1667                                     client, DixReadAccess);
1668    if (result != Success)
1669        return result;
1670
1671    isRoot = IS_ROOT_DRAWABLE(draw);
1672
1673    count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
1674    if (count > 0) {
1675        locPts = xallocarray(count, sizeof(DDXPointRec));
1676        memcpy((char *) locPts, (char *) &stuff[1],
1677               count * sizeof(DDXPointRec));
1678        FOR_NSCREENS_FORWARD(j) {
1679
1680            if (j)
1681                memcpy(&stuff[1], locPts, count * sizeof(DDXPointRec));
1682
1683            if (isRoot) {
1684                int x_off = screenInfo.screens[j]->x;
1685                int y_off = screenInfo.screens[j]->y;
1686
1687                if (x_off || y_off) {
1688                    DDXPointPtr pnts = (DDXPointPtr) &stuff[1];
1689                    int i = (stuff->coordMode == CoordModePrevious) ? 1 : count;
1690
1691                    while (i--) {
1692                        pnts->x -= x_off;
1693                        pnts->y -= y_off;
1694                        pnts++;
1695                    }
1696                }
1697            }
1698
1699            stuff->drawable = draw->info[j].id;
1700            stuff->gc = gc->info[j].id;
1701            result = (*SavedProcVector[X_FillPoly]) (client);
1702            if (result != Success)
1703                break;
1704        }
1705        free(locPts);
1706        return result;
1707    }
1708    else
1709        return Success;
1710}
1711
1712int
1713PanoramiXPolyFillRectangle(ClientPtr client)
1714{
1715    int result, things, i, j;
1716    PanoramiXRes *gc, *draw;
1717    Bool isRoot;
1718    xRectangle *origRects;
1719
1720    REQUEST(xPolyFillRectangleReq);
1721
1722    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
1723
1724    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1725                                      XRC_DRAWABLE, client, DixWriteAccess);
1726    if (result != Success)
1727        return (result == BadValue) ? BadDrawable : result;
1728
1729    if (IS_SHARED_PIXMAP(draw))
1730        return (*SavedProcVector[X_PolyFillRectangle]) (client);
1731
1732    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1733                                     client, DixReadAccess);
1734    if (result != Success)
1735        return result;
1736
1737    isRoot = IS_ROOT_DRAWABLE(draw);
1738
1739    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
1740    if (things & 4)
1741        return BadLength;
1742    things >>= 3;
1743    if (things > 0) {
1744        origRects = xallocarray(things, sizeof(xRectangle));
1745        memcpy((char *) origRects, (char *) &stuff[1],
1746               things * sizeof(xRectangle));
1747        FOR_NSCREENS_FORWARD(j) {
1748
1749            if (j)
1750                memcpy(&stuff[1], origRects, things * sizeof(xRectangle));
1751
1752            if (isRoot) {
1753                int x_off = screenInfo.screens[j]->x;
1754                int y_off = screenInfo.screens[j]->y;
1755
1756                if (x_off || y_off) {
1757                    xRectangle *rects = (xRectangle *) &stuff[1];
1758
1759                    for (i = things; i--; rects++) {
1760                        rects->x -= x_off;
1761                        rects->y -= y_off;
1762                    }
1763                }
1764            }
1765
1766            stuff->drawable = draw->info[j].id;
1767            stuff->gc = gc->info[j].id;
1768            result = (*SavedProcVector[X_PolyFillRectangle]) (client);
1769            if (result != Success)
1770                break;
1771        }
1772        free(origRects);
1773        return result;
1774    }
1775    else
1776        return Success;
1777}
1778
1779int
1780PanoramiXPolyFillArc(ClientPtr client)
1781{
1782    PanoramiXRes *gc, *draw;
1783    Bool isRoot;
1784    int result, narcs, i, j;
1785    xArc *origArcs;
1786
1787    REQUEST(xPolyFillArcReq);
1788
1789    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
1790
1791    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1792                                      XRC_DRAWABLE, client, DixWriteAccess);
1793    if (result != Success)
1794        return (result == BadValue) ? BadDrawable : result;
1795
1796    if (IS_SHARED_PIXMAP(draw))
1797        return (*SavedProcVector[X_PolyFillArc]) (client);
1798
1799    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1800                                     client, DixReadAccess);
1801    if (result != Success)
1802        return result;
1803
1804    isRoot = IS_ROOT_DRAWABLE(draw);
1805
1806    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
1807    if (narcs % sizeof(xArc))
1808        return BadLength;
1809    narcs /= sizeof(xArc);
1810    if (narcs > 0) {
1811        origArcs = xallocarray(narcs, sizeof(xArc));
1812        memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
1813        FOR_NSCREENS_FORWARD(j) {
1814
1815            if (j)
1816                memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
1817
1818            if (isRoot) {
1819                int x_off = screenInfo.screens[j]->x;
1820                int y_off = screenInfo.screens[j]->y;
1821
1822                if (x_off || y_off) {
1823                    xArc *arcs = (xArc *) &stuff[1];
1824
1825                    for (i = narcs; i--; arcs++) {
1826                        arcs->x -= x_off;
1827                        arcs->y -= y_off;
1828                    }
1829                }
1830            }
1831
1832            stuff->drawable = draw->info[j].id;
1833            stuff->gc = gc->info[j].id;
1834            result = (*SavedProcVector[X_PolyFillArc]) (client);
1835            if (result != Success)
1836                break;
1837        }
1838        free(origArcs);
1839        return result;
1840    }
1841    else
1842        return Success;
1843}
1844
1845int
1846PanoramiXPutImage(ClientPtr client)
1847{
1848    PanoramiXRes *gc, *draw;
1849    Bool isRoot;
1850    int j, result, orig_x, orig_y;
1851
1852    REQUEST(xPutImageReq);
1853
1854    REQUEST_AT_LEAST_SIZE(xPutImageReq);
1855
1856    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1857                                      XRC_DRAWABLE, client, DixWriteAccess);
1858    if (result != Success)
1859        return (result == BadValue) ? BadDrawable : result;
1860
1861    if (IS_SHARED_PIXMAP(draw))
1862        return (*SavedProcVector[X_PutImage]) (client);
1863
1864    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
1865                                     client, DixReadAccess);
1866    if (result != Success)
1867        return result;
1868
1869    isRoot = IS_ROOT_DRAWABLE(draw);
1870
1871    orig_x = stuff->dstX;
1872    orig_y = stuff->dstY;
1873    FOR_NSCREENS_BACKWARD(j) {
1874        if (isRoot) {
1875            stuff->dstX = orig_x - screenInfo.screens[j]->x;
1876            stuff->dstY = orig_y - screenInfo.screens[j]->y;
1877        }
1878        stuff->drawable = draw->info[j].id;
1879        stuff->gc = gc->info[j].id;
1880        result = (*SavedProcVector[X_PutImage]) (client);
1881        if (result != Success)
1882            break;
1883    }
1884    return result;
1885}
1886
1887int
1888PanoramiXGetImage(ClientPtr client)
1889{
1890    DrawablePtr drawables[MAXSCREENS];
1891    DrawablePtr pDraw;
1892    PanoramiXRes *draw;
1893    xGetImageReply xgi;
1894    Bool isRoot;
1895    char *pBuf;
1896    int i, x, y, w, h, format, rc;
1897    Mask plane = 0, planemask;
1898    int linesDone, nlines, linesPerBuf;
1899    long widthBytesLine, length;
1900
1901    REQUEST(xGetImageReq);
1902
1903    REQUEST_SIZE_MATCH(xGetImageReq);
1904
1905    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
1906        client->errorValue = stuff->format;
1907        return BadValue;
1908    }
1909
1910    rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1911                                  XRC_DRAWABLE, client, DixReadAccess);
1912    if (rc != Success)
1913        return (rc == BadValue) ? BadDrawable : rc;
1914
1915    if (draw->type == XRT_PIXMAP)
1916        return (*SavedProcVector[X_GetImage]) (client);
1917
1918    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess);
1919    if (rc != Success)
1920        return rc;
1921
1922    if (!((WindowPtr) pDraw)->realized)
1923        return BadMatch;
1924
1925    x = stuff->x;
1926    y = stuff->y;
1927    w = stuff->width;
1928    h = stuff->height;
1929    format = stuff->format;
1930    planemask = stuff->planeMask;
1931
1932    isRoot = IS_ROOT_DRAWABLE(draw);
1933
1934    if (isRoot) {
1935        /* check for being onscreen */
1936        if (x < 0 || x + w > PanoramiXPixWidth ||
1937            y < 0 || y + h > PanoramiXPixHeight)
1938            return BadMatch;
1939    }
1940    else {
1941        /* check for being onscreen and inside of border */
1942        if (screenInfo.screens[0]->x + pDraw->x + x < 0 ||
1943            screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth ||
1944            screenInfo.screens[0]->y + pDraw->y + y < 0 ||
1945            screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight ||
1946            x < -wBorderWidth((WindowPtr) pDraw) ||
1947            x + w > wBorderWidth((WindowPtr) pDraw) + (int) pDraw->width ||
1948            y < -wBorderWidth((WindowPtr) pDraw) ||
1949            y + h > wBorderWidth((WindowPtr) pDraw) + (int) pDraw->height)
1950            return BadMatch;
1951    }
1952
1953    drawables[0] = pDraw;
1954    FOR_NSCREENS_FORWARD_SKIP(i) {
1955        rc = dixLookupDrawable(drawables + i, draw->info[i].id, client, 0,
1956                               DixGetAttrAccess);
1957        if (rc != Success)
1958            return rc;
1959    }
1960
1961    xgi = (xGetImageReply) {
1962        .type = X_Reply,
1963        .sequenceNumber = client->sequence,
1964        .visual = wVisual(((WindowPtr) pDraw)),
1965        .depth = pDraw->depth
1966    };
1967    if (format == ZPixmap) {
1968        widthBytesLine = PixmapBytePad(w, pDraw->depth);
1969        length = widthBytesLine * h;
1970
1971    }
1972    else {
1973        widthBytesLine = BitmapBytePad(w);
1974        plane = ((Mask) 1) << (pDraw->depth - 1);
1975        /* only planes asked for */
1976        length = widthBytesLine * h * Ones(planemask & (plane | (plane - 1)));
1977
1978    }
1979
1980    xgi.length = bytes_to_int32(length);
1981
1982    if (widthBytesLine == 0 || h == 0)
1983        linesPerBuf = 0;
1984    else if (widthBytesLine >= XINERAMA_IMAGE_BUFSIZE)
1985        linesPerBuf = 1;
1986    else {
1987        linesPerBuf = XINERAMA_IMAGE_BUFSIZE / widthBytesLine;
1988        if (linesPerBuf > h)
1989            linesPerBuf = h;
1990    }
1991    if (!(pBuf = xallocarray(linesPerBuf, widthBytesLine)))
1992        return BadAlloc;
1993
1994    WriteReplyToClient(client, sizeof(xGetImageReply), &xgi);
1995
1996    if (linesPerBuf == 0) {
1997        /* nothing to do */
1998    }
1999    else if (format == ZPixmap) {
2000        linesDone = 0;
2001        while (h - linesDone > 0) {
2002            nlines = min(linesPerBuf, h - linesDone);
2003
2004            if (pDraw->depth == 1)
2005                memset(pBuf, 0, nlines * widthBytesLine);
2006
2007            XineramaGetImageData(drawables, x, y + linesDone, w, nlines,
2008                                 format, planemask, pBuf, widthBytesLine,
2009                                 isRoot);
2010
2011            WriteToClient(client, (int) (nlines * widthBytesLine), pBuf);
2012            linesDone += nlines;
2013        }
2014    }
2015    else {                      /* XYPixmap */
2016        for (; plane; plane >>= 1) {
2017            if (planemask & plane) {
2018                linesDone = 0;
2019                while (h - linesDone > 0) {
2020                    nlines = min(linesPerBuf, h - linesDone);
2021
2022                    memset(pBuf, 0, nlines * widthBytesLine);
2023
2024                    XineramaGetImageData(drawables, x, y + linesDone, w,
2025                                         nlines, format, plane, pBuf,
2026                                         widthBytesLine, isRoot);
2027
2028                    WriteToClient(client, (int)(nlines * widthBytesLine), pBuf);
2029
2030                    linesDone += nlines;
2031                }
2032            }
2033        }
2034    }
2035    free(pBuf);
2036    return Success;
2037}
2038
2039/* The text stuff should be rewritten so that duplication happens
2040   at the GlyphBlt level.  That is, loading the font and getting
2041   the glyphs should only happen once */
2042
2043int
2044PanoramiXPolyText8(ClientPtr client)
2045{
2046    PanoramiXRes *gc, *draw;
2047    Bool isRoot;
2048    int result, j;
2049    int orig_x, orig_y;
2050
2051    REQUEST(xPolyTextReq);
2052
2053    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2054
2055    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
2056                                      XRC_DRAWABLE, client, DixWriteAccess);
2057    if (result != Success)
2058        return (result == BadValue) ? BadDrawable : result;
2059
2060    if (IS_SHARED_PIXMAP(draw))
2061        return (*SavedProcVector[X_PolyText8]) (client);
2062
2063    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
2064                                     client, DixReadAccess);
2065    if (result != Success)
2066        return result;
2067
2068    isRoot = IS_ROOT_DRAWABLE(draw);
2069
2070    orig_x = stuff->x;
2071    orig_y = stuff->y;
2072    FOR_NSCREENS_BACKWARD(j) {
2073        stuff->drawable = draw->info[j].id;
2074        stuff->gc = gc->info[j].id;
2075        if (isRoot) {
2076            stuff->x = orig_x - screenInfo.screens[j]->x;
2077            stuff->y = orig_y - screenInfo.screens[j]->y;
2078        }
2079        result = (*SavedProcVector[X_PolyText8]) (client);
2080        if (result != Success)
2081            break;
2082    }
2083    return result;
2084}
2085
2086int
2087PanoramiXPolyText16(ClientPtr client)
2088{
2089    PanoramiXRes *gc, *draw;
2090    Bool isRoot;
2091    int result, j;
2092    int orig_x, orig_y;
2093
2094    REQUEST(xPolyTextReq);
2095
2096    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2097
2098    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
2099                                      XRC_DRAWABLE, client, DixWriteAccess);
2100    if (result != Success)
2101        return (result == BadValue) ? BadDrawable : result;
2102
2103    if (IS_SHARED_PIXMAP(draw))
2104        return (*SavedProcVector[X_PolyText16]) (client);
2105
2106    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
2107                                     client, DixReadAccess);
2108    if (result != Success)
2109        return result;
2110
2111    isRoot = IS_ROOT_DRAWABLE(draw);
2112
2113    orig_x = stuff->x;
2114    orig_y = stuff->y;
2115    FOR_NSCREENS_BACKWARD(j) {
2116        stuff->drawable = draw->info[j].id;
2117        stuff->gc = gc->info[j].id;
2118        if (isRoot) {
2119            stuff->x = orig_x - screenInfo.screens[j]->x;
2120            stuff->y = orig_y - screenInfo.screens[j]->y;
2121        }
2122        result = (*SavedProcVector[X_PolyText16]) (client);
2123        if (result != Success)
2124            break;
2125    }
2126    return result;
2127}
2128
2129int
2130PanoramiXImageText8(ClientPtr client)
2131{
2132    int result, j;
2133    PanoramiXRes *gc, *draw;
2134    Bool isRoot;
2135    int orig_x, orig_y;
2136
2137    REQUEST(xImageTextReq);
2138
2139    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
2140
2141    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
2142                                      XRC_DRAWABLE, client, DixWriteAccess);
2143    if (result != Success)
2144        return (result == BadValue) ? BadDrawable : result;
2145
2146    if (IS_SHARED_PIXMAP(draw))
2147        return (*SavedProcVector[X_ImageText8]) (client);
2148
2149    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
2150                                     client, DixReadAccess);
2151    if (result != Success)
2152        return result;
2153
2154    isRoot = IS_ROOT_DRAWABLE(draw);
2155
2156    orig_x = stuff->x;
2157    orig_y = stuff->y;
2158    FOR_NSCREENS_BACKWARD(j) {
2159        stuff->drawable = draw->info[j].id;
2160        stuff->gc = gc->info[j].id;
2161        if (isRoot) {
2162            stuff->x = orig_x - screenInfo.screens[j]->x;
2163            stuff->y = orig_y - screenInfo.screens[j]->y;
2164        }
2165        result = (*SavedProcVector[X_ImageText8]) (client);
2166        if (result != Success)
2167            break;
2168    }
2169    return result;
2170}
2171
2172int
2173PanoramiXImageText16(ClientPtr client)
2174{
2175    int result, j;
2176    PanoramiXRes *gc, *draw;
2177    Bool isRoot;
2178    int orig_x, orig_y;
2179
2180    REQUEST(xImageTextReq);
2181
2182    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
2183
2184    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
2185                                      XRC_DRAWABLE, client, DixWriteAccess);
2186    if (result != Success)
2187        return (result == BadValue) ? BadDrawable : result;
2188
2189    if (IS_SHARED_PIXMAP(draw))
2190        return (*SavedProcVector[X_ImageText16]) (client);
2191
2192    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
2193                                     client, DixReadAccess);
2194    if (result != Success)
2195        return result;
2196
2197    isRoot = IS_ROOT_DRAWABLE(draw);
2198
2199    orig_x = stuff->x;
2200    orig_y = stuff->y;
2201    FOR_NSCREENS_BACKWARD(j) {
2202        stuff->drawable = draw->info[j].id;
2203        stuff->gc = gc->info[j].id;
2204        if (isRoot) {
2205            stuff->x = orig_x - screenInfo.screens[j]->x;
2206            stuff->y = orig_y - screenInfo.screens[j]->y;
2207        }
2208        result = (*SavedProcVector[X_ImageText16]) (client);
2209        if (result != Success)
2210            break;
2211    }
2212    return result;
2213}
2214
2215int
2216PanoramiXCreateColormap(ClientPtr client)
2217{
2218    PanoramiXRes *win, *newCmap;
2219    int result, j, orig_visual;
2220
2221    REQUEST(xCreateColormapReq);
2222
2223    REQUEST_SIZE_MATCH(xCreateColormapReq);
2224
2225    result = dixLookupResourceByType((void **) &win, stuff->window,
2226                                     XRT_WINDOW, client, DixReadAccess);
2227    if (result != Success)
2228        return result;
2229
2230    if (!(newCmap = malloc(sizeof(PanoramiXRes))))
2231        return BadAlloc;
2232
2233    newCmap->type = XRT_COLORMAP;
2234    panoramix_setup_ids(newCmap, client, stuff->mid);
2235
2236    orig_visual = stuff->visual;
2237    FOR_NSCREENS_BACKWARD(j) {
2238        stuff->mid = newCmap->info[j].id;
2239        stuff->window = win->info[j].id;
2240        stuff->visual = PanoramiXTranslateVisualID(j, orig_visual);
2241        result = (*SavedProcVector[X_CreateColormap]) (client);
2242        if (result != Success)
2243            break;
2244    }
2245
2246    if (result == Success)
2247        AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
2248    else
2249        free(newCmap);
2250
2251    return result;
2252}
2253
2254int
2255PanoramiXFreeColormap(ClientPtr client)
2256{
2257    PanoramiXRes *cmap;
2258    int result, j;
2259
2260    REQUEST(xResourceReq);
2261
2262    REQUEST_SIZE_MATCH(xResourceReq);
2263
2264    client->errorValue = stuff->id;
2265
2266    result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
2267                                     client, DixDestroyAccess);
2268    if (result != Success)
2269        return result;
2270
2271    FOR_NSCREENS_BACKWARD(j) {
2272        stuff->id = cmap->info[j].id;
2273        result = (*SavedProcVector[X_FreeColormap]) (client);
2274        if (result != Success)
2275            break;
2276    }
2277
2278    /* Since ProcFreeColormap is using FreeResource, it will free
2279       our resource for us on the last pass through the loop above */
2280
2281    return result;
2282}
2283
2284int
2285PanoramiXCopyColormapAndFree(ClientPtr client)
2286{
2287    PanoramiXRes *cmap, *newCmap;
2288    int result, j;
2289
2290    REQUEST(xCopyColormapAndFreeReq);
2291
2292    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
2293
2294    client->errorValue = stuff->srcCmap;
2295
2296    result = dixLookupResourceByType((void **) &cmap, stuff->srcCmap,
2297                                     XRT_COLORMAP, client,
2298                                     DixReadAccess | DixWriteAccess);
2299    if (result != Success)
2300        return result;
2301
2302    if (!(newCmap = malloc(sizeof(PanoramiXRes))))
2303        return BadAlloc;
2304
2305    newCmap->type = XRT_COLORMAP;
2306    panoramix_setup_ids(newCmap, client, stuff->mid);
2307
2308    FOR_NSCREENS_BACKWARD(j) {
2309        stuff->srcCmap = cmap->info[j].id;
2310        stuff->mid = newCmap->info[j].id;
2311        result = (*SavedProcVector[X_CopyColormapAndFree]) (client);
2312        if (result != Success)
2313            break;
2314    }
2315
2316    if (result == Success)
2317        AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
2318    else
2319        free(newCmap);
2320
2321    return result;
2322}
2323
2324int
2325PanoramiXInstallColormap(ClientPtr client)
2326{
2327    REQUEST(xResourceReq);
2328    int result, j;
2329    PanoramiXRes *cmap;
2330
2331    REQUEST_SIZE_MATCH(xResourceReq);
2332
2333    client->errorValue = stuff->id;
2334
2335    result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
2336                                     client, DixReadAccess);
2337    if (result != Success)
2338        return result;
2339
2340    FOR_NSCREENS_BACKWARD(j) {
2341        stuff->id = cmap->info[j].id;
2342        result = (*SavedProcVector[X_InstallColormap]) (client);
2343        if (result != Success)
2344            break;
2345    }
2346    return result;
2347}
2348
2349int
2350PanoramiXUninstallColormap(ClientPtr client)
2351{
2352    REQUEST(xResourceReq);
2353    int result, j;
2354    PanoramiXRes *cmap;
2355
2356    REQUEST_SIZE_MATCH(xResourceReq);
2357
2358    client->errorValue = stuff->id;
2359
2360    result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
2361                                     client, DixReadAccess);
2362    if (result != Success)
2363        return result;
2364
2365    FOR_NSCREENS_BACKWARD(j) {
2366        stuff->id = cmap->info[j].id;
2367        result = (*SavedProcVector[X_UninstallColormap]) (client);
2368        if (result != Success)
2369            break;
2370    }
2371    return result;
2372}
2373
2374int
2375PanoramiXAllocColor(ClientPtr client)
2376{
2377    int result, j;
2378    PanoramiXRes *cmap;
2379
2380    REQUEST(xAllocColorReq);
2381
2382    REQUEST_SIZE_MATCH(xAllocColorReq);
2383
2384    client->errorValue = stuff->cmap;
2385
2386    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2387                                     XRT_COLORMAP, client, DixWriteAccess);
2388    if (result != Success)
2389        return result;
2390
2391    FOR_NSCREENS_BACKWARD(j) {
2392        stuff->cmap = cmap->info[j].id;
2393        result = (*SavedProcVector[X_AllocColor]) (client);
2394        if (result != Success)
2395            break;
2396    }
2397    return result;
2398}
2399
2400int
2401PanoramiXAllocNamedColor(ClientPtr client)
2402{
2403    int result, j;
2404    PanoramiXRes *cmap;
2405
2406    REQUEST(xAllocNamedColorReq);
2407
2408    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2409
2410    client->errorValue = stuff->cmap;
2411
2412    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2413                                     XRT_COLORMAP, client, DixWriteAccess);
2414    if (result != Success)
2415        return result;
2416
2417    FOR_NSCREENS_BACKWARD(j) {
2418        stuff->cmap = cmap->info[j].id;
2419        result = (*SavedProcVector[X_AllocNamedColor]) (client);
2420        if (result != Success)
2421            break;
2422    }
2423    return result;
2424}
2425
2426int
2427PanoramiXAllocColorCells(ClientPtr client)
2428{
2429    int result, j;
2430    PanoramiXRes *cmap;
2431
2432    REQUEST(xAllocColorCellsReq);
2433
2434    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2435
2436    client->errorValue = stuff->cmap;
2437
2438    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2439                                     XRT_COLORMAP, client, DixWriteAccess);
2440    if (result != Success)
2441        return result;
2442
2443    FOR_NSCREENS_BACKWARD(j) {
2444        stuff->cmap = cmap->info[j].id;
2445        result = (*SavedProcVector[X_AllocColorCells]) (client);
2446        if (result != Success)
2447            break;
2448    }
2449    return result;
2450}
2451
2452int
2453PanoramiXAllocColorPlanes(ClientPtr client)
2454{
2455    int result, j;
2456    PanoramiXRes *cmap;
2457
2458    REQUEST(xAllocColorPlanesReq);
2459
2460    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2461
2462    client->errorValue = stuff->cmap;
2463
2464    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2465                                     XRT_COLORMAP, client, DixWriteAccess);
2466    if (result != Success)
2467        return result;
2468
2469    FOR_NSCREENS_BACKWARD(j) {
2470        stuff->cmap = cmap->info[j].id;
2471        result = (*SavedProcVector[X_AllocColorPlanes]) (client);
2472        if (result != Success)
2473            break;
2474    }
2475    return result;
2476}
2477
2478int
2479PanoramiXFreeColors(ClientPtr client)
2480{
2481    int result, j;
2482    PanoramiXRes *cmap;
2483
2484    REQUEST(xFreeColorsReq);
2485
2486    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2487
2488    client->errorValue = stuff->cmap;
2489
2490    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2491                                     XRT_COLORMAP, client, DixWriteAccess);
2492    if (result != Success)
2493        return result;
2494
2495    FOR_NSCREENS_BACKWARD(j) {
2496        stuff->cmap = cmap->info[j].id;
2497        result = (*SavedProcVector[X_FreeColors]) (client);
2498    }
2499    return result;
2500}
2501
2502int
2503PanoramiXStoreColors(ClientPtr client)
2504{
2505    int result, j;
2506    PanoramiXRes *cmap;
2507
2508    REQUEST(xStoreColorsReq);
2509
2510    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2511
2512    client->errorValue = stuff->cmap;
2513
2514    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2515                                     XRT_COLORMAP, client, DixWriteAccess);
2516    if (result != Success)
2517        return result;
2518
2519    FOR_NSCREENS_BACKWARD(j) {
2520        stuff->cmap = cmap->info[j].id;
2521        result = (*SavedProcVector[X_StoreColors]) (client);
2522        if (result != Success)
2523            break;
2524    }
2525    return result;
2526}
2527
2528int
2529PanoramiXStoreNamedColor(ClientPtr client)
2530{
2531    int result, j;
2532    PanoramiXRes *cmap;
2533
2534    REQUEST(xStoreNamedColorReq);
2535
2536    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2537
2538    client->errorValue = stuff->cmap;
2539
2540    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
2541                                     XRT_COLORMAP, client, DixWriteAccess);
2542    if (result != Success)
2543        return result;
2544
2545    FOR_NSCREENS_BACKWARD(j) {
2546        stuff->cmap = cmap->info[j].id;
2547        result = (*SavedProcVector[X_StoreNamedColor]) (client);
2548        if (result != Success)
2549            break;
2550    }
2551    return result;
2552}
2553