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