region.c revision 35c4bbdf
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 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 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 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 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 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 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 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 363 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); 364 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 365 366 if (!RegionCopy(pDestination, pSource)) 367 return BadAlloc; 368 369 return Success; 370} 371 372int 373SProcXFixesCopyRegion(ClientPtr client) 374{ 375 REQUEST(xXFixesCopyRegionReq); 376 377 swaps(&stuff->length); 378 REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq); 379 swapl(&stuff->source); 380 swapl(&stuff->destination); 381 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 382} 383 384int 385ProcXFixesCombineRegion(ClientPtr client) 386{ 387 RegionPtr pSource1, pSource2, pDestination; 388 389 REQUEST(xXFixesCombineRegionReq); 390 391 REQUEST_SIZE_MATCH(xXFixesCombineRegionReq); 392 VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess); 393 VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess); 394 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 395 396 switch (stuff->xfixesReqType) { 397 case X_XFixesUnionRegion: 398 if (!RegionUnion(pDestination, pSource1, pSource2)) 399 return BadAlloc; 400 break; 401 case X_XFixesIntersectRegion: 402 if (!RegionIntersect(pDestination, pSource1, pSource2)) 403 return BadAlloc; 404 break; 405 case X_XFixesSubtractRegion: 406 if (!RegionSubtract(pDestination, pSource1, pSource2)) 407 return BadAlloc; 408 break; 409 } 410 411 return Success; 412} 413 414int 415SProcXFixesCombineRegion(ClientPtr client) 416{ 417 REQUEST(xXFixesCombineRegionReq); 418 419 swaps(&stuff->length); 420 REQUEST_SIZE_MATCH(xXFixesCombineRegionReq); 421 swapl(&stuff->source1); 422 swapl(&stuff->source2); 423 swapl(&stuff->destination); 424 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 425} 426 427int 428ProcXFixesInvertRegion(ClientPtr client) 429{ 430 RegionPtr pSource, pDestination; 431 BoxRec bounds; 432 433 REQUEST(xXFixesInvertRegionReq); 434 435 REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); 436 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); 437 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 438 439 /* Compute bounds, limit to 16 bits */ 440 bounds.x1 = stuff->x; 441 bounds.y1 = stuff->y; 442 if ((int) stuff->x + (int) stuff->width > MAXSHORT) 443 bounds.x2 = MAXSHORT; 444 else 445 bounds.x2 = stuff->x + stuff->width; 446 447 if ((int) stuff->y + (int) stuff->height > MAXSHORT) 448 bounds.y2 = MAXSHORT; 449 else 450 bounds.y2 = stuff->y + stuff->height; 451 452 if (!RegionInverse(pDestination, pSource, &bounds)) 453 return BadAlloc; 454 455 return Success; 456} 457 458int 459SProcXFixesInvertRegion(ClientPtr client) 460{ 461 REQUEST(xXFixesInvertRegionReq); 462 463 swaps(&stuff->length); 464 REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); 465 swapl(&stuff->source); 466 swaps(&stuff->x); 467 swaps(&stuff->y); 468 swaps(&stuff->width); 469 swaps(&stuff->height); 470 swapl(&stuff->destination); 471 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 472} 473 474int 475ProcXFixesTranslateRegion(ClientPtr client) 476{ 477 RegionPtr pRegion; 478 479 REQUEST(xXFixesTranslateRegionReq); 480 481 REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); 482 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); 483 484 RegionTranslate(pRegion, stuff->dx, stuff->dy); 485 return Success; 486} 487 488int 489SProcXFixesTranslateRegion(ClientPtr client) 490{ 491 REQUEST(xXFixesTranslateRegionReq); 492 493 swaps(&stuff->length); 494 REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); 495 swapl(&stuff->region); 496 swaps(&stuff->dx); 497 swaps(&stuff->dy); 498 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 499} 500 501int 502ProcXFixesRegionExtents(ClientPtr client) 503{ 504 RegionPtr pSource, pDestination; 505 506 REQUEST(xXFixesRegionExtentsReq); 507 508 REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); 509 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); 510 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 511 512 RegionReset(pDestination, RegionExtents(pSource)); 513 514 return Success; 515} 516 517int 518SProcXFixesRegionExtents(ClientPtr client) 519{ 520 REQUEST(xXFixesRegionExtentsReq); 521 522 swaps(&stuff->length); 523 REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); 524 swapl(&stuff->source); 525 swapl(&stuff->destination); 526 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 527} 528 529int 530ProcXFixesFetchRegion(ClientPtr client) 531{ 532 RegionPtr pRegion; 533 xXFixesFetchRegionReply *reply; 534 xRectangle *pRect; 535 BoxPtr pExtent; 536 BoxPtr pBox; 537 int i, nBox; 538 539 REQUEST(xXFixesFetchRegionReq); 540 541 REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); 542 VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); 543 544 pExtent = RegionExtents(pRegion); 545 pBox = RegionRects(pRegion); 546 nBox = RegionNumRects(pRegion); 547 548 reply = calloc(sizeof(xXFixesFetchRegionReply) + nBox * sizeof(xRectangle), 549 1); 550 if (!reply) 551 return BadAlloc; 552 reply->type = X_Reply; 553 reply->sequenceNumber = client->sequence; 554 reply->length = nBox << 1; 555 reply->x = pExtent->x1; 556 reply->y = pExtent->y1; 557 reply->width = pExtent->x2 - pExtent->x1; 558 reply->height = pExtent->y2 - pExtent->y1; 559 560 pRect = (xRectangle *) (reply + 1); 561 for (i = 0; i < nBox; i++) { 562 pRect[i].x = pBox[i].x1; 563 pRect[i].y = pBox[i].y1; 564 pRect[i].width = pBox[i].x2 - pBox[i].x1; 565 pRect[i].height = pBox[i].y2 - pBox[i].y1; 566 } 567 if (client->swapped) { 568 swaps(&reply->sequenceNumber); 569 swapl(&reply->length); 570 swaps(&reply->x); 571 swaps(&reply->y); 572 swaps(&reply->width); 573 swaps(&reply->height); 574 SwapShorts((INT16 *) pRect, nBox * 4); 575 } 576 WriteToClient(client, sizeof(xXFixesFetchRegionReply) + 577 nBox * sizeof(xRectangle), (char *) reply); 578 free(reply); 579 return Success; 580} 581 582int 583SProcXFixesFetchRegion(ClientPtr client) 584{ 585 REQUEST(xXFixesFetchRegionReq); 586 587 swaps(&stuff->length); 588 REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); 589 swapl(&stuff->region); 590 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 591} 592 593int 594ProcXFixesSetGCClipRegion(ClientPtr client) 595{ 596 GCPtr pGC; 597 RegionPtr pRegion; 598 ChangeGCVal vals[2]; 599 int rc; 600 601 REQUEST(xXFixesSetGCClipRegionReq); 602 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); 603 604 rc = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 605 if (rc != Success) 606 return rc; 607 608 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); 609 610 if (pRegion) { 611 pRegion = XFixesRegionCopy(pRegion); 612 if (!pRegion) 613 return BadAlloc; 614 } 615 616 vals[0].val = stuff->xOrigin; 617 vals[1].val = stuff->yOrigin; 618 ChangeGC(NullClient, pGC, GCClipXOrigin | GCClipYOrigin, vals); 619 (*pGC->funcs->ChangeClip) (pGC, pRegion ? CT_REGION : CT_NONE, 620 (void *) pRegion, 0); 621 622 return Success; 623} 624 625int 626SProcXFixesSetGCClipRegion(ClientPtr client) 627{ 628 REQUEST(xXFixesSetGCClipRegionReq); 629 630 swaps(&stuff->length); 631 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); 632 swapl(&stuff->gc); 633 swapl(&stuff->region); 634 swaps(&stuff->xOrigin); 635 swaps(&stuff->yOrigin); 636 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 637} 638 639typedef RegionPtr (*CreateDftPtr) (WindowPtr pWin); 640 641int 642ProcXFixesSetWindowShapeRegion(ClientPtr client) 643{ 644 WindowPtr pWin; 645 RegionPtr pRegion; 646 RegionPtr *pDestRegion; 647 int rc; 648 649 REQUEST(xXFixesSetWindowShapeRegionReq); 650 651 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); 652 rc = dixLookupResourceByType((void **) &pWin, stuff->dest, RT_WINDOW, 653 client, DixSetAttrAccess); 654 if (rc != Success) { 655 client->errorValue = stuff->dest; 656 return rc; 657 } 658 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess); 659 switch (stuff->destKind) { 660 case ShapeBounding: 661 case ShapeClip: 662 case ShapeInput: 663 break; 664 default: 665 client->errorValue = stuff->destKind; 666 return BadValue; 667 } 668 if (pRegion) { 669 pRegion = XFixesRegionCopy(pRegion); 670 if (!pRegion) 671 return BadAlloc; 672 if (!pWin->optional) 673 MakeWindowOptional(pWin); 674 switch (stuff->destKind) { 675 default: 676 case ShapeBounding: 677 pDestRegion = &pWin->optional->boundingShape; 678 break; 679 case ShapeClip: 680 pDestRegion = &pWin->optional->clipShape; 681 break; 682 case ShapeInput: 683 pDestRegion = &pWin->optional->inputShape; 684 break; 685 } 686 if (stuff->xOff || stuff->yOff) 687 RegionTranslate(pRegion, stuff->xOff, stuff->yOff); 688 } 689 else { 690 if (pWin->optional) { 691 switch (stuff->destKind) { 692 default: 693 case ShapeBounding: 694 pDestRegion = &pWin->optional->boundingShape; 695 break; 696 case ShapeClip: 697 pDestRegion = &pWin->optional->clipShape; 698 break; 699 case ShapeInput: 700 pDestRegion = &pWin->optional->inputShape; 701 break; 702 } 703 } 704 else 705 pDestRegion = &pRegion; /* a NULL region pointer */ 706 } 707 if (*pDestRegion) 708 RegionDestroy(*pDestRegion); 709 *pDestRegion = pRegion; 710 (*pWin->drawable.pScreen->SetShape) (pWin, stuff->destKind); 711 SendShapeNotify(pWin, stuff->destKind); 712 return Success; 713} 714 715int 716SProcXFixesSetWindowShapeRegion(ClientPtr client) 717{ 718 REQUEST(xXFixesSetWindowShapeRegionReq); 719 720 swaps(&stuff->length); 721 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); 722 swapl(&stuff->dest); 723 swaps(&stuff->xOff); 724 swaps(&stuff->yOff); 725 swapl(&stuff->region); 726 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 727} 728 729int 730ProcXFixesSetPictureClipRegion(ClientPtr client) 731{ 732 PicturePtr pPicture; 733 RegionPtr pRegion; 734 735 REQUEST(xXFixesSetPictureClipRegionReq); 736 737 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq); 738 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); 739 VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); 740 741 if (!pPicture->pDrawable) 742 return RenderErrBase + BadPicture; 743 744 return SetPictureClipRegion(pPicture, stuff->xOrigin, stuff->yOrigin, 745 pRegion); 746} 747 748int 749SProcXFixesSetPictureClipRegion(ClientPtr client) 750{ 751 REQUEST(xXFixesSetPictureClipRegionReq); 752 753 swaps(&stuff->length); 754 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq); 755 swapl(&stuff->picture); 756 swapl(&stuff->region); 757 swaps(&stuff->xOrigin); 758 swaps(&stuff->yOrigin); 759 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 760} 761 762int 763ProcXFixesExpandRegion(ClientPtr client) 764{ 765 RegionPtr pSource, pDestination; 766 767 REQUEST(xXFixesExpandRegionReq); 768 BoxPtr pTmp; 769 BoxPtr pSrc; 770 int nBoxes; 771 int i; 772 773 REQUEST_SIZE_MATCH(xXFixesExpandRegionReq); 774 VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); 775 VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); 776 777 nBoxes = RegionNumRects(pSource); 778 pSrc = RegionRects(pSource); 779 if (nBoxes) { 780 pTmp = xallocarray(nBoxes, sizeof(BoxRec)); 781 if (!pTmp) 782 return BadAlloc; 783 for (i = 0; i < nBoxes; i++) { 784 pTmp[i].x1 = pSrc[i].x1 - stuff->left; 785 pTmp[i].x2 = pSrc[i].x2 + stuff->right; 786 pTmp[i].y1 = pSrc[i].y1 - stuff->top; 787 pTmp[i].y2 = pSrc[i].y2 + stuff->bottom; 788 } 789 RegionEmpty(pDestination); 790 for (i = 0; i < nBoxes; i++) { 791 RegionRec r; 792 793 RegionInit(&r, &pTmp[i], 0); 794 RegionUnion(pDestination, pDestination, &r); 795 } 796 free(pTmp); 797 } 798 return Success; 799} 800 801int 802SProcXFixesExpandRegion(ClientPtr client) 803{ 804 REQUEST(xXFixesExpandRegionReq); 805 806 swaps(&stuff->length); 807 REQUEST_SIZE_MATCH(xXFixesExpandRegionReq); 808 swapl(&stuff->source); 809 swapl(&stuff->destination); 810 swaps(&stuff->left); 811 swaps(&stuff->right); 812 swaps(&stuff->top); 813 swaps(&stuff->bottom); 814 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 815} 816 817#ifdef PANORAMIX 818#include "panoramiX.h" 819#include "panoramiXsrv.h" 820 821int 822PanoramiXFixesSetGCClipRegion(ClientPtr client) 823{ 824 REQUEST(xXFixesSetGCClipRegionReq); 825 int result = Success, j; 826 PanoramiXRes *gc; 827 828 REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); 829 830 if ((result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC, 831 client, DixWriteAccess))) { 832 client->errorValue = stuff->gc; 833 return result; 834 } 835 836 FOR_NSCREENS_BACKWARD(j) { 837 stuff->gc = gc->info[j].id; 838 result = (*PanoramiXSaveXFixesVector[X_XFixesSetGCClipRegion]) (client); 839 if (result != Success) 840 break; 841 } 842 843 return result; 844} 845 846int 847PanoramiXFixesSetWindowShapeRegion(ClientPtr client) 848{ 849 int result = Success, j; 850 PanoramiXRes *win; 851 RegionPtr reg = NULL; 852 853 REQUEST(xXFixesSetWindowShapeRegionReq); 854 855 REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); 856 857 if ((result = dixLookupResourceByType((void **) &win, stuff->dest, 858 XRT_WINDOW, client, 859 DixWriteAccess))) { 860 client->errorValue = stuff->dest; 861 return result; 862 } 863 864 if (win->u.win.root) 865 VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess); 866 867 FOR_NSCREENS_FORWARD(j) { 868 ScreenPtr screen = screenInfo.screens[j]; 869 stuff->dest = win->info[j].id; 870 871 if (reg) 872 RegionTranslate(reg, -screen->x, -screen->y); 873 874 result = 875 (*PanoramiXSaveXFixesVector[X_XFixesSetWindowShapeRegion]) (client); 876 877 if (reg) 878 RegionTranslate(reg, screen->x, screen->y); 879 880 if (result != Success) 881 break; 882 } 883 884 return result; 885} 886 887int 888PanoramiXFixesSetPictureClipRegion(ClientPtr client) 889{ 890 REQUEST(xXFixesSetPictureClipRegionReq); 891 int result = Success, j; 892 PanoramiXRes *pict; 893 RegionPtr reg = NULL; 894 895 REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq); 896 897 if ((result = dixLookupResourceByType((void **) &pict, stuff->picture, 898 XRT_PICTURE, client, 899 DixWriteAccess))) { 900 client->errorValue = stuff->picture; 901 return result; 902 } 903 904 if (pict->u.pict.root) 905 VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess); 906 907 FOR_NSCREENS_BACKWARD(j) { 908 ScreenPtr screen = screenInfo.screens[j]; 909 stuff->picture = pict->info[j].id; 910 911 if (reg) 912 RegionTranslate(reg, -screen->x, -screen->y); 913 914 result = 915 (*PanoramiXSaveXFixesVector[X_XFixesSetPictureClipRegion]) (client); 916 917 if (reg) 918 RegionTranslate(reg, screen->x, screen->y); 919 920 if (result != Success) 921 break; 922 } 923 924 return result; 925} 926 927#endif 928