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