xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

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