XShape.c revision af9a7ee5
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#include <limits.h> 39#include "eat.h" 40 41static XExtensionInfo _shape_info_data; 42static XExtensionInfo *shape_info = &_shape_info_data; 43static const char *shape_extension_name = SHAPENAME; 44 45#define ShapeCheckExtension(dpy,i,val) \ 46 XextCheckExtension (dpy, i, shape_extension_name, val) 47#define ShapeSimpleCheckExtension(dpy,i) \ 48 XextSimpleCheckExtension (dpy, i, shape_extension_name) 49 50 51/***************************************************************************** 52 * * 53 * private utility routines * 54 * * 55 *****************************************************************************/ 56 57static int close_display(Display *dpy, XExtCodes *codes); 58static Bool wire_to_event (Display *dpy, XEvent *re, xEvent *event); 59static Status event_to_wire (Display *dpy, XEvent *re, xEvent *event); 60static /* const */ XExtensionHooks shape_extension_hooks = { 61 NULL, /* create_gc */ 62 NULL, /* copy_gc */ 63 NULL, /* flush_gc */ 64 NULL, /* free_gc */ 65 NULL, /* create_font */ 66 NULL, /* free_font */ 67 close_display, /* close_display */ 68 wire_to_event, /* wire_to_event */ 69 event_to_wire, /* event_to_wire */ 70 NULL, /* error */ 71 NULL, /* error_string */ 72}; 73 74static XEXT_GENERATE_FIND_DISPLAY (find_display, shape_info, 75 shape_extension_name, 76 &shape_extension_hooks, 77 ShapeNumberEvents, NULL) 78 79static XEXT_GENERATE_CLOSE_DISPLAY (close_display, shape_info) 80 81 82static Bool 83wire_to_event (Display *dpy, XEvent *re, xEvent *event) 84{ 85 XExtDisplayInfo *info = find_display (dpy); 86 XShapeEvent *se; 87 xShapeNotifyEvent *sevent; 88 89 ShapeCheckExtension (dpy, info, False); 90 91 switch ((event->u.u.type & 0x7f) - info->codes->first_event) { 92 case ShapeNotify: 93 se = (XShapeEvent *) re; 94 sevent = (xShapeNotifyEvent *) event; 95 se->type = sevent->type & 0x7f; 96 se->serial = _XSetLastRequestRead(dpy,(xGenericReply *) event); 97 se->send_event = (sevent->type & 0x80) != 0; 98 se->display = dpy; 99 se->window = sevent->window; 100 se->kind = sevent->kind; 101 se->x = cvtINT16toInt (sevent->x); 102 se->y = cvtINT16toInt (sevent->y); 103 se->width = sevent->width; 104 se->height = sevent->height; 105 se->time = sevent->time; 106 se->shaped = True; 107 if (sevent->shaped == xFalse) 108 se->shaped = False; 109 return True; 110 } 111 return False; 112} 113 114static Status 115event_to_wire (Display *dpy, XEvent *re, xEvent *event) 116{ 117 XExtDisplayInfo *info = find_display (dpy); 118 XShapeEvent *se; 119 xShapeNotifyEvent *sevent; 120 121 ShapeCheckExtension (dpy, info, 0); 122 123 switch ((re->type & 0x7f) - info->codes->first_event) { 124 case ShapeNotify: 125 se = (XShapeEvent *) re; 126 sevent = (xShapeNotifyEvent *) event; 127 sevent->type = se->type | (se->send_event ? 0x80 : 0); 128 sevent->sequenceNumber = se->serial & 0xffff; 129 sevent->window = se->window; 130 sevent->kind = se->kind; 131 sevent->x = se->x; 132 sevent->y = se->y; 133 sevent->width = se->width; 134 sevent->height = se->height; 135 sevent->time = se->time; 136 return 1; 137 } 138 return 0; 139} 140 141 142/**************************************************************************** 143 * * 144 * Shape public interfaces * 145 * * 146 ****************************************************************************/ 147 148Bool XShapeQueryExtension (Display *dpy, int *event_basep, int *error_basep) 149{ 150 XExtDisplayInfo *info = find_display (dpy); 151 152 if (XextHasExtension(info)) { 153 *event_basep = info->codes->first_event; 154 *error_basep = info->codes->first_error; 155 return True; 156 } else { 157 return False; 158 } 159} 160 161 162Status XShapeQueryVersion( 163 Display *dpy, 164 int *major_versionp, 165 int *minor_versionp) 166{ 167 XExtDisplayInfo *info = find_display (dpy); 168 xShapeQueryVersionReply rep; 169 register xShapeQueryVersionReq *req; 170 171 ShapeCheckExtension (dpy, info, 0); 172 173 LockDisplay (dpy); 174 GetReq (ShapeQueryVersion, req); 175 req->reqType = info->codes->major_opcode; 176 req->shapeReqType = X_ShapeQueryVersion; 177 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 178 UnlockDisplay (dpy); 179 SyncHandle (); 180 return 0; 181 } 182 *major_versionp = rep.majorVersion; 183 *minor_versionp = rep.minorVersion; 184 UnlockDisplay (dpy); 185 SyncHandle (); 186 return 1; 187} 188 189void XShapeCombineRegion( 190 register Display *dpy, 191 Window dest, 192 int destKind, int xOff, int yOff, 193 register REGION *r, 194 int op) 195{ 196 XExtDisplayInfo *info = find_display (dpy); 197 register xShapeRectanglesReq *req; 198 register long nbytes; 199 register int i; 200 register XRectangle *xr, *pr; 201 register BOX *pb; 202 203 ShapeSimpleCheckExtension (dpy, info); 204 205 LockDisplay(dpy); 206 GetReq(ShapeRectangles, req); 207 xr = (XRectangle *) 208 _XAllocScratch(dpy, (unsigned long)(r->numRects * sizeof (XRectangle))); 209 for (pr = xr, pb = r->rects, i = r->numRects; --i >= 0; pr++, pb++) { 210 pr->x = pb->x1; 211 pr->y = pb->y1; 212 pr->width = pb->x2 - pb->x1; 213 pr->height = pb->y2 - pb->y1; 214 } 215 req->reqType = info->codes->major_opcode; 216 req->shapeReqType = X_ShapeRectangles; 217 req->op = op; 218 req->ordering = YXBanded; 219 req->destKind = destKind; 220 req->dest = dest; 221 req->xOff = xOff; 222 req->yOff = yOff; 223 224 /* SIZEOF(xRectangle) will be a multiple of 4 */ 225 req->length += r->numRects * (SIZEOF(xRectangle) / 4); 226 227 nbytes = r->numRects * sizeof(xRectangle); 228 229 Data16 (dpy, (short *) xr, nbytes); 230 UnlockDisplay(dpy); 231 SyncHandle(); 232} 233 234 235void XShapeCombineRectangles ( 236 register Display *dpy, 237 XID dest, 238 int destKind, int xOff, int yOff, 239 XRectangle *rects, 240 int n_rects, 241 int op, int ordering) 242{ 243 XExtDisplayInfo *info = find_display (dpy); 244 register xShapeRectanglesReq *req; 245 register long nbytes; 246 247 ShapeSimpleCheckExtension (dpy, info); 248 249 LockDisplay(dpy); 250 GetReq(ShapeRectangles, req); 251 req->reqType = info->codes->major_opcode; 252 req->shapeReqType = X_ShapeRectangles; 253 req->op = op; 254 req->ordering = ordering; 255 req->destKind = destKind; 256 req->dest = dest; 257 req->xOff = xOff; 258 req->yOff = yOff; 259 260 /* SIZEOF(xRectangle) will be a multiple of 4 */ 261 req->length += n_rects * (SIZEOF(xRectangle) / 4); 262 263 nbytes = n_rects * sizeof(xRectangle); 264 265 Data16 (dpy, (short *) rects, nbytes); 266 UnlockDisplay(dpy); 267 SyncHandle(); 268} 269 270 271void XShapeCombineMask ( 272 register Display *dpy, 273 XID dest, 274 int destKind, 275 int xOff, int yOff, 276 Pixmap src, 277 int op) 278{ 279 XExtDisplayInfo *info = find_display (dpy); 280 register xShapeMaskReq *req; 281 282 ShapeSimpleCheckExtension (dpy, info); 283 284 LockDisplay(dpy); 285 GetReq(ShapeMask, req); 286 req->reqType = info->codes->major_opcode; 287 req->shapeReqType = X_ShapeMask; 288 req->op = op; 289 req->destKind = destKind; 290 req->dest = dest; 291 req->xOff = xOff; 292 req->yOff = yOff; 293 req->src = src; 294 UnlockDisplay(dpy); 295 SyncHandle(); 296} 297 298void XShapeCombineShape ( 299 register Display *dpy, 300 XID dest, 301 int destKind, 302 int xOff, int yOff, 303 XID src, 304 int srcKind, 305 int op) 306{ 307 XExtDisplayInfo *info = find_display (dpy); 308 register xShapeCombineReq *req; 309 310 ShapeSimpleCheckExtension (dpy, info); 311 312 LockDisplay(dpy); 313 GetReq(ShapeCombine, req); 314 req->reqType = info->codes->major_opcode; 315 req->shapeReqType = X_ShapeCombine; 316 req->op = op; 317 req->destKind = destKind; 318 req->srcKind = srcKind; 319 req->dest = dest; 320 req->xOff = xOff; 321 req->yOff = yOff; 322 req->src = src; 323 UnlockDisplay(dpy); 324 SyncHandle(); 325} 326 327void XShapeOffsetShape ( 328 register Display *dpy, 329 XID dest, 330 int destKind, 331 int xOff, int yOff) 332{ 333 XExtDisplayInfo *info = find_display (dpy); 334 register xShapeOffsetReq *req; 335 336 ShapeSimpleCheckExtension (dpy, info); 337 338 LockDisplay(dpy); 339 GetReq(ShapeOffset, req); 340 req->reqType = info->codes->major_opcode; 341 req->shapeReqType = X_ShapeOffset; 342 req->destKind = destKind; 343 req->dest = dest; 344 req->xOff = xOff; 345 req->yOff = yOff; 346 UnlockDisplay(dpy); 347 SyncHandle(); 348} 349 350Status XShapeQueryExtents ( 351 register Display *dpy, 352 Window window, 353 int *bShaped, int *xbs, int *ybs, unsigned int *wbs, unsigned int *hbs, /* RETURN */ 354 int *cShaped, int *xcs, int *ycs, unsigned int *wcs, unsigned int *hcs /* RETURN */) 355{ 356 XExtDisplayInfo *info = find_display (dpy); 357 xShapeQueryExtentsReply rep; 358 register xShapeQueryExtentsReq *req; 359 360 ShapeCheckExtension (dpy, info, 0); 361 362 LockDisplay (dpy); 363 GetReq (ShapeQueryExtents, req); 364 req->reqType = info->codes->major_opcode; 365 req->shapeReqType = X_ShapeQueryExtents; 366 req->window = window; 367 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 368 UnlockDisplay (dpy); 369 SyncHandle (); 370 return 0; 371 } 372 *bShaped = rep.boundingShaped; 373 *cShaped = rep.clipShaped; 374 *xbs = cvtINT16toInt (rep.xBoundingShape); 375 *ybs = cvtINT16toInt (rep.yBoundingShape); 376 *wbs = rep.widthBoundingShape; 377 *hbs = rep.heightBoundingShape; 378 *xcs = cvtINT16toInt (rep.xClipShape); 379 *ycs = cvtINT16toInt (rep.yClipShape); 380 *wcs = rep.widthClipShape; 381 *hcs = rep.heightClipShape; 382 UnlockDisplay (dpy); 383 SyncHandle (); 384 return 1; 385} 386 387 388void XShapeSelectInput ( 389 register Display *dpy, 390 Window window, 391 unsigned long mask) 392{ 393 XExtDisplayInfo *info = find_display (dpy); 394 register xShapeSelectInputReq *req; 395 396 ShapeSimpleCheckExtension (dpy, info); 397 398 LockDisplay (dpy); 399 GetReq (ShapeSelectInput, req); 400 req->reqType = info->codes->major_opcode; 401 req->shapeReqType = X_ShapeSelectInput; 402 req->window = window; 403 if (mask & ShapeNotifyMask) 404 req->enable = xTrue; 405 else 406 req->enable = xFalse; 407 UnlockDisplay (dpy); 408 SyncHandle (); 409} 410 411unsigned long XShapeInputSelected (register Display *dpy, Window window) 412{ 413 XExtDisplayInfo *info = find_display (dpy); 414 register xShapeInputSelectedReq *req; 415 xShapeInputSelectedReply rep; 416 417 ShapeCheckExtension (dpy, info, False); 418 419 LockDisplay (dpy); 420 GetReq (ShapeInputSelected, req); 421 req->reqType = info->codes->major_opcode; 422 req->shapeReqType = X_ShapeInputSelected; 423 req->window = window; 424 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 425 UnlockDisplay (dpy); 426 SyncHandle (); 427 return False; 428 } 429 UnlockDisplay (dpy); 430 SyncHandle (); 431 return rep.enabled ? ShapeNotifyMask : 0L; 432} 433 434 435XRectangle *XShapeGetRectangles ( 436 register Display *dpy, 437 Window window, 438 int kind, 439 int *count, /* RETURN */ 440 int *ordering /* RETURN */) 441{ 442 XExtDisplayInfo *info = find_display (dpy); 443 register xShapeGetRectanglesReq *req; 444 xShapeGetRectanglesReply rep; 445 XRectangle *rects; 446 xRectangle *xrects; 447 unsigned int i; 448 449 ShapeCheckExtension (dpy, info, (XRectangle *)NULL); 450 451 LockDisplay (dpy); 452 GetReq (ShapeGetRectangles, req); 453 req->reqType = info->codes->major_opcode; 454 req->shapeReqType = X_ShapeGetRectangles; 455 req->window = window; 456 req->kind = kind; 457 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 458 UnlockDisplay (dpy); 459 SyncHandle (); 460 return (XRectangle *)NULL; 461 } 462 *count = rep.nrects; 463 *ordering = rep.ordering; 464 rects = NULL; 465 if (rep.nrects) { 466 if (rep.nrects < (INT_MAX / sizeof (XRectangle))) { 467 xrects = Xmalloc (rep.nrects * sizeof (xRectangle)); 468 rects = Xmalloc (rep.nrects * sizeof (XRectangle)); 469 } else { 470 xrects = NULL; 471 rects = NULL; 472 } 473 if (!xrects || !rects) { 474 Xfree (xrects); 475 Xfree (rects); 476 _XEatDataWords (dpy, rep.length); 477 rects = NULL; 478 *count = 0; 479 } else { 480 _XRead (dpy, (char *) xrects, rep.nrects * sizeof (xRectangle)); 481 for (i = 0; i < rep.nrects; i++) { 482 rects[i].x = (short) cvtINT16toInt (xrects[i].x); 483 rects[i].y = (short) cvtINT16toInt (xrects[i].y); 484 rects[i].width = xrects[i].width; 485 rects[i].height = xrects[i].height; 486 } 487 Xfree (xrects); 488 } 489 } 490 UnlockDisplay (dpy); 491 SyncHandle (); 492 return rects; 493} 494