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