Imported Upstream version 1.15.1
[deb_xorg-server.git] / xfixes / region.c
CommitLineData
a09e091a
JB
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
35RESTYPE RegionResType;
36
37static int
38RegionResFree(pointer data, XID id)
39{
40 RegionPtr pRegion = (RegionPtr) data;
41
42 RegionDestroy(pRegion);
43 return Success;
44}
45
46RegionPtr
47XFixesRegionCopy(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
61Bool
62XFixesRegionInit(void)
63{
64 RegionResType = CreateNewResourceType(RegionResFree, "XFixesRegion");
65
66 return RegionResType != 0;
67}
68
69int
70ProcXFixesCreateRegion(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, (pointer) pRegion))
89 return BadAlloc;
90
91 return Success;
92}
93
94int
95SProcXFixesCreateRegion(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
106int
107ProcXFixesCreateRegionFromBitmap(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((pointer *) &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, (pointer) pRegion))
133 return BadAlloc;
134
135 return Success;
136}
137
138int
139SProcXFixesCreateRegionFromBitmap(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
150int
151ProcXFixesCreateRegionFromWindow(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((pointer *) &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, (pointer) pRegion))
192 return BadAlloc;
193
194 return Success;
195}
196
197int
198SProcXFixesCreateRegionFromWindow(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
209int
210ProcXFixesCreateRegionFromGC(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 switch (pGC->clientClipType) {
226 case CT_PIXMAP:
227 pRegion = BitmapToRegion(pGC->pScreen, (PixmapPtr) pGC->clientClip);
228 if (!pRegion)
229 return BadAlloc;
230 break;
231 case CT_REGION:
232 pClip = (RegionPtr) pGC->clientClip;
233 pRegion = XFixesRegionCopy(pClip);
234 if (!pRegion)
235 return BadAlloc;
236 break;
237 default:
238 return BadImplementation; /* assume sane server bits */
239 }
240
241 if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
242 return BadAlloc;
243
244 return Success;
245}
246
247int
248SProcXFixesCreateRegionFromGC(ClientPtr client)
249{
250 REQUEST(xXFixesCreateRegionFromGCReq);
251
252 swaps(&stuff->length);
253 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromGCReq);
254 swapl(&stuff->region);
255 swapl(&stuff->gc);
256 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
257}
258
259int
260ProcXFixesCreateRegionFromPicture(ClientPtr client)
261{
262 RegionPtr pRegion;
263 PicturePtr pPicture;
264
265 REQUEST(xXFixesCreateRegionFromPictureReq);
266
267 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromPictureReq);
268 LEGAL_NEW_RESOURCE(stuff->region, client);
269
270 VERIFY_PICTURE(pPicture, stuff->picture, client, DixGetAttrAccess);
271
272 switch (pPicture->clientClipType) {
273 case CT_PIXMAP:
274 pRegion = BitmapToRegion(pPicture->pDrawable->pScreen,
275 (PixmapPtr) pPicture->clientClip);
276 if (!pRegion)
277 return BadAlloc;
278 break;
279 case CT_REGION:
280 pRegion = XFixesRegionCopy((RegionPtr) pPicture->clientClip);
281 if (!pRegion)
282 return BadAlloc;
283 break;
284 default:
285 return BadImplementation; /* assume sane server bits */
286 }
287
288 if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
289 return BadAlloc;
290
291 return Success;
292}
293
294int
295SProcXFixesCreateRegionFromPicture(ClientPtr client)
296{
297 REQUEST(xXFixesCreateRegionFromPictureReq);
298
299 swaps(&stuff->length);
300 REQUEST_SIZE_MATCH(xXFixesCreateRegionFromPictureReq);
301 swapl(&stuff->region);
302 swapl(&stuff->picture);
303 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
304}
305
306int
307ProcXFixesDestroyRegion(ClientPtr client)
308{
309 REQUEST(xXFixesDestroyRegionReq);
310 RegionPtr pRegion;
311
312 REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq);
313 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
314 FreeResource(stuff->region, RT_NONE);
315 return Success;
316}
317
318int
319SProcXFixesDestroyRegion(ClientPtr client)
320{
321 REQUEST(xXFixesDestroyRegionReq);
322
323 swaps(&stuff->length);
324 REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq);
325 swapl(&stuff->region);
326 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
327}
328
329int
330ProcXFixesSetRegion(ClientPtr client)
331{
332 int things;
333 RegionPtr pRegion, pNew;
334
335 REQUEST(xXFixesSetRegionReq);
336
337 REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
338 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
339
340 things = (client->req_len << 2) - sizeof(xXFixesCreateRegionReq);
341 if (things & 4)
342 return BadLength;
343 things >>= 3;
344
345 pNew = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED);
346 if (!pNew)
347 return BadAlloc;
348 if (!RegionCopy(pRegion, pNew)) {
349 RegionDestroy(pNew);
350 return BadAlloc;
351 }
352 RegionDestroy(pNew);
353 return Success;
354}
355
356int
357SProcXFixesSetRegion(ClientPtr client)
358{
359 REQUEST(xXFixesSetRegionReq);
360
361 swaps(&stuff->length);
362 REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
363 swapl(&stuff->region);
364 SwapRestS(stuff);
365 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
366}
367
368int
369ProcXFixesCopyRegion(ClientPtr client)
370{
371 RegionPtr pSource, pDestination;
372
373 REQUEST(xXFixesCopyRegionReq);
374
375 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
376 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
377
378 if (!RegionCopy(pDestination, pSource))
379 return BadAlloc;
380
381 return Success;
382}
383
384int
385SProcXFixesCopyRegion(ClientPtr client)
386{
387 REQUEST(xXFixesCopyRegionReq);
388
389 swaps(&stuff->length);
390 REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq);
391 swapl(&stuff->source);
392 swapl(&stuff->destination);
393 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
394}
395
396int
397ProcXFixesCombineRegion(ClientPtr client)
398{
399 RegionPtr pSource1, pSource2, pDestination;
400
401 REQUEST(xXFixesCombineRegionReq);
402
403 REQUEST_SIZE_MATCH(xXFixesCombineRegionReq);
404 VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess);
405 VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess);
406 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
407
408 switch (stuff->xfixesReqType) {
409 case X_XFixesUnionRegion:
410 if (!RegionUnion(pDestination, pSource1, pSource2))
411 return BadAlloc;
412 break;
413 case X_XFixesIntersectRegion:
414 if (!RegionIntersect(pDestination, pSource1, pSource2))
415 return BadAlloc;
416 break;
417 case X_XFixesSubtractRegion:
418 if (!RegionSubtract(pDestination, pSource1, pSource2))
419 return BadAlloc;
420 break;
421 }
422
423 return Success;
424}
425
426int
427SProcXFixesCombineRegion(ClientPtr client)
428{
429 REQUEST(xXFixesCombineRegionReq);
430
431 swaps(&stuff->length);
432 REQUEST_SIZE_MATCH(xXFixesCombineRegionReq);
433 swapl(&stuff->source1);
434 swapl(&stuff->source2);
435 swapl(&stuff->destination);
436 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
437}
438
439int
440ProcXFixesInvertRegion(ClientPtr client)
441{
442 RegionPtr pSource, pDestination;
443 BoxRec bounds;
444
445 REQUEST(xXFixesInvertRegionReq);
446
447 REQUEST_SIZE_MATCH(xXFixesInvertRegionReq);
448 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
449 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
450
451 /* Compute bounds, limit to 16 bits */
452 bounds.x1 = stuff->x;
453 bounds.y1 = stuff->y;
454 if ((int) stuff->x + (int) stuff->width > MAXSHORT)
455 bounds.x2 = MAXSHORT;
456 else
457 bounds.x2 = stuff->x + stuff->width;
458
459 if ((int) stuff->y + (int) stuff->height > MAXSHORT)
460 bounds.y2 = MAXSHORT;
461 else
462 bounds.y2 = stuff->y + stuff->height;
463
464 if (!RegionInverse(pDestination, pSource, &bounds))
465 return BadAlloc;
466
467 return Success;
468}
469
470int
471SProcXFixesInvertRegion(ClientPtr client)
472{
473 REQUEST(xXFixesInvertRegionReq);
474
475 swaps(&stuff->length);
476 REQUEST_SIZE_MATCH(xXFixesInvertRegionReq);
477 swapl(&stuff->source);
478 swaps(&stuff->x);
479 swaps(&stuff->y);
480 swaps(&stuff->width);
481 swaps(&stuff->height);
482 swapl(&stuff->destination);
483 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
484}
485
486int
487ProcXFixesTranslateRegion(ClientPtr client)
488{
489 RegionPtr pRegion;
490
491 REQUEST(xXFixesTranslateRegionReq);
492
493 REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
494 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
495
496 RegionTranslate(pRegion, stuff->dx, stuff->dy);
497 return Success;
498}
499
500int
501SProcXFixesTranslateRegion(ClientPtr client)
502{
503 REQUEST(xXFixesTranslateRegionReq);
504
505 swaps(&stuff->length);
506 REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
507 swapl(&stuff->region);
508 swaps(&stuff->dx);
509 swaps(&stuff->dy);
510 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
511}
512
513int
514ProcXFixesRegionExtents(ClientPtr client)
515{
516 RegionPtr pSource, pDestination;
517
518 REQUEST(xXFixesRegionExtentsReq);
519
520 REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq);
521 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
522 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
523
524 RegionReset(pDestination, RegionExtents(pSource));
525
526 return Success;
527}
528
529int
530SProcXFixesRegionExtents(ClientPtr client)
531{
532 REQUEST(xXFixesRegionExtentsReq);
533
534 swaps(&stuff->length);
535 REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq);
536 swapl(&stuff->source);
537 swapl(&stuff->destination);
538 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
539}
540
541int
542ProcXFixesFetchRegion(ClientPtr client)
543{
544 RegionPtr pRegion;
545 xXFixesFetchRegionReply *reply;
546 xRectangle *pRect;
547 BoxPtr pExtent;
548 BoxPtr pBox;
549 int i, nBox;
550
551 REQUEST(xXFixesFetchRegionReq);
552
553 REQUEST_SIZE_MATCH(xXFixesFetchRegionReq);
554 VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess);
555
556 pExtent = RegionExtents(pRegion);
557 pBox = RegionRects(pRegion);
558 nBox = RegionNumRects(pRegion);
559
560 reply = calloc(sizeof(xXFixesFetchRegionReply) + nBox * sizeof(xRectangle),
561 1);
562 if (!reply)
563 return BadAlloc;
564 reply->type = X_Reply;
565 reply->sequenceNumber = client->sequence;
566 reply->length = nBox << 1;
567 reply->x = pExtent->x1;
568 reply->y = pExtent->y1;
569 reply->width = pExtent->x2 - pExtent->x1;
570 reply->height = pExtent->y2 - pExtent->y1;
571
572 pRect = (xRectangle *) (reply + 1);
573 for (i = 0; i < nBox; i++) {
574 pRect[i].x = pBox[i].x1;
575 pRect[i].y = pBox[i].y1;
576 pRect[i].width = pBox[i].x2 - pBox[i].x1;
577 pRect[i].height = pBox[i].y2 - pBox[i].y1;
578 }
579 if (client->swapped) {
580 swaps(&reply->sequenceNumber);
581 swapl(&reply->length);
582 swaps(&reply->x);
583 swaps(&reply->y);
584 swaps(&reply->width);
585 swaps(&reply->height);
586 SwapShorts((INT16 *) pRect, nBox * 4);
587 }
588 WriteToClient(client, sizeof(xXFixesFetchRegionReply) +
589 nBox * sizeof(xRectangle), (char *) reply);
590 free(reply);
591 return Success;
592}
593
594int
595SProcXFixesFetchRegion(ClientPtr client)
596{
597 REQUEST(xXFixesFetchRegionReq);
598
599 swaps(&stuff->length);
600 REQUEST_SIZE_MATCH(xXFixesFetchRegionReq);
601 swapl(&stuff->region);
602 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
603}
604
605int
606ProcXFixesSetGCClipRegion(ClientPtr client)
607{
608 GCPtr pGC;
609 RegionPtr pRegion;
610 ChangeGCVal vals[2];
611 int rc;
612
613 REQUEST(xXFixesSetGCClipRegionReq);
614 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
615
616 rc = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
617 if (rc != Success)
618 return rc;
619
620 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess);
621
622 if (pRegion) {
623 pRegion = XFixesRegionCopy(pRegion);
624 if (!pRegion)
625 return BadAlloc;
626 }
627
628 vals[0].val = stuff->xOrigin;
629 vals[1].val = stuff->yOrigin;
630 ChangeGC(NullClient, pGC, GCClipXOrigin | GCClipYOrigin, vals);
631 (*pGC->funcs->ChangeClip) (pGC, pRegion ? CT_REGION : CT_NONE,
632 (pointer) pRegion, 0);
633
634 return Success;
635}
636
637int
638SProcXFixesSetGCClipRegion(ClientPtr client)
639{
640 REQUEST(xXFixesSetGCClipRegionReq);
641
642 swaps(&stuff->length);
643 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
644 swapl(&stuff->gc);
645 swapl(&stuff->region);
646 swaps(&stuff->xOrigin);
647 swaps(&stuff->yOrigin);
648 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
649}
650
651typedef RegionPtr (*CreateDftPtr) (WindowPtr pWin);
652
653int
654ProcXFixesSetWindowShapeRegion(ClientPtr client)
655{
656 WindowPtr pWin;
657 RegionPtr pRegion;
658 RegionPtr *pDestRegion;
659 int rc;
660
661 REQUEST(xXFixesSetWindowShapeRegionReq);
662
663 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
664 rc = dixLookupResourceByType((pointer *) &pWin, stuff->dest, RT_WINDOW,
665 client, DixSetAttrAccess);
666 if (rc != Success) {
667 client->errorValue = stuff->dest;
668 return rc;
669 }
670 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess);
671 switch (stuff->destKind) {
672 case ShapeBounding:
673 case ShapeClip:
674 case ShapeInput:
675 break;
676 default:
677 client->errorValue = stuff->destKind;
678 return BadValue;
679 }
680 if (pRegion) {
681 pRegion = XFixesRegionCopy(pRegion);
682 if (!pRegion)
683 return BadAlloc;
684 if (!pWin->optional)
685 MakeWindowOptional(pWin);
686 switch (stuff->destKind) {
687 default:
688 case ShapeBounding:
689 pDestRegion = &pWin->optional->boundingShape;
690 break;
691 case ShapeClip:
692 pDestRegion = &pWin->optional->clipShape;
693 break;
694 case ShapeInput:
695 pDestRegion = &pWin->optional->inputShape;
696 break;
697 }
698 if (stuff->xOff || stuff->yOff)
699 RegionTranslate(pRegion, stuff->xOff, stuff->yOff);
700 }
701 else {
702 if (pWin->optional) {
703 switch (stuff->destKind) {
704 default:
705 case ShapeBounding:
706 pDestRegion = &pWin->optional->boundingShape;
707 break;
708 case ShapeClip:
709 pDestRegion = &pWin->optional->clipShape;
710 break;
711 case ShapeInput:
712 pDestRegion = &pWin->optional->inputShape;
713 break;
714 }
715 }
716 else
717 pDestRegion = &pRegion; /* a NULL region pointer */
718 }
719 if (*pDestRegion)
720 RegionDestroy(*pDestRegion);
721 *pDestRegion = pRegion;
722 (*pWin->drawable.pScreen->SetShape) (pWin, stuff->destKind);
723 SendShapeNotify(pWin, stuff->destKind);
724 return Success;
725}
726
727int
728SProcXFixesSetWindowShapeRegion(ClientPtr client)
729{
730 REQUEST(xXFixesSetWindowShapeRegionReq);
731
732 swaps(&stuff->length);
733 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
734 swapl(&stuff->dest);
735 swaps(&stuff->xOff);
736 swaps(&stuff->yOff);
737 swapl(&stuff->region);
738 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
739}
740
741int
742ProcXFixesSetPictureClipRegion(ClientPtr client)
743{
744 PicturePtr pPicture;
745 RegionPtr pRegion;
746
747 REQUEST(xXFixesSetPictureClipRegionReq);
748
749 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq);
750 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
751 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess);
752
753 return SetPictureClipRegion(pPicture, stuff->xOrigin, stuff->yOrigin,
754 pRegion);
755}
756
757int
758SProcXFixesSetPictureClipRegion(ClientPtr client)
759{
760 REQUEST(xXFixesSetPictureClipRegionReq);
761
762 swaps(&stuff->length);
763 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq);
764 swapl(&stuff->picture);
765 swapl(&stuff->region);
766 swaps(&stuff->xOrigin);
767 swaps(&stuff->yOrigin);
768 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
769}
770
771int
772ProcXFixesExpandRegion(ClientPtr client)
773{
774 RegionPtr pSource, pDestination;
775
776 REQUEST(xXFixesExpandRegionReq);
777 BoxPtr pTmp;
778 BoxPtr pSrc;
779 int nBoxes;
780 int i;
781
782 REQUEST_SIZE_MATCH(xXFixesExpandRegionReq);
783 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
784 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
785
786 nBoxes = RegionNumRects(pSource);
787 pSrc = RegionRects(pSource);
788 if (nBoxes) {
789 pTmp = malloc(nBoxes * sizeof(BoxRec));
790 if (!pTmp)
791 return BadAlloc;
792 for (i = 0; i < nBoxes; i++) {
793 pTmp[i].x1 = pSrc[i].x1 - stuff->left;
794 pTmp[i].x2 = pSrc[i].x2 + stuff->right;
795 pTmp[i].y1 = pSrc[i].y1 - stuff->top;
796 pTmp[i].y2 = pSrc[i].y2 + stuff->bottom;
797 }
798 RegionEmpty(pDestination);
799 for (i = 0; i < nBoxes; i++) {
800 RegionRec r;
801
802 RegionInit(&r, &pTmp[i], 0);
803 RegionUnion(pDestination, pDestination, &r);
804 }
805 free(pTmp);
806 }
807 return Success;
808}
809
810int
811SProcXFixesExpandRegion(ClientPtr client)
812{
813 REQUEST(xXFixesExpandRegionReq);
814
815 swaps(&stuff->length);
816 REQUEST_SIZE_MATCH(xXFixesExpandRegionReq);
817 swapl(&stuff->source);
818 swapl(&stuff->destination);
819 swaps(&stuff->left);
820 swaps(&stuff->right);
821 swaps(&stuff->top);
822 swaps(&stuff->bottom);
823 return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
824}
825
826#ifdef PANORAMIX
827#include "panoramiX.h"
828#include "panoramiXsrv.h"
829
830int
831PanoramiXFixesSetGCClipRegion(ClientPtr client)
832{
833 REQUEST(xXFixesSetGCClipRegionReq);
834 int result = Success, j;
835 PanoramiXRes *gc;
836
837 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
838
839 if ((result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
840 client, DixWriteAccess))) {
841 client->errorValue = stuff->gc;
842 return result;
843 }
844
845 FOR_NSCREENS_BACKWARD(j) {
846 stuff->gc = gc->info[j].id;
847 result = (*PanoramiXSaveXFixesVector[X_XFixesSetGCClipRegion]) (client);
848 if (result != Success)
849 break;
850 }
851
852 return result;
853}
854
855int
856PanoramiXFixesSetWindowShapeRegion(ClientPtr client)
857{
858 int result = Success, j;
859 PanoramiXRes *win;
860 RegionPtr reg = NULL;
861
862 REQUEST(xXFixesSetWindowShapeRegionReq);
863
864 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
865
866 if ((result = dixLookupResourceByType((void **) &win, stuff->dest,
867 XRT_WINDOW, client,
868 DixWriteAccess))) {
869 client->errorValue = stuff->dest;
870 return result;
871 }
872
873 if (win->u.win.root)
874 VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess);
875
876 FOR_NSCREENS_FORWARD(j) {
877 ScreenPtr screen = screenInfo.screens[j];
878 stuff->dest = win->info[j].id;
879
880 if (reg)
881 RegionTranslate(reg, -screen->x, -screen->y);
882
883 result =
884 (*PanoramiXSaveXFixesVector[X_XFixesSetWindowShapeRegion]) (client);
885
886 if (reg)
887 RegionTranslate(reg, screen->x, screen->y);
888
889 if (result != Success)
890 break;
891 }
892
893 return result;
894}
895
896int
897PanoramiXFixesSetPictureClipRegion(ClientPtr client)
898{
899 REQUEST(xXFixesSetPictureClipRegionReq);
900 int result = Success, j;
901 PanoramiXRes *pict;
902 RegionPtr reg = NULL;
903
904 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq);
905
906 if ((result = dixLookupResourceByType((void **) &pict, stuff->picture,
907 XRT_PICTURE, client,
908 DixWriteAccess))) {
909 client->errorValue = stuff->picture;
910 return result;
911 }
912
913 if (pict->u.pict.root)
914 VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess);
915
916 FOR_NSCREENS_BACKWARD(j) {
917 ScreenPtr screen = screenInfo.screens[j];
918 stuff->picture = pict->info[j].id;
919
920 if (reg)
921 RegionTranslate(reg, -screen->x, -screen->y);
922
923 result =
924 (*PanoramiXSaveXFixesVector[X_XFixesSetPictureClipRegion]) (client);
925
926 if (reg)
927 RegionTranslate(reg, screen->x, screen->y);
928
929 if (result != Success)
930 break;
931 }
932
933 return result;
934}
935
936#endif