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