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