Region.c revision 0f1ac3bc
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_CONFIG_H
24#include <config.h>
25#endif
26#include <limits.h>
27#include "Xfixesint.h"
28
29XserverRegion
30XFixesCreateRegion (Display *dpy, XRectangle *rectangles, int nrectangles)
31{
32    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
33    xXFixesCreateRegionReq	*req;
34    long    			len;
35    XserverRegion		region;
36
37    XFixesCheckExtension (dpy, info, 0);
38    LockDisplay (dpy);
39    GetReq (XFixesCreateRegion, req);
40    req->reqType = info->codes->major_opcode;
41    req->xfixesReqType = X_XFixesCreateRegion;
42    region = req->region = XAllocID (dpy);
43    len = ((long) nrectangles) << 1;
44    SetReqLen (req, len, len);
45    len <<= 2;
46    Data16 (dpy, (short *) rectangles, len);
47    UnlockDisplay (dpy);
48    SyncHandle();
49    return region;
50}
51
52XserverRegion
53XFixesCreateRegionFromBitmap (Display *dpy, Pixmap bitmap)
54{
55    XFixesExtDisplayInfo		*info = XFixesFindDisplay (dpy);
56    xXFixesCreateRegionFromBitmapReq	*req;
57    XserverRegion			region;
58
59    XFixesCheckExtension (dpy, info, 0);
60    LockDisplay (dpy);
61    GetReq (XFixesCreateRegionFromBitmap, req);
62    req->reqType = info->codes->major_opcode;
63    req->xfixesReqType = X_XFixesCreateRegionFromBitmap;
64    region = req->region = XAllocID (dpy);
65    req->bitmap = bitmap;
66    UnlockDisplay (dpy);
67    SyncHandle();
68    return region;
69}
70
71XserverRegion
72XFixesCreateRegionFromWindow (Display *dpy, Window window, int kind)
73{
74    XFixesExtDisplayInfo		*info = XFixesFindDisplay (dpy);
75    xXFixesCreateRegionFromWindowReq	*req;
76    XserverRegion			region;
77
78    XFixesCheckExtension (dpy, info, 0);
79    LockDisplay (dpy);
80    GetReq (XFixesCreateRegionFromWindow, req);
81    req->reqType = info->codes->major_opcode;
82    req->xfixesReqType = X_XFixesCreateRegionFromWindow;
83    region = req->region = XAllocID (dpy);
84    req->window = window;
85    req->kind = kind;
86    UnlockDisplay (dpy);
87    SyncHandle();
88    return region;
89}
90
91XserverRegion
92XFixesCreateRegionFromGC (Display *dpy, GC gc)
93{
94    XFixesExtDisplayInfo		*info = XFixesFindDisplay (dpy);
95    xXFixesCreateRegionFromGCReq	*req;
96    XserverRegion			region;
97
98    XFixesCheckExtension (dpy, info, 0);
99    LockDisplay (dpy);
100    GetReq (XFixesCreateRegionFromGC, req);
101    req->reqType = info->codes->major_opcode;
102    req->xfixesReqType = X_XFixesCreateRegionFromGC;
103    region = req->region = XAllocID (dpy);
104    req->gc = gc->gid;
105    UnlockDisplay (dpy);
106    SyncHandle();
107    return region;
108}
109
110XserverRegion
111XFixesCreateRegionFromPicture (Display *dpy, XID picture)
112{
113    XFixesExtDisplayInfo		*info = XFixesFindDisplay (dpy);
114    xXFixesCreateRegionFromPictureReq	*req;
115    XserverRegion			region;
116
117    XFixesCheckExtension (dpy, info, 0);
118    LockDisplay (dpy);
119    GetReq (XFixesCreateRegionFromPicture, req);
120    req->reqType = info->codes->major_opcode;
121    req->xfixesReqType = X_XFixesCreateRegionFromPicture;
122    region = req->region = XAllocID (dpy);
123    req->picture = picture;
124    UnlockDisplay (dpy);
125    SyncHandle();
126    return region;
127}
128
129void
130XFixesDestroyRegion (Display *dpy, XserverRegion region)
131{
132    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
133    xXFixesDestroyRegionReq	*req;
134
135    XFixesSimpleCheckExtension (dpy, info);
136    LockDisplay (dpy);
137    GetReq (XFixesDestroyRegion, req);
138    req->reqType = info->codes->major_opcode;
139    req->xfixesReqType = X_XFixesDestroyRegion;
140    req->region = region;
141    UnlockDisplay (dpy);
142    SyncHandle();
143}
144
145void
146XFixesSetRegion (Display *dpy, XserverRegion region,
147		 XRectangle *rectangles, int nrectangles)
148{
149    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
150    xXFixesSetRegionReq		*req;
151    long    			len;
152
153    XFixesSimpleCheckExtension (dpy, info);
154    LockDisplay (dpy);
155    GetReq (XFixesSetRegion, req);
156    req->reqType = info->codes->major_opcode;
157    req->xfixesReqType = X_XFixesSetRegion;
158    req->region = region;
159    len = ((long) nrectangles) << 1;
160    SetReqLen (req, len, len);
161    len <<= 2;
162    Data16 (dpy, (short *) rectangles, len);
163    UnlockDisplay (dpy);
164    SyncHandle();
165}
166
167void
168XFixesCopyRegion (Display *dpy, XserverRegion dst, XserverRegion src)
169{
170    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
171    xXFixesCopyRegionReq	*req;
172
173    XFixesSimpleCheckExtension (dpy, info);
174    LockDisplay (dpy);
175    GetReq (XFixesCopyRegion, req);
176    req->reqType = info->codes->major_opcode;
177    req->xfixesReqType = X_XFixesCopyRegion;
178    req->source = src;
179    req->destination = dst;
180    UnlockDisplay (dpy);
181    SyncHandle();
182}
183
184void
185XFixesUnionRegion (Display *dpy, XserverRegion dst,
186		   XserverRegion src1, XserverRegion src2)
187{
188    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
189    xXFixesUnionRegionReq	*req;
190
191    XFixesSimpleCheckExtension (dpy, info);
192    LockDisplay (dpy);
193    GetReq (XFixesUnionRegion, req);
194    req->reqType = info->codes->major_opcode;
195    req->xfixesReqType = X_XFixesUnionRegion;
196    req->source1 = src1;
197    req->source2 = src2;
198    req->destination = dst;
199    UnlockDisplay (dpy);
200    SyncHandle();
201}
202
203void
204XFixesIntersectRegion (Display *dpy, XserverRegion dst,
205		       XserverRegion src1, XserverRegion src2)
206{
207    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
208    xXFixesIntersectRegionReq	*req;
209
210    XFixesSimpleCheckExtension (dpy, info);
211    LockDisplay (dpy);
212    GetReq (XFixesIntersectRegion, req);
213    req->reqType = info->codes->major_opcode;
214    req->xfixesReqType = X_XFixesIntersectRegion;
215    req->source1 = src1;
216    req->source2 = src2;
217    req->destination = dst;
218    UnlockDisplay (dpy);
219    SyncHandle();
220}
221
222void
223XFixesSubtractRegion (Display *dpy, XserverRegion dst,
224		      XserverRegion src1, XserverRegion src2)
225{
226    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
227    xXFixesSubtractRegionReq	*req;
228
229    XFixesSimpleCheckExtension (dpy, info);
230    LockDisplay (dpy);
231    GetReq (XFixesSubtractRegion, req);
232    req->reqType = info->codes->major_opcode;
233    req->xfixesReqType = X_XFixesSubtractRegion;
234    req->source1 = src1;
235    req->source2 = src2;
236    req->destination = dst;
237    UnlockDisplay (dpy);
238    SyncHandle();
239}
240
241void
242XFixesInvertRegion (Display *dpy, XserverRegion dst,
243		    XRectangle *rect, XserverRegion src)
244{
245    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
246    xXFixesInvertRegionReq	*req;
247
248    XFixesSimpleCheckExtension (dpy, info);
249    LockDisplay (dpy);
250    GetReq (XFixesInvertRegion, req);
251    req->reqType = info->codes->major_opcode;
252    req->xfixesReqType = X_XFixesInvertRegion;
253    req->x = rect->x;
254    req->y = rect->y;
255    req->width = rect->width;
256    req->height = rect->height;
257    req->source = src;
258    req->destination = dst;
259    UnlockDisplay (dpy);
260    SyncHandle();
261}
262
263void
264XFixesTranslateRegion (Display *dpy, XserverRegion region, int dx, int dy)
265{
266    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
267    xXFixesTranslateRegionReq	*req;
268
269    XFixesSimpleCheckExtension (dpy, info);
270    LockDisplay (dpy);
271    GetReq (XFixesTranslateRegion, req);
272    req->reqType = info->codes->major_opcode;
273    req->xfixesReqType = X_XFixesTranslateRegion;
274    req->region = region;
275    req->dx = dx;
276    req->dy = dy;
277    UnlockDisplay (dpy);
278    SyncHandle();
279}
280
281void
282XFixesRegionExtents (Display *dpy, XserverRegion dst, XserverRegion src)
283{
284    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
285    xXFixesRegionExtentsReq	*req;
286
287    XFixesSimpleCheckExtension (dpy, info);
288    LockDisplay (dpy);
289    GetReq (XFixesRegionExtents, req);
290    req->reqType = info->codes->major_opcode;
291    req->xfixesReqType = X_XFixesRegionExtents;
292    req->source = src;
293    req->destination = dst;
294    UnlockDisplay (dpy);
295    SyncHandle();
296}
297
298XRectangle *
299XFixesFetchRegion (Display *dpy, XserverRegion region, int *nrectanglesRet)
300{
301    XRectangle	bounds;
302
303    return XFixesFetchRegionAndBounds (dpy, region, nrectanglesRet, &bounds);
304}
305
306XRectangle *
307XFixesFetchRegionAndBounds (Display	    *dpy,
308			    XserverRegion   region,
309			    int		    *nrectanglesRet,
310			    XRectangle	    *bounds)
311{
312    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
313    xXFixesFetchRegionReq	*req;
314    xXFixesFetchRegionReply	rep;
315    XRectangle			*rects;
316    int    			nrects;
317    long    			nbytes;
318    long			nread;
319
320    XFixesCheckExtension (dpy, info, NULL);
321    LockDisplay (dpy);
322    GetReq (XFixesFetchRegion, req);
323    req->reqType = info->codes->major_opcode;
324    req->xfixesReqType = X_XFixesFetchRegion;
325    req->region = region;
326    *nrectanglesRet = 0;
327    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
328    {
329	UnlockDisplay (dpy);
330	SyncHandle ();
331	return NULL;
332    }
333    bounds->x = rep.x;
334    bounds->y = rep.y;
335    bounds->width = rep.width;
336    bounds->height = rep.height;
337
338    if (rep.length < (INT_MAX >> 2)) {
339	nbytes = (long) rep.length << 2;
340	nrects = rep.length >> 1;
341	rects = Xmalloc (nrects * sizeof (XRectangle));
342    } else {
343	nbytes = 0;
344	nrects = 0;
345	rects = NULL;
346    }
347
348    if (!rects)
349    {
350	_XEatDataWords(dpy, rep.length);
351	UnlockDisplay (dpy);
352	SyncHandle ();
353	return NULL;
354    }
355    nread = nrects << 3;
356    _XRead16 (dpy, (short *) rects, nread);
357    /* skip any padding */
358    if(nbytes > nread)
359    {
360	_XEatData (dpy, (unsigned long) (nbytes - nread));
361    }
362    UnlockDisplay (dpy);
363    SyncHandle();
364    *nrectanglesRet = nrects;
365    return rects;
366}
367
368void
369XFixesSetGCClipRegion (Display *dpy, GC gc,
370		       int clip_x_origin, int clip_y_origin,
371		       XserverRegion region)
372{
373    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
374    xXFixesSetGCClipRegionReq	    *req;
375
376    XFixesSimpleCheckExtension (dpy, info);
377    LockDisplay (dpy);
378    GetReq (XFixesSetGCClipRegion, req);
379    req->reqType = info->codes->major_opcode;
380    req->xfixesReqType = X_XFixesSetGCClipRegion;
381    req->gc = gc->gid;
382    req->region = region;
383    req->xOrigin = clip_x_origin;
384    req->yOrigin = clip_y_origin;
385    UnlockDisplay (dpy);
386    SyncHandle();
387}
388
389void
390XFixesSetWindowShapeRegion (Display *dpy, Window win, int shape_kind,
391			    int x_off, int y_off, XserverRegion region)
392{
393    XFixesExtDisplayInfo	    *info = XFixesFindDisplay (dpy);
394    xXFixesSetWindowShapeRegionReq  *req;
395
396    XFixesSimpleCheckExtension (dpy, info);
397    LockDisplay (dpy);
398    GetReq (XFixesSetWindowShapeRegion, req);
399    req->reqType = info->codes->major_opcode;
400    req->xfixesReqType = X_XFixesSetWindowShapeRegion;
401    req->dest = win;
402    req->destKind = shape_kind;
403    req->xOff = x_off;
404    req->yOff = y_off;
405    req->region = region;
406    UnlockDisplay (dpy);
407    SyncHandle();
408}
409
410void
411XFixesSetPictureClipRegion (Display *dpy, XID picture,
412			    int clip_x_origin, int clip_y_origin,
413			    XserverRegion region)
414{
415    XFixesExtDisplayInfo	    *info = XFixesFindDisplay (dpy);
416    xXFixesSetPictureClipRegionReq  *req;
417
418    XFixesSimpleCheckExtension (dpy, info);
419    LockDisplay (dpy);
420    GetReq (XFixesSetPictureClipRegion, req);
421    req->reqType = info->codes->major_opcode;
422    req->xfixesReqType = X_XFixesSetPictureClipRegion;
423    req->picture = picture;
424    req->region = region;
425    req->xOrigin = clip_x_origin;
426    req->yOrigin = clip_y_origin;
427    UnlockDisplay (dpy);
428    SyncHandle();
429}
430
431void
432XFixesExpandRegion (Display *dpy, XserverRegion dst, XserverRegion src,
433		    unsigned left, unsigned right,
434		    unsigned top, unsigned bottom)
435{
436    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
437    xXFixesExpandRegionReq	*req;
438
439    XFixesSimpleCheckExtension (dpy, info);
440    LockDisplay (dpy);
441    GetReq (XFixesExpandRegion, req);
442    req->reqType = info->codes->major_opcode;
443    req->xfixesReqType = X_XFixesExpandRegion;
444    req->source = src;
445    req->destination = dst;
446    req->left = left;
447    req->right = right;
448    req->top = top;
449    req->bottom = bottom;
450    UnlockDisplay (dpy);
451    SyncHandle();
452}
453
454