region.c revision 4642e01f
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_DIX_CONFIG_H 24#include <dix-config.h> 25#endif 26 27#include "xfixesint.h" 28#include "scrnintstr.h" 29#ifdef RENDER 30#include <picturestr.h> 31extern int RenderErrBase; 32#endif 33#include <regionstr.h> 34#include <gcstruct.h> 35#include <window.h> 36 37RESTYPE RegionResType; 38 39static int 40RegionResFree (pointer data, XID id) 41{ 42 RegionPtr pRegion = (RegionPtr) data; 43 44 REGION_DESTROY (0, pRegion); 45 return Success; 46} 47 48RegionPtr 49XFixesRegionCopy (RegionPtr pRegion) 50{ 51 RegionPtr pNew = REGION_CREATE (0, REGION_EXTENTS(0, pRegion), 52 REGION_NUM_RECTS(pRegion)); 53 if (!pNew) 54 return 0; 55 if (!REGION_COPY (0, pNew, pRegion)) 56 { 57 REGION_DESTROY (0, pNew); 58 return 0; 59 } 60 return pNew; 61} 62 63Bool 64XFixesRegionInit (void) 65{ 66 RegionResType = CreateNewResourceType(RegionResFree); 67 return TRUE; 68} 69 70int 71ProcXFixesCreateRegion (ClientPtr client) 72{ 73 int things; 74 RegionPtr pRegion; 75 REQUEST (xXFixesCreateRegionReq); 76 77 REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq); 78 LEGAL_NEW_RESOURCE (stuff->region, client); 79 80 things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq); 81 if (things & 4) 82 return BadLength; 83 things >>= 3; 84 85 pRegion = RECTS_TO_REGION(0, things, (xRectangle *) (stuff + 1), CT_UNSORTED); 86 if (!pRegion) 87 return BadAlloc; 88 if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) 89 return BadAlloc; 90 91 return(client->noClientException); 92} 93 94int 95SProcXFixesCreateRegion (ClientPtr client) 96{ 97 register int n; 98 REQUEST(xXFixesCreateRegionReq); 99 100 swaps(&stuff->length, n); 101 REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq); 102 swapl(&stuff->region, n); 103 SwapRestS(stuff); 104 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 105} 106 107int 108ProcXFixesCreateRegionFromBitmap (ClientPtr client) 109{ 110 RegionPtr pRegion; 111 PixmapPtr pPixmap; 112 int rc; 113 REQUEST (xXFixesCreateRegionFromBitmapReq); 114 115 REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq); 116 LEGAL_NEW_RESOURCE (stuff->region, client); 117 118 rc = dixLookupResource((pointer *)&pPixmap, stuff->bitmap, RT_PIXMAP, 119 client, DixReadAccess); 120 if (rc != Success) 121 { 122 client->errorValue = stuff->bitmap; 123 return (rc == BadValue) ? BadPixmap : rc; 124 } 125 if (pPixmap->drawable.depth != 1) 126 return BadMatch; 127 128 pRegion = BITMAP_TO_REGION(pPixmap->drawable.pScreen, pPixmap); 129 130 if (!pRegion) 131 return BadAlloc; 132 133 if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) 134 return BadAlloc; 135 136 return(client->noClientException); 137} 138 139int 140SProcXFixesCreateRegionFromBitmap (ClientPtr client) 141{ 142 int n; 143 REQUEST (xXFixesCreateRegionFromBitmapReq); 144 145 swaps(&stuff->length, n); 146 REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq); 147 swapl(&stuff->region, n); 148 swapl(&stuff->bitmap, n); 149 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 150} 151 152int 153ProcXFixesCreateRegionFromWindow (ClientPtr client) 154{ 155 RegionPtr pRegion; 156 Bool copy = TRUE; 157 WindowPtr pWin; 158 int rc; 159 REQUEST (xXFixesCreateRegionFromWindowReq); 160 161 REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq); 162 LEGAL_NEW_RESOURCE (stuff->region, client); 163 rc = dixLookupResource((pointer *)&pWin, stuff->window, RT_WINDOW, 164 client, DixGetAttrAccess); 165 if (rc != Success) 166 { 167 client->errorValue = stuff->window; 168 return (rc == BadValue) ? BadWindow : rc; 169 } 170 switch (stuff->kind) { 171 case WindowRegionBounding: 172 pRegion = wBoundingShape(pWin); 173 if (!pRegion) 174 { 175 pRegion = CreateBoundingShape (pWin); 176 copy = FALSE; 177 } 178 break; 179 case WindowRegionClip: 180 pRegion = wClipShape(pWin); 181 if (!pRegion) 182 { 183 pRegion = CreateClipShape (pWin); 184 copy = FALSE; 185 } 186 break; 187 default: 188 client->errorValue = stuff->kind; 189 return BadValue; 190 } 191 if (copy && pRegion) 192 pRegion = XFixesRegionCopy (pRegion); 193 if (!pRegion) 194 return BadAlloc; 195 if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) 196 return BadAlloc; 197 198 return(client->noClientException); 199} 200 201int 202SProcXFixesCreateRegionFromWindow (ClientPtr client) 203{ 204 int n; 205 REQUEST (xXFixesCreateRegionFromWindowReq); 206 207 swaps(&stuff->length, n); 208 REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq); 209 swapl(&stuff->region, n); 210 swapl(&stuff->window, n); 211 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 212} 213 214int 215ProcXFixesCreateRegionFromGC (ClientPtr client) 216{ 217 RegionPtr pRegion, pClip; 218 GCPtr pGC; 219 int rc; 220 REQUEST (xXFixesCreateRegionFromGCReq); 221 222 REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq); 223 LEGAL_NEW_RESOURCE (stuff->region, client); 224 225 rc = dixLookupGC(&pGC, stuff->gc, client, DixGetAttrAccess); 226 if (rc != Success) 227 return rc; 228 229 switch (pGC->clientClipType) { 230 case CT_PIXMAP: 231 pRegion = BITMAP_TO_REGION(pGC->pScreen, (PixmapPtr) pGC->clientClip); 232 if (!pRegion) 233 return BadAlloc; 234 break; 235 case CT_REGION: 236 pClip = (RegionPtr) pGC->clientClip; 237 pRegion = XFixesRegionCopy (pClip); 238 if (!pRegion) 239 return BadAlloc; 240 break; 241 default: 242 return BadImplementation; /* assume sane server bits */ 243 } 244 245 if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) 246 return BadAlloc; 247 248 return(client->noClientException); 249} 250 251int 252SProcXFixesCreateRegionFromGC (ClientPtr client) 253{ 254 int n; 255 REQUEST (xXFixesCreateRegionFromGCReq); 256 257 swaps(&stuff->length, n); 258 REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq); 259 swapl(&stuff->region, n); 260 swapl(&stuff->gc, n); 261 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 262} 263 264int 265ProcXFixesCreateRegionFromPicture (ClientPtr client) 266{ 267#ifdef RENDER 268 RegionPtr pRegion; 269 PicturePtr pPicture; 270 REQUEST (xXFixesCreateRegionFromPictureReq); 271 272 REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq); 273 LEGAL_NEW_RESOURCE (stuff->region, client); 274 275 VERIFY_PICTURE(pPicture, stuff->picture, client, DixGetAttrAccess, 276 RenderErrBase + BadPicture); 277 278 switch (pPicture->clientClipType) { 279 case CT_PIXMAP: 280 pRegion = BITMAP_TO_REGION(pPicture->pDrawable->pScreen, 281 (PixmapPtr) pPicture->clientClip); 282 if (!pRegion) 283 return BadAlloc; 284 break; 285 case CT_REGION: 286 pRegion = XFixesRegionCopy ((RegionPtr) pPicture->clientClip); 287 if (!pRegion) 288 return BadAlloc; 289 break; 290 default: 291 return BadImplementation; /* assume sane server bits */ 292 } 293 294 if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) 295 return BadAlloc; 296 297 return(client->noClientException); 298#else 299 return BadRequest; 300#endif 301} 302 303int 304SProcXFixesCreateRegionFromPicture (ClientPtr client) 305{ 306 int n; 307 REQUEST (xXFixesCreateRegionFromPictureReq); 308 309 swaps(&stuff->length, n); 310 REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq); 311 swapl(&stuff->region, n); 312 swapl(&stuff->picture, n); 313 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 314} 315 316int 317ProcXFixesDestroyRegion (ClientPtr client) 318{ 319 REQUEST (xXFixesDestroyRegionReq); 320 RegionPtr pRegion; 321 322 REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq); 323 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); 324 FreeResource (stuff->region, RT_NONE); 325 return(client->noClientException); 326} 327 328int 329SProcXFixesDestroyRegion (ClientPtr client) 330{ 331 int n; 332 REQUEST (xXFixesDestroyRegionReq); 333 334 swaps (&stuff->length, n); 335 REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq); 336 swapl (&stuff->region, n); 337 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 338} 339 340int 341ProcXFixesSetRegion (ClientPtr client) 342{ 343 int things; 344 RegionPtr pRegion, pNew; 345 REQUEST (xXFixesSetRegionReq); 346 347 REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); 348 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); 349 350 things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq); 351 if (things & 4) 352 return BadLength; 353 things >>= 3; 354 355 pNew = RECTS_TO_REGION(0, things, (xRectangle *) (stuff + 1), CT_UNSORTED); 356 if (!pNew) 357 return BadAlloc; 358 if (!REGION_COPY (0, pRegion, pNew)) 359 { 360 REGION_DESTROY (0, pNew); 361 return BadAlloc; 362 } 363 REGION_DESTROY (0, pNew); 364 return(client->noClientException); 365} 366 367int 368SProcXFixesSetRegion (ClientPtr client) 369{ 370 int n; 371 REQUEST (xXFixesSetRegionReq); 372 373 swaps (&stuff->length, n); 374 REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); 375 swapl (&stuff->region, n); 376 SwapRestS(stuff); 377 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 378} 379 380int 381ProcXFixesCopyRegion (ClientPtr client) 382{ 383 RegionPtr pSource, pDestination; 384 REQUEST (xXFixesCopyRegionReq); 385 386 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); 387 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 388 389 if (!REGION_COPY(pScreen, pDestination, pSource)) 390 return BadAlloc; 391 392 return(client->noClientException); 393} 394 395int 396SProcXFixesCopyRegion (ClientPtr client) 397{ 398 int n; 399 REQUEST (xXFixesCopyRegionReq); 400 401 swaps (&stuff->length, n); 402 REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq); 403 swapl (&stuff->source, n); 404 swapl (&stuff->destination, n); 405 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 406} 407 408int 409ProcXFixesCombineRegion (ClientPtr client) 410{ 411 RegionPtr pSource1, pSource2, pDestination; 412 int ret = Success; 413 REQUEST (xXFixesCombineRegionReq); 414 415 REQUEST_SIZE_MATCH (xXFixesCombineRegionReq); 416 VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess); 417 VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess); 418 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 419 420 switch (stuff->xfixesReqType) { 421 case X_XFixesUnionRegion: 422 if (!REGION_UNION (0, pDestination, pSource1, pSource2)) 423 ret = BadAlloc; 424 break; 425 case X_XFixesIntersectRegion: 426 if (!REGION_INTERSECT (0, pDestination, pSource1, pSource2)) 427 ret = BadAlloc; 428 break; 429 case X_XFixesSubtractRegion: 430 if (!REGION_SUBTRACT (0, pDestination, pSource1, pSource2)) 431 ret = BadAlloc; 432 break; 433 } 434 435 if (ret == Success) 436 ret = client->noClientException; 437 return ret; 438} 439 440int 441SProcXFixesCombineRegion (ClientPtr client) 442{ 443 int n; 444 REQUEST (xXFixesCombineRegionReq); 445 446 swaps (&stuff->length, n); 447 REQUEST_SIZE_MATCH (xXFixesCombineRegionReq); 448 swapl (&stuff->source1, n); 449 swapl (&stuff->source2, n); 450 swapl (&stuff->destination, n); 451 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 452} 453 454int 455ProcXFixesInvertRegion (ClientPtr client) 456{ 457 RegionPtr pSource, pDestination; 458 BoxRec bounds; 459 int ret = Success; 460 REQUEST(xXFixesInvertRegionReq); 461 462 REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); 463 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); 464 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 465 466 /* Compute bounds, limit to 16 bits */ 467 bounds.x1 = stuff->x; 468 bounds.y1 = stuff->y; 469 if ((int) stuff->x + (int) stuff->width > MAXSHORT) 470 bounds.x2 = MAXSHORT; 471 else 472 bounds.x2 = stuff->x + stuff->width; 473 474 if ((int) stuff->y + (int) stuff->height > MAXSHORT) 475 bounds.y2 = MAXSHORT; 476 else 477 bounds.y2 = stuff->y + stuff->height; 478 479 if (!REGION_INVERSE(0, pDestination, pSource, &bounds)) 480 ret = BadAlloc; 481 482 if (ret == Success) 483 ret = client->noClientException; 484 return ret; 485} 486 487int 488SProcXFixesInvertRegion (ClientPtr client) 489{ 490 int n; 491 REQUEST(xXFixesInvertRegionReq); 492 493 swaps (&stuff->length, n); 494 REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); 495 swapl (&stuff->source, n); 496 swaps (&stuff->x, n); 497 swaps (&stuff->y, n); 498 swaps (&stuff->width, n); 499 swaps (&stuff->height, n); 500 swapl (&stuff->destination, n); 501 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 502} 503 504int 505ProcXFixesTranslateRegion (ClientPtr client) 506{ 507 RegionPtr pRegion; 508 REQUEST(xXFixesTranslateRegionReq); 509 510 REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); 511 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); 512 513 REGION_TRANSLATE(pScreen, pRegion, stuff->dx, stuff->dy); 514 return (client->noClientException); 515} 516 517int 518SProcXFixesTranslateRegion (ClientPtr client) 519{ 520 int n; 521 REQUEST(xXFixesTranslateRegionReq); 522 523 swaps (&stuff->length, n); 524 REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); 525 swapl (&stuff->region, n); 526 swaps (&stuff->dx, n); 527 swaps (&stuff->dy, n); 528 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 529} 530 531int 532ProcXFixesRegionExtents (ClientPtr client) 533{ 534 RegionPtr pSource, pDestination; 535 REQUEST(xXFixesRegionExtentsReq); 536 537 REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); 538 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); 539 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 540 541 REGION_RESET (0, pDestination, REGION_EXTENTS (0, pSource)); 542 543 return (client->noClientException); 544} 545 546int 547SProcXFixesRegionExtents (ClientPtr client) 548{ 549 int n; 550 REQUEST(xXFixesRegionExtentsReq); 551 552 swaps (&stuff->length, n); 553 REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); 554 swapl (&stuff->source, n); 555 swapl (&stuff->destination, n); 556 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 557} 558 559int 560ProcXFixesFetchRegion (ClientPtr client) 561{ 562 RegionPtr pRegion; 563 xXFixesFetchRegionReply *reply; 564 xRectangle *pRect; 565 BoxPtr pExtent; 566 BoxPtr pBox; 567 int i, nBox; 568 REQUEST(xXFixesFetchRegionReq); 569 570 REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); 571 VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); 572 573 pExtent = REGION_EXTENTS (0, pRegion); 574 pBox = REGION_RECTS (pRegion); 575 nBox = REGION_NUM_RECTS (pRegion); 576 577 reply = xalloc (sizeof (xXFixesFetchRegionReply) + 578 nBox * sizeof (xRectangle)); 579 if (!reply) 580 return BadAlloc; 581 reply->type = X_Reply; 582 reply->sequenceNumber = client->sequence; 583 reply->length = nBox << 1; 584 reply->x = pExtent->x1; 585 reply->y = pExtent->y1; 586 reply->width = pExtent->x2 - pExtent->x1; 587 reply->height = pExtent->y2 - pExtent->y1; 588 589 pRect = (xRectangle *) (reply + 1); 590 for (i = 0; i < nBox; i++) 591 { 592 pRect[i].x = pBox[i].x1; 593 pRect[i].y = pBox[i].y1; 594 pRect[i].width = pBox[i].x2 - pBox[i].x1; 595 pRect[i].height = pBox[i].y2 - pBox[i].y1; 596 } 597 if (client->swapped) 598 { 599 int n; 600 swaps (&reply->sequenceNumber, n); 601 swapl (&reply->length, n); 602 swaps (&reply->x, n); 603 swaps (&reply->y, n); 604 swaps (&reply->width, n); 605 swaps (&reply->height, n); 606 SwapShorts ((INT16 *) pRect, nBox * 4); 607 } 608 (void) WriteToClient(client, sizeof (xXFixesFetchRegionReply) + 609 nBox * sizeof (xRectangle), (char *) reply); 610 xfree (reply); 611 return (client->noClientException); 612} 613 614int 615SProcXFixesFetchRegion (ClientPtr client) 616{ 617 int n; 618 REQUEST(xXFixesFetchRegionReq); 619 620 swaps (&stuff->length, n); 621 REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); 622 swapl (&stuff->region, n); 623 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 624} 625 626int 627ProcXFixesSetGCClipRegion (ClientPtr client) 628{ 629 GCPtr pGC; 630 RegionPtr pRegion; 631 XID vals[2]; 632 int rc; 633 REQUEST(xXFixesSetGCClipRegionReq); 634 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); 635 636 rc = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 637 if (rc != Success) 638 return rc; 639 640 VERIFY_REGION_OR_NONE (pRegion, stuff->region, client, DixReadAccess); 641 642 if (pRegion) 643 { 644 pRegion = XFixesRegionCopy (pRegion); 645 if (!pRegion) 646 return BadAlloc; 647 } 648 649 vals[0] = stuff->xOrigin; 650 vals[1] = stuff->yOrigin; 651 DoChangeGC (pGC, GCClipXOrigin|GCClipYOrigin, vals, 0); 652 (*pGC->funcs->ChangeClip)(pGC, pRegion ? CT_REGION : CT_NONE, (pointer)pRegion, 0); 653 654 return (client->noClientException); 655} 656 657int 658SProcXFixesSetGCClipRegion (ClientPtr client) 659{ 660 int n; 661 REQUEST(xXFixesSetGCClipRegionReq); 662 663 swaps (&stuff->length, n); 664 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); 665 swapl (&stuff->gc, n); 666 swapl (&stuff->region, n); 667 swaps (&stuff->xOrigin, n); 668 swaps (&stuff->yOrigin, n); 669 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 670} 671 672typedef RegionPtr (*CreateDftPtr)(WindowPtr pWin); 673 674int 675ProcXFixesSetWindowShapeRegion (ClientPtr client) 676{ 677 WindowPtr pWin; 678 ScreenPtr pScreen; 679 RegionPtr pRegion; 680 RegionPtr *pDestRegion; 681 int rc; 682 REQUEST(xXFixesSetWindowShapeRegionReq); 683 684 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); 685 rc = dixLookupResource((pointer *)&pWin, stuff->dest, RT_WINDOW, 686 client, DixSetAttrAccess); 687 if (rc != Success) 688 { 689 client->errorValue = stuff->dest; 690 return (rc == BadValue) ? BadWindow : rc; 691 } 692 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess); 693 pScreen = pWin->drawable.pScreen; 694 switch (stuff->destKind) { 695 case ShapeBounding: 696 case ShapeClip: 697 case ShapeInput: 698 break; 699 default: 700 client->errorValue = stuff->destKind; 701 return BadValue; 702 } 703 if (pRegion) 704 { 705 pRegion = XFixesRegionCopy (pRegion); 706 if (!pRegion) 707 return BadAlloc; 708 if (!pWin->optional) 709 MakeWindowOptional (pWin); 710 switch (stuff->destKind) { 711 default: 712 case ShapeBounding: 713 pDestRegion = &pWin->optional->boundingShape; 714 break; 715 case ShapeClip: 716 pDestRegion = &pWin->optional->clipShape; 717 break; 718 case ShapeInput: 719 pDestRegion = &pWin->optional->inputShape; 720 break; 721 } 722 if (stuff->xOff || stuff->yOff) 723 REGION_TRANSLATE (0, pRegion, stuff->xOff, stuff->yOff); 724 } 725 else 726 { 727 if (pWin->optional) 728 { 729 switch (stuff->destKind) { 730 default: 731 case ShapeBounding: 732 pDestRegion = &pWin->optional->boundingShape; 733 break; 734 case ShapeClip: 735 pDestRegion = &pWin->optional->clipShape; 736 break; 737 case ShapeInput: 738 pDestRegion = &pWin->optional->inputShape; 739 break; 740 } 741 } 742 else 743 pDestRegion = &pRegion; /* a NULL region pointer */ 744 } 745 if (*pDestRegion) 746 REGION_DESTROY(pScreen, *pDestRegion); 747 *pDestRegion = pRegion; 748 (*pScreen->SetShape) (pWin); 749 SendShapeNotify (pWin, stuff->destKind); 750 return (client->noClientException); 751} 752 753int 754SProcXFixesSetWindowShapeRegion (ClientPtr client) 755{ 756 int n; 757 REQUEST(xXFixesSetWindowShapeRegionReq); 758 759 swaps (&stuff->length, n); 760 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); 761 swapl (&stuff->dest, n); 762 swaps (&stuff->xOff, n); 763 swaps (&stuff->yOff, n); 764 swapl (&stuff->region, n); 765 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 766} 767 768int 769ProcXFixesSetPictureClipRegion (ClientPtr client) 770{ 771#ifdef RENDER 772 PicturePtr pPicture; 773 RegionPtr pRegion; 774 ScreenPtr pScreen; 775 PictureScreenPtr ps; 776 REQUEST(xXFixesSetPictureClipRegionReq); 777 778 REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq); 779 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess, 780 RenderErrBase + BadPicture); 781 pScreen = pPicture->pDrawable->pScreen; 782 ps = GetPictureScreen (pScreen); 783 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); 784 785 return SetPictureClipRegion (pPicture, stuff->xOrigin, stuff->yOrigin, 786 pRegion); 787#else 788 return BadRequest; 789#endif 790} 791 792int 793SProcXFixesSetPictureClipRegion (ClientPtr client) 794{ 795 int n; 796 REQUEST(xXFixesSetPictureClipRegionReq); 797 798 swaps (&stuff->length, n); 799 REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq); 800 swapl (&stuff->picture, n); 801 swapl (&stuff->region, n); 802 swaps (&stuff->xOrigin, n); 803 swaps (&stuff->yOrigin, n); 804 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 805} 806 807int 808ProcXFixesExpandRegion (ClientPtr client) 809{ 810 RegionPtr pSource, pDestination; 811 int ret = Success; 812 REQUEST (xXFixesExpandRegionReq); 813 BoxPtr pTmp; 814 BoxPtr pSrc; 815 int nBoxes; 816 int i; 817 818 REQUEST_SIZE_MATCH (xXFixesExpandRegionReq); 819 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); 820 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 821 822 nBoxes = REGION_NUM_RECTS(pSource); 823 pSrc = REGION_RECTS(pSource); 824 if (nBoxes) 825 { 826 pTmp = xalloc (nBoxes * sizeof (BoxRec)); 827 if (!pTmp) 828 return BadAlloc; 829 for (i = 0; i < nBoxes; i++) 830 { 831 pTmp[i].x1 = pSrc[i].x1 - stuff->left; 832 pTmp[i].x2 = pSrc[i].x2 + stuff->right; 833 pTmp[i].y1 = pSrc[i].y1 - stuff->top; 834 pTmp[i].y2 = pSrc[i].y2 + stuff->bottom; 835 } 836 REGION_EMPTY (pScreen, pDestination); 837 for (i = 0; i < nBoxes; i++) 838 { 839 RegionRec r; 840 REGION_INIT (pScreen, &r, &pTmp[i], 0); 841 REGION_UNION (pScreen, pDestination, pDestination, &r); 842 } 843 xfree(pTmp); 844 } 845 if (ret == Success) 846 ret = client->noClientException; 847 return ret; 848} 849 850int 851SProcXFixesExpandRegion (ClientPtr client) 852{ 853 int n; 854 REQUEST (xXFixesExpandRegionReq); 855 856 swaps (&stuff->length, n); 857 REQUEST_SIZE_MATCH (xXFixesExpandRegionReq); 858 swapl (&stuff->source, n); 859 swapl (&stuff->destination, n); 860 swaps (&stuff->left, n); 861 swaps (&stuff->right, n); 862 swaps (&stuff->top, n); 863 swaps (&stuff->bottom, n); 864 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 865} 866 867