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