3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 * Author: Keith Packard, MIT X Consortium
31 #include <X11/Xlibint.h>
32 #include <X11/Xutil.h>
33 #include <X11/Xregion.h>
34 #include <X11/extensions/Xext.h>
35 #include <X11/extensions/extutil.h>
36 #include <X11/extensions/shape.h>
37 #include <X11/extensions/shapeproto.h>
39 static XExtensionInfo _shape_info_data;
40 static XExtensionInfo *shape_info = &_shape_info_data;
41 static /* const */ char *shape_extension_name = SHAPENAME;
43 #define ShapeCheckExtension(dpy,i,val) \
44 XextCheckExtension (dpy, i, shape_extension_name, val)
45 #define ShapeSimpleCheckExtension(dpy,i) \
46 XextSimpleCheckExtension (dpy, i, shape_extension_name)
49 /*****************************************************************************
51 * private utility routines *
53 *****************************************************************************/
55 static int close_display(Display *dpy, XExtCodes *codes);
56 static Bool wire_to_event (Display *dpy, XEvent *re, xEvent *event);
57 static Status event_to_wire (Display *dpy, XEvent *re, xEvent *event);
58 static /* const */ XExtensionHooks shape_extension_hooks = {
63 NULL, /* create_font */
65 close_display, /* close_display */
66 wire_to_event, /* wire_to_event */
67 event_to_wire, /* event_to_wire */
69 NULL, /* error_string */
72 static XEXT_GENERATE_FIND_DISPLAY (find_display, shape_info,
74 &shape_extension_hooks,
75 ShapeNumberEvents, NULL)
77 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, shape_info)
81 wire_to_event (Display *dpy, XEvent *re, xEvent *event)
83 XExtDisplayInfo *info = find_display (dpy);
85 xShapeNotifyEvent *sevent;
87 ShapeCheckExtension (dpy, info, False);
89 switch ((event->u.u.type & 0x7f) - info->codes->first_event) {
91 se = (XShapeEvent *) re;
92 sevent = (xShapeNotifyEvent *) event;
93 se->type = sevent->type & 0x7f;
94 se->serial = _XSetLastRequestRead(dpy,(xGenericReply *) event);
95 se->send_event = (sevent->type & 0x80) != 0;
97 se->window = sevent->window;
98 se->kind = sevent->kind;
99 se->x = cvtINT16toInt (sevent->x);
100 se->y = cvtINT16toInt (sevent->y);
101 se->width = sevent->width;
102 se->height = sevent->height;
103 se->time = sevent->time;
105 if (sevent->shaped == xFalse)
113 event_to_wire (Display *dpy, XEvent *re, xEvent *event)
115 XExtDisplayInfo *info = find_display (dpy);
117 xShapeNotifyEvent *sevent;
119 ShapeCheckExtension (dpy, info, 0);
121 switch ((re->type & 0x7f) - info->codes->first_event) {
123 se = (XShapeEvent *) re;
124 sevent = (xShapeNotifyEvent *) event;
125 sevent->type = se->type | (se->send_event ? 0x80 : 0);
126 sevent->sequenceNumber = se->serial & 0xffff;
127 sevent->window = se->window;
128 sevent->kind = se->kind;
131 sevent->width = se->width;
132 sevent->height = se->height;
133 sevent->time = se->time;
140 /****************************************************************************
142 * Shape public interfaces *
144 ****************************************************************************/
146 Bool XShapeQueryExtension (Display *dpy, int *event_basep, int *error_basep)
148 XExtDisplayInfo *info = find_display (dpy);
150 if (XextHasExtension(info)) {
151 *event_basep = info->codes->first_event;
152 *error_basep = info->codes->first_error;
160 Status XShapeQueryVersion(
165 XExtDisplayInfo *info = find_display (dpy);
166 xShapeQueryVersionReply rep;
167 register xShapeQueryVersionReq *req;
169 ShapeCheckExtension (dpy, info, 0);
172 GetReq (ShapeQueryVersion, req);
173 req->reqType = info->codes->major_opcode;
174 req->shapeReqType = X_ShapeQueryVersion;
175 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
180 *major_versionp = rep.majorVersion;
181 *minor_versionp = rep.minorVersion;
187 void XShapeCombineRegion(
188 register Display *dpy,
190 int destKind, int xOff, int yOff,
194 XExtDisplayInfo *info = find_display (dpy);
195 register xShapeRectanglesReq *req;
196 register long nbytes;
198 register XRectangle *xr, *pr;
201 ShapeSimpleCheckExtension (dpy, info);
204 GetReq(ShapeRectangles, req);
206 _XAllocScratch(dpy, (unsigned long)(r->numRects * sizeof (XRectangle)));
207 for (pr = xr, pb = r->rects, i = r->numRects; --i >= 0; pr++, pb++) {
210 pr->width = pb->x2 - pb->x1;
211 pr->height = pb->y2 - pb->y1;
213 req->reqType = info->codes->major_opcode;
214 req->shapeReqType = X_ShapeRectangles;
216 req->ordering = YXBanded;
217 req->destKind = destKind;
222 /* SIZEOF(xRectangle) will be a multiple of 4 */
223 req->length += r->numRects * (SIZEOF(xRectangle) / 4);
225 nbytes = r->numRects * sizeof(xRectangle);
227 Data16 (dpy, (short *) xr, nbytes);
233 void XShapeCombineRectangles (
234 register Display *dpy,
236 int destKind, int xOff, int yOff,
239 int op, int ordering)
241 XExtDisplayInfo *info = find_display (dpy);
242 register xShapeRectanglesReq *req;
243 register long nbytes;
245 ShapeSimpleCheckExtension (dpy, info);
248 GetReq(ShapeRectangles, req);
249 req->reqType = info->codes->major_opcode;
250 req->shapeReqType = X_ShapeRectangles;
252 req->ordering = ordering;
253 req->destKind = destKind;
258 /* SIZEOF(xRectangle) will be a multiple of 4 */
259 req->length += n_rects * (SIZEOF(xRectangle) / 4);
261 nbytes = n_rects * sizeof(xRectangle);
263 Data16 (dpy, (short *) rects, nbytes);
269 void XShapeCombineMask (
270 register Display *dpy,
277 XExtDisplayInfo *info = find_display (dpy);
278 register xShapeMaskReq *req;
280 ShapeSimpleCheckExtension (dpy, info);
283 GetReq(ShapeMask, req);
284 req->reqType = info->codes->major_opcode;
285 req->shapeReqType = X_ShapeMask;
287 req->destKind = destKind;
296 void XShapeCombineShape (
297 register Display *dpy,
305 XExtDisplayInfo *info = find_display (dpy);
306 register xShapeCombineReq *req;
308 ShapeSimpleCheckExtension (dpy, info);
311 GetReq(ShapeCombine, req);
312 req->reqType = info->codes->major_opcode;
313 req->shapeReqType = X_ShapeCombine;
315 req->destKind = destKind;
316 req->srcKind = srcKind;
325 void XShapeOffsetShape (
326 register Display *dpy,
331 XExtDisplayInfo *info = find_display (dpy);
332 register xShapeOffsetReq *req;
334 ShapeSimpleCheckExtension (dpy, info);
337 GetReq(ShapeOffset, req);
338 req->reqType = info->codes->major_opcode;
339 req->shapeReqType = X_ShapeOffset;
340 req->destKind = destKind;
348 Status XShapeQueryExtents (
349 register Display *dpy,
351 int *bShaped, int *xbs, int *ybs, unsigned int *wbs, unsigned int *hbs, /* RETURN */
352 int *cShaped, int *xcs, int *ycs, unsigned int *wcs, unsigned int *hcs /* RETURN */)
354 XExtDisplayInfo *info = find_display (dpy);
355 xShapeQueryExtentsReply rep;
356 register xShapeQueryExtentsReq *req;
358 ShapeCheckExtension (dpy, info, 0);
361 GetReq (ShapeQueryExtents, req);
362 req->reqType = info->codes->major_opcode;
363 req->shapeReqType = X_ShapeQueryExtents;
364 req->window = window;
365 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
370 *bShaped = rep.boundingShaped;
371 *cShaped = rep.clipShaped;
372 *xbs = cvtINT16toInt (rep.xBoundingShape);
373 *ybs = cvtINT16toInt (rep.yBoundingShape);
374 *wbs = rep.widthBoundingShape;
375 *hbs = rep.heightBoundingShape;
376 *xcs = cvtINT16toInt (rep.xClipShape);
377 *ycs = cvtINT16toInt (rep.yClipShape);
378 *wcs = rep.widthClipShape;
379 *hcs = rep.heightClipShape;
386 void XShapeSelectInput (
387 register Display *dpy,
391 XExtDisplayInfo *info = find_display (dpy);
392 register xShapeSelectInputReq *req;
394 ShapeSimpleCheckExtension (dpy, info);
397 GetReq (ShapeSelectInput, req);
398 req->reqType = info->codes->major_opcode;
399 req->shapeReqType = X_ShapeSelectInput;
400 req->window = window;
401 if (mask & ShapeNotifyMask)
404 req->enable = xFalse;
409 unsigned long XShapeInputSelected (register Display *dpy, Window window)
411 XExtDisplayInfo *info = find_display (dpy);
412 register xShapeInputSelectedReq *req;
413 xShapeInputSelectedReply rep;
415 ShapeCheckExtension (dpy, info, False);
418 GetReq (ShapeInputSelected, req);
419 req->reqType = info->codes->major_opcode;
420 req->shapeReqType = X_ShapeInputSelected;
421 req->window = window;
422 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
429 return rep.enabled ? ShapeNotifyMask : 0L;
433 XRectangle *XShapeGetRectangles (
434 register Display *dpy,
437 int *count, /* RETURN */
438 int *ordering /* RETURN */)
440 XExtDisplayInfo *info = find_display (dpy);
441 register xShapeGetRectanglesReq *req;
442 xShapeGetRectanglesReply rep;
447 ShapeCheckExtension (dpy, info, (XRectangle *)NULL);
450 GetReq (ShapeGetRectangles, req);
451 req->reqType = info->codes->major_opcode;
452 req->shapeReqType = X_ShapeGetRectangles;
453 req->window = window;
455 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
458 return (XRectangle *)NULL;
461 *ordering = rep.ordering;
464 xrects = (xRectangle *) Xmalloc (*count * sizeof (xRectangle));
465 rects = (XRectangle *) Xmalloc (*count * sizeof (XRectangle));
466 if (!xrects || !rects) {
471 _XEatData (dpy, *count * sizeof (xRectangle));
475 _XRead (dpy, (char *) xrects, *count * sizeof (xRectangle));
476 for (i = 0; i < *count; i++) {
477 rects[i].x = (short) cvtINT16toInt (xrects[i].x);
478 rects[i].y = (short) cvtINT16toInt (xrects[i].y);
479 rects[i].width = xrects[i].width;
480 rects[i].height = xrects[i].height;