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