xserver

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

compext.c (27042B)


      1 /*
      2  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  *
     23  * Copyright © 2003 Keith Packard
     24  *
     25  * Permission to use, copy, modify, distribute, and sell this software and its
     26  * documentation for any purpose is hereby granted without fee, provided that
     27  * the above copyright notice appear in all copies and that both that
     28  * copyright notice and this permission notice appear in supporting
     29  * documentation, and that the name of Keith Packard not be used in
     30  * advertising or publicity pertaining to distribution of the software without
     31  * specific, written prior permission.  Keith Packard makes no
     32  * representations about the suitability of this software for any purpose.  It
     33  * is provided "as is" without express or implied warranty.
     34  *
     35  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     36  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     37  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     38  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     39  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     40  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     41  * PERFORMANCE OF THIS SOFTWARE.
     42  */
     43 
     44 #ifdef HAVE_DIX_CONFIG_H
     45 #include <dix-config.h>
     46 #endif
     47 
     48 #include "compint.h"
     49 #include "xace.h"
     50 #include "protocol-versions.h"
     51 #include "extinit.h"
     52 
     53 static CARD8 CompositeReqCode;
     54 static DevPrivateKeyRec CompositeClientPrivateKeyRec;
     55 
     56 #define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec)
     57 RESTYPE CompositeClientWindowType;
     58 RESTYPE CompositeClientSubwindowsType;
     59 RESTYPE CompositeClientOverlayType;
     60 
     61 typedef struct _CompositeClient {
     62     int major_version;
     63     int minor_version;
     64 } CompositeClientRec, *CompositeClientPtr;
     65 
     66 #define GetCompositeClient(pClient) ((CompositeClientPtr) \
     67     dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
     68 
     69 static int
     70 FreeCompositeClientWindow(void *value, XID ccwid)
     71 {
     72     WindowPtr pWin = value;
     73 
     74     compFreeClientWindow(pWin, ccwid);
     75     return Success;
     76 }
     77 
     78 static int
     79 FreeCompositeClientSubwindows(void *value, XID ccwid)
     80 {
     81     WindowPtr pWin = value;
     82 
     83     compFreeClientSubwindows(pWin, ccwid);
     84     return Success;
     85 }
     86 
     87 static int
     88 FreeCompositeClientOverlay(void *value, XID ccwid)
     89 {
     90     CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
     91 
     92     compFreeOverlayClient(pOc);
     93     return Success;
     94 }
     95 
     96 static int
     97 ProcCompositeQueryVersion(ClientPtr client)
     98 {
     99     CompositeClientPtr pCompositeClient = GetCompositeClient(client);
    100     xCompositeQueryVersionReply rep = {
    101         .type = X_Reply,
    102         .sequenceNumber = client->sequence,
    103         .length = 0
    104     };
    105 
    106     REQUEST(xCompositeQueryVersionReq);
    107 
    108     REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
    109     if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
    110         rep.majorVersion = stuff->majorVersion;
    111         rep.minorVersion = stuff->minorVersion;
    112     }
    113     else {
    114         rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
    115         rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
    116     }
    117     pCompositeClient->major_version = rep.majorVersion;
    118     pCompositeClient->minor_version = rep.minorVersion;
    119     if (client->swapped) {
    120         swaps(&rep.sequenceNumber);
    121         swapl(&rep.length);
    122         swapl(&rep.majorVersion);
    123         swapl(&rep.minorVersion);
    124     }
    125     WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep);
    126     return Success;
    127 }
    128 
    129 #define VERIFY_WINDOW(pWindow, wid, client, mode)			\
    130     do {								\
    131 	int err;							\
    132 	err = dixLookupResourceByType((void **) &pWindow, wid,	\
    133 				      RT_WINDOW, client, mode);		\
    134 	if (err != Success) {						\
    135 	    client->errorValue = wid;					\
    136 	    return err;							\
    137 	}								\
    138     } while (0)
    139 
    140 static int
    141 ProcCompositeRedirectWindow(ClientPtr client)
    142 {
    143     WindowPtr pWin;
    144 
    145     REQUEST(xCompositeRedirectWindowReq);
    146 
    147     REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
    148     VERIFY_WINDOW(pWin, stuff->window, client,
    149                   DixSetAttrAccess | DixManageAccess | DixBlendAccess);
    150 
    151     return compRedirectWindow(client, pWin, stuff->update);
    152 }
    153 
    154 static int
    155 ProcCompositeRedirectSubwindows(ClientPtr client)
    156 {
    157     WindowPtr pWin;
    158 
    159     REQUEST(xCompositeRedirectSubwindowsReq);
    160 
    161     REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
    162     VERIFY_WINDOW(pWin, stuff->window, client,
    163                   DixSetAttrAccess | DixManageAccess | DixBlendAccess);
    164 
    165     return compRedirectSubwindows(client, pWin, stuff->update);
    166 }
    167 
    168 static int
    169 ProcCompositeUnredirectWindow(ClientPtr client)
    170 {
    171     WindowPtr pWin;
    172 
    173     REQUEST(xCompositeUnredirectWindowReq);
    174 
    175     REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
    176     VERIFY_WINDOW(pWin, stuff->window, client,
    177                   DixSetAttrAccess | DixManageAccess | DixBlendAccess);
    178 
    179     return compUnredirectWindow(client, pWin, stuff->update);
    180 }
    181 
    182 static int
    183 ProcCompositeUnredirectSubwindows(ClientPtr client)
    184 {
    185     WindowPtr pWin;
    186 
    187     REQUEST(xCompositeUnredirectSubwindowsReq);
    188 
    189     REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
    190     VERIFY_WINDOW(pWin, stuff->window, client,
    191                   DixSetAttrAccess | DixManageAccess | DixBlendAccess);
    192 
    193     return compUnredirectSubwindows(client, pWin, stuff->update);
    194 }
    195 
    196 static int
    197 ProcCompositeCreateRegionFromBorderClip(ClientPtr client)
    198 {
    199     WindowPtr pWin;
    200     CompWindowPtr cw;
    201     RegionPtr pBorderClip, pRegion;
    202 
    203     REQUEST(xCompositeCreateRegionFromBorderClipReq);
    204 
    205     REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
    206     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
    207     LEGAL_NEW_RESOURCE(stuff->region, client);
    208 
    209     cw = GetCompWindow(pWin);
    210     if (cw)
    211         pBorderClip = &cw->borderClip;
    212     else
    213         pBorderClip = &pWin->borderClip;
    214     pRegion = XFixesRegionCopy(pBorderClip);
    215     if (!pRegion)
    216         return BadAlloc;
    217     RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
    218 
    219     if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
    220         return BadAlloc;
    221 
    222     return Success;
    223 }
    224 
    225 static int
    226 ProcCompositeNameWindowPixmap(ClientPtr client)
    227 {
    228     WindowPtr pWin;
    229     CompWindowPtr cw;
    230     PixmapPtr pPixmap;
    231     ScreenPtr pScreen;
    232     int rc;
    233 
    234     REQUEST(xCompositeNameWindowPixmapReq);
    235 
    236     REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
    237     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
    238 
    239     pScreen = pWin->drawable.pScreen;
    240 
    241     if (!pWin->viewable)
    242         return BadMatch;
    243 
    244     LEGAL_NEW_RESOURCE(stuff->pixmap, client);
    245 
    246     cw = GetCompWindow(pWin);
    247     if (!cw)
    248         return BadMatch;
    249 
    250     pPixmap = (*pScreen->GetWindowPixmap) (pWin);
    251     if (!pPixmap)
    252         return BadMatch;
    253 
    254     /* security creation/labeling check */
    255     rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
    256                   pPixmap, RT_WINDOW, pWin, DixCreateAccess);
    257     if (rc != Success)
    258         return rc;
    259 
    260     ++pPixmap->refcnt;
    261 
    262     if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pPixmap))
    263         return BadAlloc;
    264 
    265     if (pScreen->NameWindowPixmap) {
    266         rc = pScreen->NameWindowPixmap(pWin, pPixmap, stuff->pixmap);
    267         if (rc != Success) {
    268             FreeResource(stuff->pixmap, RT_NONE);
    269             return rc;
    270         }
    271     }
    272 
    273     return Success;
    274 }
    275 
    276 static int
    277 ProcCompositeGetOverlayWindow(ClientPtr client)
    278 {
    279     REQUEST(xCompositeGetOverlayWindowReq);
    280     xCompositeGetOverlayWindowReply rep;
    281     WindowPtr pWin;
    282     ScreenPtr pScreen;
    283     CompScreenPtr cs;
    284     CompOverlayClientPtr pOc;
    285     int rc;
    286 
    287     REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
    288     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
    289     pScreen = pWin->drawable.pScreen;
    290 
    291     /*
    292      * Create an OverlayClient structure to mark this client's
    293      * interest in the overlay window
    294      */
    295     pOc = compCreateOverlayClient(pScreen, client);
    296     if (pOc == NULL)
    297         return BadAlloc;
    298 
    299     /*
    300      * Make sure the overlay window exists
    301      */
    302     cs = GetCompScreen(pScreen);
    303     if (cs->pOverlayWin == NULL)
    304         if (!compCreateOverlayWindow(pScreen)) {
    305             FreeResource(pOc->resource, RT_NONE);
    306             return BadAlloc;
    307         }
    308 
    309     rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
    310                   RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
    311     if (rc != Success) {
    312         FreeResource(pOc->resource, RT_NONE);
    313         return rc;
    314     }
    315 
    316     rep = (xCompositeGetOverlayWindowReply) {
    317         .type = X_Reply,
    318         .sequenceNumber = client->sequence,
    319         .length = 0,
    320         .overlayWin = cs->pOverlayWin->drawable.id
    321     };
    322 
    323     if (client->swapped) {
    324         swaps(&rep.sequenceNumber);
    325         swapl(&rep.length);
    326         swapl(&rep.overlayWin);
    327     }
    328     WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
    329 
    330     return Success;
    331 }
    332 
    333 static int
    334 ProcCompositeReleaseOverlayWindow(ClientPtr client)
    335 {
    336     REQUEST(xCompositeReleaseOverlayWindowReq);
    337     WindowPtr pWin;
    338     CompOverlayClientPtr pOc;
    339 
    340     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
    341     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
    342 
    343     /*
    344      * Has client queried a reference to the overlay window
    345      * on this screen? If not, generate an error.
    346      */
    347     pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
    348     if (pOc == NULL)
    349         return BadMatch;
    350 
    351     /* The delete function will free the client structure */
    352     FreeResource(pOc->resource, RT_NONE);
    353 
    354     return Success;
    355 }
    356 
    357 static int (*ProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
    358 ProcCompositeQueryVersion,
    359         ProcCompositeRedirectWindow,
    360         ProcCompositeRedirectSubwindows,
    361         ProcCompositeUnredirectWindow,
    362         ProcCompositeUnredirectSubwindows,
    363         ProcCompositeCreateRegionFromBorderClip,
    364         ProcCompositeNameWindowPixmap,
    365         ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,};
    366 
    367 static int
    368 ProcCompositeDispatch(ClientPtr client)
    369 {
    370     REQUEST(xReq);
    371 
    372     if (stuff->data < CompositeNumberRequests)
    373         return (*ProcCompositeVector[stuff->data]) (client);
    374     else
    375         return BadRequest;
    376 }
    377 
    378 static int _X_COLD
    379 SProcCompositeQueryVersion(ClientPtr client)
    380 {
    381     REQUEST(xCompositeQueryVersionReq);
    382 
    383     swaps(&stuff->length);
    384     REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
    385     swapl(&stuff->majorVersion);
    386     swapl(&stuff->minorVersion);
    387     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    388 }
    389 
    390 static int _X_COLD
    391 SProcCompositeRedirectWindow(ClientPtr client)
    392 {
    393     REQUEST(xCompositeRedirectWindowReq);
    394 
    395     swaps(&stuff->length);
    396     REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
    397     swapl(&stuff->window);
    398     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    399 }
    400 
    401 static int _X_COLD
    402 SProcCompositeRedirectSubwindows(ClientPtr client)
    403 {
    404     REQUEST(xCompositeRedirectSubwindowsReq);
    405 
    406     swaps(&stuff->length);
    407     REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
    408     swapl(&stuff->window);
    409     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    410 }
    411 
    412 static int _X_COLD
    413 SProcCompositeUnredirectWindow(ClientPtr client)
    414 {
    415     REQUEST(xCompositeUnredirectWindowReq);
    416 
    417     swaps(&stuff->length);
    418     REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
    419     swapl(&stuff->window);
    420     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    421 }
    422 
    423 static int _X_COLD
    424 SProcCompositeUnredirectSubwindows(ClientPtr client)
    425 {
    426     REQUEST(xCompositeUnredirectSubwindowsReq);
    427 
    428     swaps(&stuff->length);
    429     REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
    430     swapl(&stuff->window);
    431     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    432 }
    433 
    434 static int _X_COLD
    435 SProcCompositeCreateRegionFromBorderClip(ClientPtr client)
    436 {
    437     REQUEST(xCompositeCreateRegionFromBorderClipReq);
    438 
    439     swaps(&stuff->length);
    440     REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
    441     swapl(&stuff->region);
    442     swapl(&stuff->window);
    443     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    444 }
    445 
    446 static int _X_COLD
    447 SProcCompositeNameWindowPixmap(ClientPtr client)
    448 {
    449     REQUEST(xCompositeNameWindowPixmapReq);
    450 
    451     swaps(&stuff->length);
    452     REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
    453     swapl(&stuff->window);
    454     swapl(&stuff->pixmap);
    455     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    456 }
    457 
    458 static int _X_COLD
    459 SProcCompositeGetOverlayWindow(ClientPtr client)
    460 {
    461     REQUEST(xCompositeGetOverlayWindowReq);
    462 
    463     swaps(&stuff->length);
    464     REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
    465     swapl(&stuff->window);
    466     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    467 }
    468 
    469 static int _X_COLD
    470 SProcCompositeReleaseOverlayWindow(ClientPtr client)
    471 {
    472     REQUEST(xCompositeReleaseOverlayWindowReq);
    473 
    474     swaps(&stuff->length);
    475     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
    476     swapl(&stuff->window);
    477     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
    478 }
    479 
    480 static int
    481 (*SProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
    482     SProcCompositeQueryVersion,
    483     SProcCompositeRedirectWindow,
    484     SProcCompositeRedirectSubwindows,
    485     SProcCompositeUnredirectWindow,
    486     SProcCompositeUnredirectSubwindows,
    487     SProcCompositeCreateRegionFromBorderClip,
    488     SProcCompositeNameWindowPixmap,
    489     SProcCompositeGetOverlayWindow,
    490     SProcCompositeReleaseOverlayWindow,
    491 };
    492 
    493 static int _X_COLD
    494 SProcCompositeDispatch(ClientPtr client)
    495 {
    496     REQUEST(xReq);
    497 
    498     if (stuff->data < CompositeNumberRequests)
    499         return (*SProcCompositeVector[stuff->data]) (client);
    500     else
    501         return BadRequest;
    502 }
    503 
    504 /** @see GetDefaultBytes */
    505 static SizeType coreGetWindowBytes;
    506 
    507 static void
    508 GetCompositeWindowBytes(void *value, XID id, ResourceSizePtr size)
    509 {
    510     WindowPtr window = value;
    511 
    512     /* call down */
    513     coreGetWindowBytes(value, id, size);
    514 
    515     /* account for redirection */
    516     if (window->redirectDraw != RedirectDrawNone)
    517     {
    518         SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP);
    519         ResourceSizeRec pixmapSize = { 0, 0 };
    520         ScreenPtr screen = window->drawable.pScreen;
    521         PixmapPtr pixmap = screen->GetWindowPixmap(window);
    522         pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize);
    523         size->pixmapRefSize += pixmapSize.pixmapRefSize;
    524     }
    525 }
    526 
    527 void
    528 CompositeExtensionInit(void)
    529 {
    530     ExtensionEntry *extEntry;
    531     int s;
    532 
    533     /* Assume initialization is going to fail */
    534     noCompositeExtension = TRUE;
    535 
    536     for (s = 0; s < screenInfo.numScreens; s++) {
    537         ScreenPtr pScreen = screenInfo.screens[s];
    538         VisualPtr vis;
    539 
    540         /* Composite on 8bpp pseudocolor root windows appears to fail, so
    541          * just disable it on anything pseudocolor for safety.
    542          */
    543         for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++);
    544         if ((vis->class | DynamicClass) == PseudoColor)
    545             return;
    546 
    547         /* Ensure that Render is initialized, which is required for automatic
    548          * compositing.
    549          */
    550         if (GetPictureScreenIfSet(pScreen) == NULL)
    551             return;
    552     }
    553 
    554     CompositeClientWindowType = CreateNewResourceType
    555         (FreeCompositeClientWindow, "CompositeClientWindow");
    556     if (!CompositeClientWindowType)
    557         return;
    558 
    559     coreGetWindowBytes = GetResourceTypeSizeFunc(RT_WINDOW);
    560     SetResourceTypeSizeFunc(RT_WINDOW, GetCompositeWindowBytes);
    561 
    562     CompositeClientSubwindowsType = CreateNewResourceType
    563         (FreeCompositeClientSubwindows, "CompositeClientSubwindows");
    564     if (!CompositeClientSubwindowsType)
    565         return;
    566 
    567     CompositeClientOverlayType = CreateNewResourceType
    568         (FreeCompositeClientOverlay, "CompositeClientOverlay");
    569     if (!CompositeClientOverlayType)
    570         return;
    571 
    572     if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT,
    573                                sizeof(CompositeClientRec)))
    574         return;
    575 
    576     for (s = 0; s < screenInfo.numScreens; s++)
    577         if (!compScreenInit(screenInfo.screens[s]))
    578             return;
    579 
    580     extEntry = AddExtension(COMPOSITE_NAME, 0, 0,
    581                             ProcCompositeDispatch, SProcCompositeDispatch,
    582                             NULL, StandardMinorOpcode);
    583     if (!extEntry)
    584         return;
    585     CompositeReqCode = (CARD8) extEntry->base;
    586 
    587     /* Initialization succeeded */
    588     noCompositeExtension = FALSE;
    589 }
    590 
    591 #ifdef PANORAMIX
    592 #include "panoramiXsrv.h"
    593 
    594 int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr);
    595 
    596 static int
    597 PanoramiXCompositeRedirectWindow(ClientPtr client)
    598 {
    599     PanoramiXRes *win;
    600     int rc = 0, j;
    601 
    602     REQUEST(xCompositeRedirectWindowReq);
    603 
    604     REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
    605 
    606     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
    607                                       client, DixUnknownAccess))) {
    608         client->errorValue = stuff->window;
    609         return rc;
    610     }
    611 
    612     FOR_NSCREENS_FORWARD(j) {
    613         stuff->window = win->info[j].id;
    614         rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
    615         if (rc != Success)
    616             break;
    617     }
    618 
    619     return rc;
    620 }
    621 
    622 static int
    623 PanoramiXCompositeRedirectSubwindows(ClientPtr client)
    624 {
    625     PanoramiXRes *win;
    626     int rc = 0, j;
    627 
    628     REQUEST(xCompositeRedirectSubwindowsReq);
    629 
    630     REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
    631 
    632     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
    633                                       client, DixUnknownAccess))) {
    634         client->errorValue = stuff->window;
    635         return rc;
    636     }
    637 
    638     FOR_NSCREENS_FORWARD(j) {
    639         stuff->window = win->info[j].id;
    640         rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
    641         if (rc != Success)
    642             break;
    643     }
    644 
    645     return rc;
    646 }
    647 
    648 static int
    649 PanoramiXCompositeUnredirectWindow(ClientPtr client)
    650 {
    651     PanoramiXRes *win;
    652     int rc = 0, j;
    653 
    654     REQUEST(xCompositeUnredirectWindowReq);
    655 
    656     REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
    657 
    658     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
    659                                       client, DixUnknownAccess))) {
    660         client->errorValue = stuff->window;
    661         return rc;
    662     }
    663 
    664     FOR_NSCREENS_FORWARD(j) {
    665         stuff->window = win->info[j].id;
    666         rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
    667         if (rc != Success)
    668             break;
    669     }
    670 
    671     return rc;
    672 }
    673 
    674 static int
    675 PanoramiXCompositeUnredirectSubwindows(ClientPtr client)
    676 {
    677     PanoramiXRes *win;
    678     int rc = 0, j;
    679 
    680     REQUEST(xCompositeUnredirectSubwindowsReq);
    681 
    682     REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
    683 
    684     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
    685                                       client, DixUnknownAccess))) {
    686         client->errorValue = stuff->window;
    687         return rc;
    688     }
    689 
    690     FOR_NSCREENS_FORWARD(j) {
    691         stuff->window = win->info[j].id;
    692         rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
    693         if (rc != Success)
    694             break;
    695     }
    696 
    697     return rc;
    698 }
    699 
    700 static int
    701 PanoramiXCompositeNameWindowPixmap(ClientPtr client)
    702 {
    703     WindowPtr pWin;
    704     CompWindowPtr cw;
    705     PixmapPtr pPixmap;
    706     int rc;
    707     PanoramiXRes *win, *newPix;
    708     int i;
    709 
    710     REQUEST(xCompositeNameWindowPixmapReq);
    711 
    712     REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
    713 
    714     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
    715                                       client, DixUnknownAccess))) {
    716         client->errorValue = stuff->window;
    717         return rc;
    718     }
    719 
    720     LEGAL_NEW_RESOURCE(stuff->pixmap, client);
    721 
    722     if (!(newPix = malloc(sizeof(PanoramiXRes))))
    723         return BadAlloc;
    724 
    725     newPix->type = XRT_PIXMAP;
    726     newPix->u.pix.shared = FALSE;
    727     panoramix_setup_ids(newPix, client, stuff->pixmap);
    728 
    729     FOR_NSCREENS(i) {
    730         rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
    731                                      RT_WINDOW, client, DixGetAttrAccess);
    732         if (rc != Success) {
    733             client->errorValue = stuff->window;
    734             free(newPix);
    735             return rc;
    736         }
    737 
    738         if (!pWin->viewable) {
    739             free(newPix);
    740             return BadMatch;
    741         }
    742 
    743         cw = GetCompWindow(pWin);
    744         if (!cw) {
    745             free(newPix);
    746             return BadMatch;
    747         }
    748 
    749         pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
    750         if (!pPixmap) {
    751             free(newPix);
    752             return BadMatch;
    753         }
    754 
    755         if (!AddResource(newPix->info[i].id, RT_PIXMAP, (void *) pPixmap))
    756             return BadAlloc;
    757 
    758         ++pPixmap->refcnt;
    759     }
    760 
    761     if (!AddResource(stuff->pixmap, XRT_PIXMAP, (void *) newPix))
    762         return BadAlloc;
    763 
    764     return Success;
    765 }
    766 
    767 static int
    768 PanoramiXCompositeGetOverlayWindow(ClientPtr client)
    769 {
    770     REQUEST(xCompositeGetOverlayWindowReq);
    771     xCompositeGetOverlayWindowReply rep;
    772     WindowPtr pWin;
    773     ScreenPtr pScreen;
    774     CompScreenPtr cs;
    775     CompOverlayClientPtr pOc;
    776     int rc;
    777     PanoramiXRes *win, *overlayWin = NULL;
    778     int i;
    779 
    780     REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
    781 
    782     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
    783                                       client, DixUnknownAccess))) {
    784         client->errorValue = stuff->window;
    785         return rc;
    786     }
    787 
    788     cs = GetCompScreen(screenInfo.screens[0]);
    789     if (!cs->pOverlayWin) {
    790         if (!(overlayWin = malloc(sizeof(PanoramiXRes))))
    791             return BadAlloc;
    792 
    793         overlayWin->type = XRT_WINDOW;
    794         overlayWin->u.win.root = FALSE;
    795     }
    796 
    797     FOR_NSCREENS_BACKWARD(i) {
    798         rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
    799                                      RT_WINDOW, client, DixGetAttrAccess);
    800         if (rc != Success) {
    801             client->errorValue = stuff->window;
    802             free(overlayWin);
    803             return rc;
    804         }
    805         pScreen = pWin->drawable.pScreen;
    806 
    807         /*
    808          * Create an OverlayClient structure to mark this client's
    809          * interest in the overlay window
    810          */
    811         pOc = compCreateOverlayClient(pScreen, client);
    812         if (pOc == NULL) {
    813             free(overlayWin);
    814             return BadAlloc;
    815         }
    816 
    817         /*
    818          * Make sure the overlay window exists
    819          */
    820         cs = GetCompScreen(pScreen);
    821         if (cs->pOverlayWin == NULL)
    822             if (!compCreateOverlayWindow(pScreen)) {
    823                 FreeResource(pOc->resource, RT_NONE);
    824                 free(overlayWin);
    825                 return BadAlloc;
    826             }
    827 
    828         rc = XaceHook(XACE_RESOURCE_ACCESS, client,
    829                       cs->pOverlayWin->drawable.id,
    830                       RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL,
    831                       DixGetAttrAccess);
    832         if (rc != Success) {
    833             FreeResource(pOc->resource, RT_NONE);
    834             free(overlayWin);
    835             return rc;
    836         }
    837     }
    838 
    839     if (overlayWin) {
    840         FOR_NSCREENS(i) {
    841             cs = GetCompScreen(screenInfo.screens[i]);
    842             overlayWin->info[i].id = cs->pOverlayWin->drawable.id;
    843         }
    844 
    845         AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin);
    846     }
    847 
    848     cs = GetCompScreen(screenInfo.screens[0]);
    849 
    850     rep = (xCompositeGetOverlayWindowReply) {
    851         .type = X_Reply,
    852         .sequenceNumber = client->sequence,
    853         .length = 0,
    854         .overlayWin = cs->pOverlayWin->drawable.id
    855     };
    856 
    857     if (client->swapped) {
    858         swaps(&rep.sequenceNumber);
    859         swapl(&rep.length);
    860         swapl(&rep.overlayWin);
    861     }
    862     WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
    863 
    864     return Success;
    865 }
    866 
    867 static int
    868 PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)
    869 {
    870     REQUEST(xCompositeReleaseOverlayWindowReq);
    871     WindowPtr pWin;
    872     CompOverlayClientPtr pOc;
    873     PanoramiXRes *win;
    874     int i, rc;
    875 
    876     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
    877 
    878     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
    879                                       client, DixUnknownAccess))) {
    880         client->errorValue = stuff->window;
    881         return rc;
    882     }
    883 
    884     FOR_NSCREENS_BACKWARD(i) {
    885         if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
    886                                           XRT_WINDOW, client,
    887                                           DixUnknownAccess))) {
    888             client->errorValue = stuff->window;
    889             return rc;
    890         }
    891 
    892         /*
    893          * Has client queried a reference to the overlay window
    894          * on this screen? If not, generate an error.
    895          */
    896         pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
    897         if (pOc == NULL)
    898             return BadMatch;
    899 
    900         /* The delete function will free the client structure */
    901         FreeResource(pOc->resource, RT_NONE);
    902     }
    903 
    904     return Success;
    905 }
    906 
    907 void
    908 PanoramiXCompositeInit(void)
    909 {
    910     int i;
    911 
    912     for (i = 0; i < CompositeNumberRequests; i++)
    913         PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i];
    914     /*
    915      * Stuff in Xinerama aware request processing hooks
    916      */
    917     ProcCompositeVector[X_CompositeRedirectWindow] =
    918         PanoramiXCompositeRedirectWindow;
    919     ProcCompositeVector[X_CompositeRedirectSubwindows] =
    920         PanoramiXCompositeRedirectSubwindows;
    921     ProcCompositeVector[X_CompositeUnredirectWindow] =
    922         PanoramiXCompositeUnredirectWindow;
    923     ProcCompositeVector[X_CompositeUnredirectSubwindows] =
    924         PanoramiXCompositeUnredirectSubwindows;
    925     ProcCompositeVector[X_CompositeNameWindowPixmap] =
    926         PanoramiXCompositeNameWindowPixmap;
    927     ProcCompositeVector[X_CompositeGetOverlayWindow] =
    928         PanoramiXCompositeGetOverlayWindow;
    929     ProcCompositeVector[X_CompositeReleaseOverlayWindow] =
    930         PanoramiXCompositeReleaseOverlayWindow;
    931 }
    932 
    933 void
    934 PanoramiXCompositeReset(void)
    935 {
    936     int i;
    937 
    938     for (i = 0; i < CompositeNumberRequests; i++)
    939         ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i];
    940 }
    941 
    942 #endif