1 /*
2 * Copyright © 2003 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23 #ifdef HAVE_DIX_CONFIG_H
24 #include <dix-config.h>
25 #endif
26
27 #include "xfixesint.h"
28 #include "scrnintstr.h"
29 #include <picturestr.h>
30
31 #include <regionstr.h>
32 #include <gcstruct.h>
33 #include <window.h>
34
35 RESTYPE RegionResType;
36
37 static int
RegionResFree(void * data,XID id)38 RegionResFree(void *data, XID id)
39 {
40 RegionPtr pRegion = (RegionPtr) data;
41
42 RegionDestroy(pRegion);
43 return Success;
44 }
45
46 RegionPtr
XFixesRegionCopy(RegionPtr pRegion)47 XFixesRegionCopy(RegionPtr pRegion)
48 {
49 RegionPtr pNew = RegionCreate(RegionExtents(pRegion),
50 RegionNumRects(pRegion));
51
52 if (!pNew)
53 return 0;
54 if (!RegionCopy(pNew, pRegion)) {
55 RegionDestroy(pNew);
56 return 0;
57 }
58 return pNew;
59 }
60
61 Bool
XFixesRegionInit(void)62 XFixesRegionInit(void)
63 {
64 RegionResType = CreateNewResourceType(RegionResFree, "XFixesRegion");
65
66 return RegionResType != 0;
67 }
68
69 int
ProcXFixesCreateRegion(ClientPtr client)70 ProcXFixesCreateRegion(ClientPtr client)
71 {
72 int things;
73 RegionPtr pRegion;
74
75 REQUEST(xXFixesCreateRegionReq);
76
77 REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq);
78 LEGAL_NEW_RESOURCE(stuff->region, client);
79
80 things = (client->req_len << 2) - sizeof(xXFixesCreateRegionReq);
81 if (things & 4)
82 return BadLength;
83 things >>= 3;
84
85 pRegion = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED);
86 if (!pRegion)
87 return BadAlloc;
88 if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
89 return BadAlloc;
90
91 return Success;
92 }
93
94 int _X_COLD
SProcXFixesCreateRegion(ClientPtr client)95 SProcXFixesCreateRegion(ClientPtr client)
96 {
97 REQUEST(xXFixesCreateRegionReq);
98
99 swaps(&stuff->length);
100 REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq);
101 swapl(&stuff->region);
102 SwapRestS(stuff);
103 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
104 }
105
106 int
ProcXFixesCreateRegionFromBitmap(ClientPtr client)107 ProcXFixesCreateRegionFromBitmap(ClientPtr client)
108 {
109 RegionPtr pRegion;
110 PixmapPtr pPixmap;
111 int rc;
112
113 REQUEST(xXFixesCreateRegionFromBitmapReq);
114
115 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromBitmapReq);
116 LEGAL_NEW_RESOURCE(stuff->region, client);
117
118 rc = dixLookupResourceByType((void **) &pPixmap, stuff->bitmap, RT_PIXMAP,
119 client, DixReadAccess);
120 if (rc != Success) {
121 client->errorValue = stuff->bitmap;
122 return rc;
123 }
124 if (pPixmap->drawable.depth != 1)
125 return BadMatch;
126
127 pRegion = BitmapToRegion(pPixmap->drawable.pScreen, pPixmap);
128
129 if (!pRegion)
130 return BadAlloc;
131
132 if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
133 return BadAlloc;
134
135 return Success;
136 }
137
138 int _X_COLD
SProcXFixesCreateRegionFromBitmap(ClientPtr client)139 SProcXFixesCreateRegionFromBitmap(ClientPtr client)
140 {
141 REQUEST(xXFixesCreateRegionFromBitmapReq);
142
143 swaps(&stuff->length);
144 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromBitmapReq);
145 swapl(&stuff->region);
146 swapl(&stuff->bitmap);
147 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
148 }
149
150 int
ProcXFixesCreateRegionFromWindow(ClientPtr client)151 ProcXFixesCreateRegionFromWindow(ClientPtr client)
152 {
153 RegionPtr pRegion;
154 Bool copy = TRUE;
155 WindowPtr pWin;
156 int rc;
157
158 REQUEST(xXFixesCreateRegionFromWindowReq);
159
160 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromWindowReq);
161 LEGAL_NEW_RESOURCE(stuff->region, client);
162 rc = dixLookupResourceByType((void **) &pWin, stuff->window, RT_WINDOW,
163 client, DixGetAttrAccess);
164 if (rc != Success) {
165 client->errorValue = stuff->window;
166 return rc;
167 }
168 switch (stuff->kind) {
169 case WindowRegionBounding:
170 pRegion = wBoundingShape(pWin);
171 if (!pRegion) {
172 pRegion = CreateBoundingShape(pWin);
173 copy = FALSE;
174 }
175 break;
176 case WindowRegionClip:
177 pRegion = wClipShape(pWin);
178 if (!pRegion) {
179 pRegion = CreateClipShape(pWin);
180 copy = FALSE;
181 }
182 break;
183 default:
184 client->errorValue = stuff->kind;
185 return BadValue;
186 }
187 if (copy && pRegion)
188 pRegion = XFixesRegionCopy(pRegion);
189 if (!pRegion)
190 return BadAlloc;
191 if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
192 return BadAlloc;
193
194 return Success;
195 }
196
197 int _X_COLD
SProcXFixesCreateRegionFromWindow(ClientPtr client)198 SProcXFixesCreateRegionFromWindow(ClientPtr client)
199 {
200 REQUEST(xXFixesCreateRegionFromWindowReq);
201
202 swaps(&stuff->length);
203 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromWindowReq);
204 swapl(&stuff->region);
205 swapl(&stuff->window);
206 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
207 }
208
209 int
ProcXFixesCreateRegionFromGC(ClientPtr client)210 ProcXFixesCreateRegionFromGC(ClientPtr client)
211 {
212 RegionPtr pRegion, pClip;
213 GCPtr pGC;
214 int rc;
215
216 REQUEST(xXFixesCreateRegionFromGCReq);
217
218 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromGCReq);
219 LEGAL_NEW_RESOURCE(stuff->region, client);
220
221 rc = dixLookupGC(&pGC, stuff->gc, client, DixGetAttrAccess);
222 if (rc != Success)
223 return rc;
224
225 if (pGC->clientClip) {
226 pClip = (RegionPtr) pGC->clientClip;
227 pRegion = XFixesRegionCopy(pClip);
228 if (!pRegion)
229 return BadAlloc;
230 } else {
231 return BadMatch;
232 }
233
234 if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
235 return BadAlloc;
236
237 return Success;
238 }
239
240 int _X_COLD
SProcXFixesCreateRegionFromGC(ClientPtr client)241 SProcXFixesCreateRegionFromGC(ClientPtr client)
242 {
243 REQUEST(xXFixesCreateRegionFromGCReq);
244
245 swaps(&stuff->length);
246 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromGCReq);
247 swapl(&stuff->region);
248 swapl(&stuff->gc);
249 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
250 }
251
252 int
ProcXFixesCreateRegionFromPicture(ClientPtr client)253 ProcXFixesCreateRegionFromPicture(ClientPtr client)
254 {
255 RegionPtr pRegion;
256 PicturePtr pPicture;
257
258 REQUEST(xXFixesCreateRegionFromPictureReq);
259
260 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromPictureReq);
261 LEGAL_NEW_RESOURCE(stuff->region, client);
262
263 VERIFY_PICTURE(pPicture, stuff->picture, client, DixGetAttrAccess);
264
265 if (!pPicture->pDrawable)
266 return RenderErrBase + BadPicture;
267
268 if (pPicture->clientClip) {
269 pRegion = XFixesRegionCopy((RegionPtr) pPicture->clientClip);
270 if (!pRegion)
271 return BadAlloc;
272 } else {
273 return BadMatch;
274 }
275
276 if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
277 return BadAlloc;
278
279 return Success;
280 }
281
282 int _X_COLD
SProcXFixesCreateRegionFromPicture(ClientPtr client)283 SProcXFixesCreateRegionFromPicture(ClientPtr client)
284 {
285 REQUEST(xXFixesCreateRegionFromPictureReq);
286
287 swaps(&stuff->length);
288 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromPictureReq);
289 swapl(&stuff->region);
290 swapl(&stuff->picture);
291 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
292 }
293
294 int
ProcXFixesDestroyRegion(ClientPtr client)295 ProcXFixesDestroyRegion(ClientPtr client)
296 {
297 REQUEST(xXFixesDestroyRegionReq);
298 RegionPtr pRegion;
299
300 REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq);
301 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
302 FreeResource(stuff->region, RT_NONE);
303 return Success;
304 }
305
306 int _X_COLD
SProcXFixesDestroyRegion(ClientPtr client)307 SProcXFixesDestroyRegion(ClientPtr client)
308 {
309 REQUEST(xXFixesDestroyRegionReq);
310
311 swaps(&stuff->length);
312 REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq);
313 swapl(&stuff->region);
314 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
315 }
316
317 int
ProcXFixesSetRegion(ClientPtr client)318 ProcXFixesSetRegion(ClientPtr client)
319 {
320 int things;
321 RegionPtr pRegion, pNew;
322
323 REQUEST(xXFixesSetRegionReq);
324
325 REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
326 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
327
328 things = (client->req_len << 2) - sizeof(xXFixesCreateRegionReq);
329 if (things & 4)
330 return BadLength;
331 things >>= 3;
332
333 pNew = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED);
334 if (!pNew)
335 return BadAlloc;
336 if (!RegionCopy(pRegion, pNew)) {
337 RegionDestroy(pNew);
338 return BadAlloc;
339 }
340 RegionDestroy(pNew);
341 return Success;
342 }
343
344 int _X_COLD
SProcXFixesSetRegion(ClientPtr client)345 SProcXFixesSetRegion(ClientPtr client)
346 {
347 REQUEST(xXFixesSetRegionReq);
348
349 swaps(&stuff->length);
350 REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
351 swapl(&stuff->region);
352 SwapRestS(stuff);
353 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
354 }
355
356 int
ProcXFixesCopyRegion(ClientPtr client)357 ProcXFixesCopyRegion(ClientPtr client)
358 {
359 RegionPtr pSource, pDestination;
360
361 REQUEST(xXFixesCopyRegionReq);
362 REQUEST_SIZE_MATCH(xXFixesCopyRegionReq);
363
364 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
365 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
366
367 if (!RegionCopy(pDestination, pSource))
368 return BadAlloc;
369
370 return Success;
371 }
372
373 int _X_COLD
SProcXFixesCopyRegion(ClientPtr client)374 SProcXFixesCopyRegion(ClientPtr client)
375 {
376 REQUEST(xXFixesCopyRegionReq);
377
378 swaps(&stuff->length);
379 REQUEST_SIZE_MATCH(xXFixesCopyRegionReq);
380 swapl(&stuff->source);
381 swapl(&stuff->destination);
382 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
383 }
384
385 int
ProcXFixesCombineRegion(ClientPtr client)386 ProcXFixesCombineRegion(ClientPtr client)
387 {
388 RegionPtr pSource1, pSource2, pDestination;
389
390 REQUEST(xXFixesCombineRegionReq);
391
392 REQUEST_SIZE_MATCH(xXFixesCombineRegionReq);
393 VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess);
394 VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess);
395 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
396
397 switch (stuff->xfixesReqType) {
398 case X_XFixesUnionRegion:
399 if (!RegionUnion(pDestination, pSource1, pSource2))
400 return BadAlloc;
401 break;
402 case X_XFixesIntersectRegion:
403 if (!RegionIntersect(pDestination, pSource1, pSource2))
404 return BadAlloc;
405 break;
406 case X_XFixesSubtractRegion:
407 if (!RegionSubtract(pDestination, pSource1, pSource2))
408 return BadAlloc;
409 break;
410 }
411
412 return Success;
413 }
414
415 int _X_COLD
SProcXFixesCombineRegion(ClientPtr client)416 SProcXFixesCombineRegion(ClientPtr client)
417 {
418 REQUEST(xXFixesCombineRegionReq);
419
420 swaps(&stuff->length);
421 REQUEST_SIZE_MATCH(xXFixesCombineRegionReq);
422 swapl(&stuff->source1);
423 swapl(&stuff->source2);
424 swapl(&stuff->destination);
425 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
426 }
427
428 int
ProcXFixesInvertRegion(ClientPtr client)429 ProcXFixesInvertRegion(ClientPtr client)
430 {
431 RegionPtr pSource, pDestination;
432 BoxRec bounds;
433
434 REQUEST(xXFixesInvertRegionReq);
435
436 REQUEST_SIZE_MATCH(xXFixesInvertRegionReq);
437 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
438 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
439
440 /* Compute bounds, limit to 16 bits */
441 bounds.x1 = stuff->x;
442 bounds.y1 = stuff->y;
443 if ((int) stuff->x + (int) stuff->width > MAXSHORT)
444 bounds.x2 = MAXSHORT;
445 else
446 bounds.x2 = stuff->x + stuff->width;
447
448 if ((int) stuff->y + (int) stuff->height > MAXSHORT)
449 bounds.y2 = MAXSHORT;
450 else
451 bounds.y2 = stuff->y + stuff->height;
452
453 if (!RegionInverse(pDestination, pSource, &bounds))
454 return BadAlloc;
455
456 return Success;
457 }
458
459 int _X_COLD
SProcXFixesInvertRegion(ClientPtr client)460 SProcXFixesInvertRegion(ClientPtr client)
461 {
462 REQUEST(xXFixesInvertRegionReq);
463
464 swaps(&stuff->length);
465 REQUEST_SIZE_MATCH(xXFixesInvertRegionReq);
466 swapl(&stuff->source);
467 swaps(&stuff->x);
468 swaps(&stuff->y);
469 swaps(&stuff->width);
470 swaps(&stuff->height);
471 swapl(&stuff->destination);
472 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
473 }
474
475 int
ProcXFixesTranslateRegion(ClientPtr client)476 ProcXFixesTranslateRegion(ClientPtr client)
477 {
478 RegionPtr pRegion;
479
480 REQUEST(xXFixesTranslateRegionReq);
481
482 REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
483 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
484
485 RegionTranslate(pRegion, stuff->dx, stuff->dy);
486 return Success;
487 }
488
489 int _X_COLD
SProcXFixesTranslateRegion(ClientPtr client)490 SProcXFixesTranslateRegion(ClientPtr client)
491 {
492 REQUEST(xXFixesTranslateRegionReq);
493
494 swaps(&stuff->length);
495 REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
496 swapl(&stuff->region);
497 swaps(&stuff->dx);
498 swaps(&stuff->dy);
499 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
500 }
501
502 int
ProcXFixesRegionExtents(ClientPtr client)503 ProcXFixesRegionExtents(ClientPtr client)
504 {
505 RegionPtr pSource, pDestination;
506
507 REQUEST(xXFixesRegionExtentsReq);
508
509 REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq);
510 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
511 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
512
513 RegionReset(pDestination, RegionExtents(pSource));
514
515 return Success;
516 }
517
518 int _X_COLD
SProcXFixesRegionExtents(ClientPtr client)519 SProcXFixesRegionExtents(ClientPtr client)
520 {
521 REQUEST(xXFixesRegionExtentsReq);
522
523 swaps(&stuff->length);
524 REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq);
525 swapl(&stuff->source);
526 swapl(&stuff->destination);
527 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
528 }
529
530 int
ProcXFixesFetchRegion(ClientPtr client)531 ProcXFixesFetchRegion(ClientPtr client)
532 {
533 RegionPtr pRegion;
534 xXFixesFetchRegionReply *reply;
535 xRectangle *pRect;
536 BoxPtr pExtent;
537 BoxPtr pBox;
538 int i, nBox;
539
540 REQUEST(xXFixesFetchRegionReq);
541
542 REQUEST_SIZE_MATCH(xXFixesFetchRegionReq);
543 VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess);
544
545 pExtent = RegionExtents(pRegion);
546 pBox = RegionRects(pRegion);
547 nBox = RegionNumRects(pRegion);
548
549 reply = calloc(sizeof(xXFixesFetchRegionReply) + nBox * sizeof(xRectangle),
550 1);
551 if (!reply)
552 return BadAlloc;
553 reply->type = X_Reply;
554 reply->sequenceNumber = client->sequence;
555 reply->length = nBox << 1;
556 reply->x = pExtent->x1;
557 reply->y = pExtent->y1;
558 reply->width = pExtent->x2 - pExtent->x1;
559 reply->height = pExtent->y2 - pExtent->y1;
560
561 pRect = (xRectangle *) (reply + 1);
562 for (i = 0; i < nBox; i++) {
563 pRect[i].x = pBox[i].x1;
564 pRect[i].y = pBox[i].y1;
565 pRect[i].width = pBox[i].x2 - pBox[i].x1;
566 pRect[i].height = pBox[i].y2 - pBox[i].y1;
567 }
568 if (client->swapped) {
569 swaps(&reply->sequenceNumber);
570 swapl(&reply->length);
571 swaps(&reply->x);
572 swaps(&reply->y);
573 swaps(&reply->width);
574 swaps(&reply->height);
575 SwapShorts((INT16 *) pRect, nBox * 4);
576 }
577 WriteToClient(client, sizeof(xXFixesFetchRegionReply) +
578 nBox * sizeof(xRectangle), (char *) reply);
579 free(reply);
580 return Success;
581 }
582
583 int _X_COLD
SProcXFixesFetchRegion(ClientPtr client)584 SProcXFixesFetchRegion(ClientPtr client)
585 {
586 REQUEST(xXFixesFetchRegionReq);
587
588 swaps(&stuff->length);
589 REQUEST_SIZE_MATCH(xXFixesFetchRegionReq);
590 swapl(&stuff->region);
591 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
592 }
593
594 int
ProcXFixesSetGCClipRegion(ClientPtr client)595 ProcXFixesSetGCClipRegion(ClientPtr client)
596 {
597 GCPtr pGC;
598 RegionPtr pRegion;
599 ChangeGCVal vals[2];
600 int rc;
601
602 REQUEST(xXFixesSetGCClipRegionReq);
603 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
604
605 rc = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
606 if (rc != Success)
607 return rc;
608
609 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess);
610
611 if (pRegion) {
612 pRegion = XFixesRegionCopy(pRegion);
613 if (!pRegion)
614 return BadAlloc;
615 }
616
617 vals[0].val = stuff->xOrigin;
618 vals[1].val = stuff->yOrigin;
619 ChangeGC(NullClient, pGC, GCClipXOrigin | GCClipYOrigin, vals);
620 (*pGC->funcs->ChangeClip) (pGC, pRegion ? CT_REGION : CT_NONE,
621 (void *) pRegion, 0);
622
623 return Success;
624 }
625
626 int _X_COLD
SProcXFixesSetGCClipRegion(ClientPtr client)627 SProcXFixesSetGCClipRegion(ClientPtr client)
628 {
629 REQUEST(xXFixesSetGCClipRegionReq);
630
631 swaps(&stuff->length);
632 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
633 swapl(&stuff->gc);
634 swapl(&stuff->region);
635 swaps(&stuff->xOrigin);
636 swaps(&stuff->yOrigin);
637 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
638 }
639
640 typedef RegionPtr (*CreateDftPtr) (WindowPtr pWin);
641
642 int
ProcXFixesSetWindowShapeRegion(ClientPtr client)643 ProcXFixesSetWindowShapeRegion(ClientPtr client)
644 {
645 WindowPtr pWin;
646 RegionPtr pRegion;
647 RegionPtr *pDestRegion;
648 int rc;
649
650 REQUEST(xXFixesSetWindowShapeRegionReq);
651
652 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
653 rc = dixLookupResourceByType((void **) &pWin, stuff->dest, RT_WINDOW,
654 client, DixSetAttrAccess);
655 if (rc != Success) {
656 client->errorValue = stuff->dest;
657 return rc;
658 }
659 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess);
660 switch (stuff->destKind) {
661 case ShapeBounding:
662 case ShapeClip:
663 case ShapeInput:
664 break;
665 default:
666 client->errorValue = stuff->destKind;
667 return BadValue;
668 }
669 if (pRegion) {
670 pRegion = XFixesRegionCopy(pRegion);
671 if (!pRegion)
672 return BadAlloc;
673 if (!pWin->optional)
674 MakeWindowOptional(pWin);
675 switch (stuff->destKind) {
676 default:
677 case ShapeBounding:
678 pDestRegion = &pWin->optional->boundingShape;
679 break;
680 case ShapeClip:
681 pDestRegion = &pWin->optional->clipShape;
682 break;
683 case ShapeInput:
684 pDestRegion = &pWin->optional->inputShape;
685 break;
686 }
687 if (stuff->xOff || stuff->yOff)
688 RegionTranslate(pRegion, stuff->xOff, stuff->yOff);
689 }
690 else {
691 if (pWin->optional) {
692 switch (stuff->destKind) {
693 default:
694 case ShapeBounding:
695 pDestRegion = &pWin->optional->boundingShape;
696 break;
697 case ShapeClip:
698 pDestRegion = &pWin->optional->clipShape;
699 break;
700 case ShapeInput:
701 pDestRegion = &pWin->optional->inputShape;
702 break;
703 }
704 }
705 else
706 pDestRegion = &pRegion; /* a NULL region pointer */
707 }
708 if (*pDestRegion)
709 RegionDestroy(*pDestRegion);
710 *pDestRegion = pRegion;
711 (*pWin->drawable.pScreen->SetShape) (pWin, stuff->destKind);
712 SendShapeNotify(pWin, stuff->destKind);
713 return Success;
714 }
715
716 int _X_COLD
SProcXFixesSetWindowShapeRegion(ClientPtr client)717 SProcXFixesSetWindowShapeRegion(ClientPtr client)
718 {
719 REQUEST(xXFixesSetWindowShapeRegionReq);
720
721 swaps(&stuff->length);
722 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
723 swapl(&stuff->dest);
724 swaps(&stuff->xOff);
725 swaps(&stuff->yOff);
726 swapl(&stuff->region);
727 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
728 }
729
730 int
ProcXFixesSetPictureClipRegion(ClientPtr client)731 ProcXFixesSetPictureClipRegion(ClientPtr client)
732 {
733 PicturePtr pPicture;
734 RegionPtr pRegion;
735
736 REQUEST(xXFixesSetPictureClipRegionReq);
737
738 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq);
739 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
740 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess);
741
742 if (!pPicture->pDrawable)
743 return RenderErrBase + BadPicture;
744
745 return SetPictureClipRegion(pPicture, stuff->xOrigin, stuff->yOrigin,
746 pRegion);
747 }
748
749 int _X_COLD
SProcXFixesSetPictureClipRegion(ClientPtr client)750 SProcXFixesSetPictureClipRegion(ClientPtr client)
751 {
752 REQUEST(xXFixesSetPictureClipRegionReq);
753
754 swaps(&stuff->length);
755 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq);
756 swapl(&stuff->picture);
757 swapl(&stuff->region);
758 swaps(&stuff->xOrigin);
759 swaps(&stuff->yOrigin);
760 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
761 }
762
763 int
ProcXFixesExpandRegion(ClientPtr client)764 ProcXFixesExpandRegion(ClientPtr client)
765 {
766 RegionPtr pSource, pDestination;
767
768 REQUEST(xXFixesExpandRegionReq);
769 BoxPtr pTmp;
770 BoxPtr pSrc;
771 int nBoxes;
772 int i;
773
774 REQUEST_SIZE_MATCH(xXFixesExpandRegionReq);
775 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
776 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
777
778 nBoxes = RegionNumRects(pSource);
779 pSrc = RegionRects(pSource);
780 if (nBoxes) {
781 pTmp = xallocarray(nBoxes, sizeof(BoxRec));
782 if (!pTmp)
783 return BadAlloc;
784 for (i = 0; i < nBoxes; i++) {
785 pTmp[i].x1 = pSrc[i].x1 - stuff->left;
786 pTmp[i].x2 = pSrc[i].x2 + stuff->right;
787 pTmp[i].y1 = pSrc[i].y1 - stuff->top;
788 pTmp[i].y2 = pSrc[i].y2 + stuff->bottom;
789 }
790 RegionEmpty(pDestination);
791 for (i = 0; i < nBoxes; i++) {
792 RegionRec r;
793
794 RegionInit(&r, &pTmp[i], 0);
795 RegionUnion(pDestination, pDestination, &r);
796 }
797 free(pTmp);
798 }
799 return Success;
800 }
801
802 int _X_COLD
SProcXFixesExpandRegion(ClientPtr client)803 SProcXFixesExpandRegion(ClientPtr client)
804 {
805 REQUEST(xXFixesExpandRegionReq);
806
807 swaps(&stuff->length);
808 REQUEST_SIZE_MATCH(xXFixesExpandRegionReq);
809 swapl(&stuff->source);
810 swapl(&stuff->destination);
811 swaps(&stuff->left);
812 swaps(&stuff->right);
813 swaps(&stuff->top);
814 swaps(&stuff->bottom);
815 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
816 }
817
818 #ifdef PANORAMIX
819 #include "panoramiX.h"
820 #include "panoramiXsrv.h"
821
822 int
PanoramiXFixesSetGCClipRegion(ClientPtr client)823 PanoramiXFixesSetGCClipRegion(ClientPtr client)
824 {
825 REQUEST(xXFixesSetGCClipRegionReq);
826 int result = Success, j;
827 PanoramiXRes *gc;
828
829 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
830
831 if ((result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
832 client, DixWriteAccess))) {
833 client->errorValue = stuff->gc;
834 return result;
835 }
836
837 FOR_NSCREENS_BACKWARD(j) {
838 stuff->gc = gc->info[j].id;
839 result = (*PanoramiXSaveXFixesVector[X_XFixesSetGCClipRegion]) (client);
840 if (result != Success)
841 break;
842 }
843
844 return result;
845 }
846
847 int
PanoramiXFixesSetWindowShapeRegion(ClientPtr client)848 PanoramiXFixesSetWindowShapeRegion(ClientPtr client)
849 {
850 int result = Success, j;
851 PanoramiXRes *win;
852 RegionPtr reg = NULL;
853
854 REQUEST(xXFixesSetWindowShapeRegionReq);
855
856 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
857
858 if ((result = dixLookupResourceByType((void **) &win, stuff->dest,
859 XRT_WINDOW, client,
860 DixWriteAccess))) {
861 client->errorValue = stuff->dest;
862 return result;
863 }
864
865 if (win->u.win.root)
866 VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess);
867
868 FOR_NSCREENS_FORWARD(j) {
869 ScreenPtr screen = screenInfo.screens[j];
870 stuff->dest = win->info[j].id;
871
872 if (reg)
873 RegionTranslate(reg, -screen->x, -screen->y);
874
875 result =
876 (*PanoramiXSaveXFixesVector[X_XFixesSetWindowShapeRegion]) (client);
877
878 if (reg)
879 RegionTranslate(reg, screen->x, screen->y);
880
881 if (result != Success)
882 break;
883 }
884
885 return result;
886 }
887
888 int
PanoramiXFixesSetPictureClipRegion(ClientPtr client)889 PanoramiXFixesSetPictureClipRegion(ClientPtr client)
890 {
891 REQUEST(xXFixesSetPictureClipRegionReq);
892 int result = Success, j;
893 PanoramiXRes *pict;
894 RegionPtr reg = NULL;
895
896 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq);
897
898 if ((result = dixLookupResourceByType((void **) &pict, stuff->picture,
899 XRT_PICTURE, client,
900 DixWriteAccess))) {
901 client->errorValue = stuff->picture;
902 return result;
903 }
904
905 if (pict->u.pict.root)
906 VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess);
907
908 FOR_NSCREENS_BACKWARD(j) {
909 ScreenPtr screen = screenInfo.screens[j];
910 stuff->picture = pict->info[j].id;
911
912 if (reg)
913 RegionTranslate(reg, -screen->x, -screen->y);
914
915 result =
916 (*PanoramiXSaveXFixesVector[X_XFixesSetPictureClipRegion]) (client);
917
918 if (reg)
919 RegionTranslate(reg, screen->x, screen->y);
920
921 if (result != Success)
922 break;
923 }
924
925 return result;
926 }
927
928 #endif
929