XShape.c revision e8a5466a
1/* 2 * 3Copyright 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 * 25 * Author: Keith Packard, MIT X Consortium 26 */ 27 28#ifdef HAVE_CONFIG_H 29#include <config.h> 30#endif 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> 38 39static XExtensionInfo _shape_info_data; 40static XExtensionInfo *shape_info = &_shape_info_data; 41static /* const */ char *shape_extension_name = SHAPENAME; 42 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) 47 48 49/***************************************************************************** 50 * * 51 * private utility routines * 52 * * 53 *****************************************************************************/ 54 55static int close_display(Display *dpy, XExtCodes *codes); 56static Bool wire_to_event (Display *dpy, XEvent *re, xEvent *event); 57static Status event_to_wire (Display *dpy, XEvent *re, xEvent *event); 58static /* const */ XExtensionHooks shape_extension_hooks = { 59 NULL, /* create_gc */ 60 NULL, /* copy_gc */ 61 NULL, /* flush_gc */ 62 NULL, /* free_gc */ 63 NULL, /* create_font */ 64 NULL, /* free_font */ 65 close_display, /* close_display */ 66 wire_to_event, /* wire_to_event */ 67 event_to_wire, /* event_to_wire */ 68 NULL, /* error */ 69 NULL, /* error_string */ 70}; 71 72static XEXT_GENERATE_FIND_DISPLAY (find_display, shape_info, 73 shape_extension_name, 74 &shape_extension_hooks, 75 ShapeNumberEvents, NULL) 76 77static XEXT_GENERATE_CLOSE_DISPLAY (close_display, shape_info) 78 79 80static Bool 81wire_to_event (Display *dpy, XEvent *re, xEvent *event) 82{ 83 XExtDisplayInfo *info = find_display (dpy); 84 XShapeEvent *se; 85 xShapeNotifyEvent *sevent; 86 87 ShapeCheckExtension (dpy, info, False); 88 89 switch ((event->u.u.type & 0x7f) - info->codes->first_event) { 90 case ShapeNotify: 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; 96 se->display = dpy; 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; 104 se->shaped = True; 105 if (sevent->shaped == xFalse) 106 se->shaped = False; 107 return True; 108 } 109 return False; 110} 111 112static Status 113event_to_wire (Display *dpy, XEvent *re, xEvent *event) 114{ 115 XExtDisplayInfo *info = find_display (dpy); 116 XShapeEvent *se; 117 xShapeNotifyEvent *sevent; 118 119 ShapeCheckExtension (dpy, info, 0); 120 121 switch ((re->type & 0x7f) - info->codes->first_event) { 122 case ShapeNotify: 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; 129 sevent->x = se->x; 130 sevent->y = se->y; 131 sevent->width = se->width; 132 sevent->height = se->height; 133 sevent->time = se->time; 134 return 1; 135 } 136 return 0; 137} 138 139 140/**************************************************************************** 141 * * 142 * Shape public interfaces * 143 * * 144 ****************************************************************************/ 145 146Bool XShapeQueryExtension (Display *dpy, int *event_basep, int *error_basep) 147{ 148 XExtDisplayInfo *info = find_display (dpy); 149 150 if (XextHasExtension(info)) { 151 *event_basep = info->codes->first_event; 152 *error_basep = info->codes->first_error; 153 return True; 154 } else { 155 return False; 156 } 157} 158 159 160Status XShapeQueryVersion( 161 Display *dpy, 162 int *major_versionp, 163 int *minor_versionp) 164{ 165 XExtDisplayInfo *info = find_display (dpy); 166 xShapeQueryVersionReply rep; 167 register xShapeQueryVersionReq *req; 168 169 ShapeCheckExtension (dpy, info, 0); 170 171 LockDisplay (dpy); 172 GetReq (ShapeQueryVersion, req); 173 req->reqType = info->codes->major_opcode; 174 req->shapeReqType = X_ShapeQueryVersion; 175 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 176 UnlockDisplay (dpy); 177 SyncHandle (); 178 return 0; 179 } 180 *major_versionp = rep.majorVersion; 181 *minor_versionp = rep.minorVersion; 182 UnlockDisplay (dpy); 183 SyncHandle (); 184 return 1; 185} 186 187void XShapeCombineRegion( 188 register Display *dpy, 189 Window dest, 190 int destKind, int xOff, int yOff, 191 register REGION *r, 192 int op) 193{ 194 XExtDisplayInfo *info = find_display (dpy); 195 register xShapeRectanglesReq *req; 196 register long nbytes; 197 register int i; 198 register XRectangle *xr, *pr; 199 register BOX *pb; 200 201 ShapeSimpleCheckExtension (dpy, info); 202 203 LockDisplay(dpy); 204 GetReq(ShapeRectangles, req); 205 xr = (XRectangle *) 206 _XAllocScratch(dpy, (unsigned long)(r->numRects * sizeof (XRectangle))); 207 for (pr = xr, pb = r->rects, i = r->numRects; --i >= 0; pr++, pb++) { 208 pr->x = pb->x1; 209 pr->y = pb->y1; 210 pr->width = pb->x2 - pb->x1; 211 pr->height = pb->y2 - pb->y1; 212 } 213 req->reqType = info->codes->major_opcode; 214 req->shapeReqType = X_ShapeRectangles; 215 req->op = op; 216 req->ordering = YXBanded; 217 req->destKind = destKind; 218 req->dest = dest; 219 req->xOff = xOff; 220 req->yOff = yOff; 221 222 /* SIZEOF(xRectangle) will be a multiple of 4 */ 223 req->length += r->numRects * (SIZEOF(xRectangle) / 4); 224 225 nbytes = r->numRects * sizeof(xRectangle); 226 227 Data16 (dpy, (short *) xr, nbytes); 228 UnlockDisplay(dpy); 229 SyncHandle(); 230} 231 232 233void XShapeCombineRectangles ( 234 register Display *dpy, 235 XID dest, 236 int destKind, int xOff, int yOff, 237 XRectangle *rects, 238 int n_rects, 239 int op, int ordering) 240{ 241 XExtDisplayInfo *info = find_display (dpy); 242 register xShapeRectanglesReq *req; 243 register long nbytes; 244 245 ShapeSimpleCheckExtension (dpy, info); 246 247 LockDisplay(dpy); 248 GetReq(ShapeRectangles, req); 249 req->reqType = info->codes->major_opcode; 250 req->shapeReqType = X_ShapeRectangles; 251 req->op = op; 252 req->ordering = ordering; 253 req->destKind = destKind; 254 req->dest = dest; 255 req->xOff = xOff; 256 req->yOff = yOff; 257 258 /* SIZEOF(xRectangle) will be a multiple of 4 */ 259 req->length += n_rects * (SIZEOF(xRectangle) / 4); 260 261 nbytes = n_rects * sizeof(xRectangle); 262 263 Data16 (dpy, (short *) rects, nbytes); 264 UnlockDisplay(dpy); 265 SyncHandle(); 266} 267 268 269void XShapeCombineMask ( 270 register Display *dpy, 271 XID dest, 272 int destKind, 273 int xOff, int yOff, 274 Pixmap src, 275 int op) 276{ 277 XExtDisplayInfo *info = find_display (dpy); 278 register xShapeMaskReq *req; 279 280 ShapeSimpleCheckExtension (dpy, info); 281 282 LockDisplay(dpy); 283 GetReq(ShapeMask, req); 284 req->reqType = info->codes->major_opcode; 285 req->shapeReqType = X_ShapeMask; 286 req->op = op; 287 req->destKind = destKind; 288 req->dest = dest; 289 req->xOff = xOff; 290 req->yOff = yOff; 291 req->src = src; 292 UnlockDisplay(dpy); 293 SyncHandle(); 294} 295 296void XShapeCombineShape ( 297 register Display *dpy, 298 XID dest, 299 int destKind, 300 int xOff, int yOff, 301 XID src, 302 int srcKind, 303 int op) 304{ 305 XExtDisplayInfo *info = find_display (dpy); 306 register xShapeCombineReq *req; 307 308 ShapeSimpleCheckExtension (dpy, info); 309 310 LockDisplay(dpy); 311 GetReq(ShapeCombine, req); 312 req->reqType = info->codes->major_opcode; 313 req->shapeReqType = X_ShapeCombine; 314 req->op = op; 315 req->destKind = destKind; 316 req->srcKind = srcKind; 317 req->dest = dest; 318 req->xOff = xOff; 319 req->yOff = yOff; 320 req->src = src; 321 UnlockDisplay(dpy); 322 SyncHandle(); 323} 324 325void XShapeOffsetShape ( 326 register Display *dpy, 327 XID dest, 328 int destKind, 329 int xOff, int yOff) 330{ 331 XExtDisplayInfo *info = find_display (dpy); 332 register xShapeOffsetReq *req; 333 334 ShapeSimpleCheckExtension (dpy, info); 335 336 LockDisplay(dpy); 337 GetReq(ShapeOffset, req); 338 req->reqType = info->codes->major_opcode; 339 req->shapeReqType = X_ShapeOffset; 340 req->destKind = destKind; 341 req->dest = dest; 342 req->xOff = xOff; 343 req->yOff = yOff; 344 UnlockDisplay(dpy); 345 SyncHandle(); 346} 347 348Status XShapeQueryExtents ( 349 register Display *dpy, 350 Window window, 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 */) 353{ 354 XExtDisplayInfo *info = find_display (dpy); 355 xShapeQueryExtentsReply rep; 356 register xShapeQueryExtentsReq *req; 357 358 ShapeCheckExtension (dpy, info, 0); 359 360 LockDisplay (dpy); 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)) { 366 UnlockDisplay (dpy); 367 SyncHandle (); 368 return 0; 369 } 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; 380 UnlockDisplay (dpy); 381 SyncHandle (); 382 return 1; 383} 384 385 386void XShapeSelectInput ( 387 register Display *dpy, 388 Window window, 389 unsigned long mask) 390{ 391 XExtDisplayInfo *info = find_display (dpy); 392 register xShapeSelectInputReq *req; 393 394 ShapeSimpleCheckExtension (dpy, info); 395 396 LockDisplay (dpy); 397 GetReq (ShapeSelectInput, req); 398 req->reqType = info->codes->major_opcode; 399 req->shapeReqType = X_ShapeSelectInput; 400 req->window = window; 401 if (mask & ShapeNotifyMask) 402 req->enable = xTrue; 403 else 404 req->enable = xFalse; 405 UnlockDisplay (dpy); 406 SyncHandle (); 407} 408 409unsigned long XShapeInputSelected (register Display *dpy, Window window) 410{ 411 XExtDisplayInfo *info = find_display (dpy); 412 register xShapeInputSelectedReq *req; 413 xShapeInputSelectedReply rep; 414 415 ShapeCheckExtension (dpy, info, False); 416 417 LockDisplay (dpy); 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)) { 423 UnlockDisplay (dpy); 424 SyncHandle (); 425 return False; 426 } 427 UnlockDisplay (dpy); 428 SyncHandle (); 429 return rep.enabled ? ShapeNotifyMask : 0L; 430} 431 432 433XRectangle *XShapeGetRectangles ( 434 register Display *dpy, 435 Window window, 436 int kind, 437 int *count, /* RETURN */ 438 int *ordering /* RETURN */) 439{ 440 XExtDisplayInfo *info = find_display (dpy); 441 register xShapeGetRectanglesReq *req; 442 xShapeGetRectanglesReply rep; 443 XRectangle *rects; 444 xRectangle *xrects; 445 int i; 446 447 ShapeCheckExtension (dpy, info, (XRectangle *)NULL); 448 449 LockDisplay (dpy); 450 GetReq (ShapeGetRectangles, req); 451 req->reqType = info->codes->major_opcode; 452 req->shapeReqType = X_ShapeGetRectangles; 453 req->window = window; 454 req->kind = kind; 455 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 456 UnlockDisplay (dpy); 457 SyncHandle (); 458 return (XRectangle *)NULL; 459 } 460 *count = rep.nrects; 461 *ordering = rep.ordering; 462 rects = NULL; 463 if (*count) { 464 xrects = (xRectangle *) Xmalloc (*count * sizeof (xRectangle)); 465 rects = (XRectangle *) Xmalloc (*count * sizeof (XRectangle)); 466 if (!xrects || !rects) { 467 if (xrects) 468 Xfree (xrects); 469 if (rects) 470 Xfree (rects); 471 _XEatData (dpy, *count * sizeof (xRectangle)); 472 rects = NULL; 473 *count = 0; 474 } else { 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; 481 } 482 Xfree (xrects); 483 } 484 } 485 UnlockDisplay (dpy); 486 SyncHandle (); 487 return rects; 488} 489