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