xref: /OK3568_Linux_fs/external/xserver/xfixes/region.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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