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