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