region.c (24220B)
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 35 RESTYPE RegionResType; 36 37 static int 38 RegionResFree(void *data, XID id) 39 { 40 RegionPtr pRegion = (RegionPtr) data; 41 42 RegionDestroy(pRegion); 43 return Success; 44 } 45 46 RegionPtr 47 XFixesRegionCopy(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 61 Bool 62 XFixesRegionInit(void) 63 { 64 RegionResType = CreateNewResourceType(RegionResFree, "XFixesRegion"); 65 66 return RegionResType != 0; 67 } 68 69 int 70 ProcXFixesCreateRegion(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 94 int _X_COLD 95 SProcXFixesCreateRegion(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 106 int 107 ProcXFixesCreateRegionFromBitmap(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 138 int _X_COLD 139 SProcXFixesCreateRegionFromBitmap(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 150 int 151 ProcXFixesCreateRegionFromWindow(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 197 int _X_COLD 198 SProcXFixesCreateRegionFromWindow(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 209 int 210 ProcXFixesCreateRegionFromGC(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 240 int _X_COLD 241 SProcXFixesCreateRegionFromGC(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 252 int 253 ProcXFixesCreateRegionFromPicture(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 282 int _X_COLD 283 SProcXFixesCreateRegionFromPicture(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 294 int 295 ProcXFixesDestroyRegion(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 306 int _X_COLD 307 SProcXFixesDestroyRegion(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 317 int 318 ProcXFixesSetRegion(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 344 int _X_COLD 345 SProcXFixesSetRegion(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 356 int 357 ProcXFixesCopyRegion(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 373 int _X_COLD 374 SProcXFixesCopyRegion(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 385 int 386 ProcXFixesCombineRegion(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 415 int _X_COLD 416 SProcXFixesCombineRegion(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 428 int 429 ProcXFixesInvertRegion(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 459 int _X_COLD 460 SProcXFixesInvertRegion(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 475 int 476 ProcXFixesTranslateRegion(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 489 int _X_COLD 490 SProcXFixesTranslateRegion(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 502 int 503 ProcXFixesRegionExtents(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 518 int _X_COLD 519 SProcXFixesRegionExtents(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 530 int 531 ProcXFixesFetchRegion(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 583 int _X_COLD 584 SProcXFixesFetchRegion(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 594 int 595 ProcXFixesSetGCClipRegion(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 626 int _X_COLD 627 SProcXFixesSetGCClipRegion(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 640 typedef RegionPtr (*CreateDftPtr) (WindowPtr pWin); 641 642 int 643 ProcXFixesSetWindowShapeRegion(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 716 int _X_COLD 717 SProcXFixesSetWindowShapeRegion(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 730 int 731 ProcXFixesSetPictureClipRegion(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 749 int _X_COLD 750 SProcXFixesSetPictureClipRegion(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 763 int 764 ProcXFixesExpandRegion(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 802 int _X_COLD 803 SProcXFixesExpandRegion(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 822 int 823 PanoramiXFixesSetGCClipRegion(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 847 int 848 PanoramiXFixesSetWindowShapeRegion(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 888 int 889 PanoramiXFixesSetPictureClipRegion(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