diff options
Diffstat (limited to 'nx-X11/programs/Xserver/composite/compext.c')
-rw-r--r-- | nx-X11/programs/Xserver/composite/compext.c | 741 |
1 files changed, 707 insertions, 34 deletions
diff --git a/nx-X11/programs/Xserver/composite/compext.c b/nx-X11/programs/Xserver/composite/compext.c index f57235d46..d5f8fd6d4 100644 --- a/nx-X11/programs/Xserver/composite/compext.c +++ b/nx-X11/programs/Xserver/composite/compext.c @@ -27,18 +27,44 @@ #endif #include "compint.h" +#include "XI.h" +#include "XIproto.h" +#include "extinit.h" + +#ifndef SERVER_COMPOSITE_MAJOR_VERSION +#define SERVER_COMPOSITE_MAJOR_VERSION 0 +#endif + +#ifndef SERVER_COMPOSITE_MINOR_VERSION +#define SERVER_COMPOSITE_MINOR_VERSION 4 +#endif static CARD8 CompositeReqCode; -int CompositeClientPrivateIndex; + +#ifndef NXAGENT_SERVER +static DevPrivateKeyRec CompositeClientPrivateKeyRec; + +#define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec) +#else /* !defined(NXAGENT_SERVER) */ +static int CompositeClientPrivIndex = -1; +#endif /* !defined(NXAGENT_SERVER) */ + RESTYPE CompositeClientWindowType; RESTYPE CompositeClientSubwindowsType; +RESTYPE CompositeClientOverlayType; typedef struct _CompositeClient { int major_version; int minor_version; } CompositeClientRec, *CompositeClientPtr; -#define GetCompositeClient(pClient) ((CompositeClientPtr) (pClient)->devPrivates[CompositeClientPrivateIndex].ptr) +#ifndef NXAGENT_SERVER +#define GetCompositeClient(pClient) ((CompositeClientPtr) \ + dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey)) +#else /* !defined(NXAGENT_SERVER) */ +#define GetCompositeClient(pClient) ((CompositeClientPtr) \ + (pClient)->devPrivates[CompositeClientPrivIndex].ptr) +#endif /* !edefined(NXAGENT_SERVER) */ static void CompositeClientCallback (CallbackListPtr *list, @@ -57,22 +83,31 @@ static void CompositeResetProc (ExtensionEntry *extEntry) { } + +static int +FreeCompositeClientWindow(void *value, XID ccwid) +{ + WindowPtr pWin = value; + + compFreeClientWindow(pWin, ccwid); + return Success; +} static int -FreeCompositeClientWindow (void * value, XID ccwid) +FreeCompositeClientSubwindows(void *value, XID ccwid) { WindowPtr pWin = value; - compFreeClientWindow (pWin, ccwid); + compFreeClientSubwindows(pWin, ccwid); return Success; } static int -FreeCompositeClientSubwindows (void * value, XID ccwid) +FreeCompositeClientOverlay(void *value, XID ccwid) { - WindowPtr pWin = value; + CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; - compFreeClientSubwindows (pWin, ccwid); + compFreeOverlayClient(pOc); return Success; } @@ -80,24 +115,22 @@ static int ProcCompositeQueryVersion (ClientPtr client) { CompositeClientPtr pCompositeClient = GetCompositeClient (client); - xCompositeQueryVersionReply rep; + xCompositeQueryVersionReply rep = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0 + }; register int n; + REQUEST(xCompositeQueryVersionReq); REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - if (stuff->majorVersion < COMPOSITE_MAJOR) { + if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; } else { - rep.majorVersion = COMPOSITE_MAJOR; - if (stuff->majorVersion == COMPOSITE_MAJOR && - stuff->minorVersion < COMPOSITE_MINOR) - rep.minorVersion = stuff->minorVersion; - else - rep.minorVersion = COMPOSITE_MINOR; + rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION; + rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION; } pCompositeClient->major_version = rep.majorVersion; pCompositeClient->minor_version = rep.minorVersion; @@ -108,9 +141,23 @@ ProcCompositeQueryVersion (ClientPtr client) swapl(&rep.minorVersion, n); } WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep); - return(client->noClientException); + return Success; } +/* Unsupported by current architecture and porting is too much effort. */ +#if 0 +#define VERIFY_WINDOW(pWindow, wid, client, mode) \ + do { \ + int err; \ + err = dixLookupResourceByType((void **) &pWindow, wid, \ + RT_WINDOW, client, mode); \ + if (err != Success) { \ + client->errorValue = wid; \ + return err; \ + } \ + } while (0) +#endif /* 0 */ + static int ProcCompositeRedirectWindow (ClientPtr client) { @@ -118,12 +165,18 @@ ProcCompositeRedirectWindow (ClientPtr client) REQUEST(xCompositeRedirectWindowReq); REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); + /* Unsupported by current architecture and porting is too much effort. */ + /* + VERIFY_WINDOW(pWin, stuff->window, client, + DixSetAttrAccess | DixManageAccess | DixBlendAccess); + */ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); if (!pWin) { client->errorValue = stuff->window; return BadWindow; } + return compRedirectWindow (client, pWin, stuff->update); } @@ -134,12 +187,18 @@ ProcCompositeRedirectSubwindows (ClientPtr client) REQUEST(xCompositeRedirectSubwindowsReq); REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); + /* Unsupported by current architecture and porting is too much effort. */ + /* + VERIFY_WINDOW(pWin, stuff->window, client, + DixSetAttrAccess | DixManageAccess | DixBlendAccess); + */ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); if (!pWin) { client->errorValue = stuff->window; return BadWindow; } + return compRedirectSubwindows (client, pWin, stuff->update); } @@ -150,12 +209,18 @@ ProcCompositeUnredirectWindow (ClientPtr client) REQUEST(xCompositeUnredirectWindowReq); REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); + /* Unsupported by current architecture and porting is too much effort. */ + /* + VERIFY_WINDOW(pWin, stuff->window, client, + DixSetAttrAccess | DixManageAccess | DixBlendAccess); + */ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); if (!pWin) { client->errorValue = stuff->window; return BadWindow; } + return compUnredirectWindow (client, pWin, stuff->update); } @@ -166,12 +231,18 @@ ProcCompositeUnredirectSubwindows (ClientPtr client) REQUEST(xCompositeUnredirectSubwindowsReq); REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); + /* Unsupported by current architecture and porting is too much effort. */ + /* + VERIFY_WINDOW(pWin, stuff->window, client, + DixSetAttrAccess | DixManageAccess | DixBlendAccess); + */ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); if (!pWin) { client->errorValue = stuff->window; return BadWindow; } + return compUnredirectSubwindows (client, pWin, stuff->update); } @@ -184,13 +255,16 @@ ProcCompositeCreateRegionFromBorderClip (ClientPtr client) REQUEST(xCompositeCreateRegionFromBorderClipReq); REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); + /* Unsupported by current architecture and porting is too much effort. */ + /* + VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); + */ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); if (!pWin) { client->errorValue = stuff->window; return BadWindow; } - LEGAL_NEW_RESOURCE (stuff->region, client); cw = GetCompWindow (pWin); @@ -206,7 +280,7 @@ ProcCompositeCreateRegionFromBorderClip (ClientPtr client) if (!AddResource (stuff->region, RegionResType, (void *) pRegion)) return BadAlloc; - return(client->noClientException); + return Success; } static int @@ -215,35 +289,170 @@ ProcCompositeNameWindowPixmap (ClientPtr client) WindowPtr pWin; CompWindowPtr cw; PixmapPtr pPixmap; + ScreenPtr pScreen; + int rc; + REQUEST(xCompositeNameWindowPixmapReq); REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); + /* Unsupported by current architecture and porting is too much effort. */ + /* + VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); + */ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); if (!pWin) { client->errorValue = stuff->window; return BadWindow; } - + + pScreen = pWin->drawable.pScreen; + + if (!pWin->viewable) + return BadMatch; + LEGAL_NEW_RESOURCE (stuff->pixmap, client); cw = GetCompWindow (pWin); if (!cw) return BadMatch; - pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); + pPixmap = (*pScreen->GetWindowPixmap) (pWin); if (!pPixmap) return BadMatch; + /* security creation/labeling check */ + /* + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, + pPixmap, RT_WINDOW, pWin, DixCreateAccess); + */ + rc = Success; + if (rc != Success) + return rc; + ++pPixmap->refcnt; if (!AddResource (stuff->pixmap, RT_PIXMAP, (void *) pPixmap)) return BadAlloc; - return(client->noClientException); + /* Unsupported by current architecture. */ + /* + if (pScreen->NameWindowPixmap) { + rc = pScreen->NameWindowPixmap(pWin, pPixmap, stuff->pixmap); + if (rc != Success) { + FreeResource(stuff->pixmap, RT_NONE); + return rc; + } + } + */ + + return Success; +} + +static int +ProcCompositeGetOverlayWindow(ClientPtr client) +{ + REQUEST(xCompositeGetOverlayWindowReq); + xCompositeGetOverlayWindowReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + CompScreenPtr cs; + CompOverlayClientPtr pOc; + int rc; + int n = 0; + + REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); + /* Unsupported by current architecture and porting is too much effort. */ + /* + VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); + */ + pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); + if (!pWin) + { + client->errorValue = stuff->window; + return BadWindow; + } + pScreen = pWin->drawable.pScreen; + + /* + * Create an OverlayClient structure to mark this client's + * interest in the overlay window + */ + pOc = compCreateOverlayClient(pScreen, client); + if (pOc == NULL) + return BadAlloc; + + /* + * Make sure the overlay window exists + */ + cs = GetCompScreen(pScreen); + if (cs->pOverlayWin == NULL) + if (!compCreateOverlayWindow(pScreen)) { + FreeResource(pOc->resource, RT_NONE); + return BadAlloc; + } + + /* + rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id, + RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess); + */ + rc = Success; + if (rc != Success) { + FreeResource(pOc->resource, RT_NONE); + return rc; + } + + rep = (xCompositeGetOverlayWindowReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .overlayWin = cs->pOverlayWin->drawable.id + }; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.overlayWin, n); + } + WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep); + + return Success; } -int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { +static int +ProcCompositeReleaseOverlayWindow(ClientPtr client) +{ + REQUEST(xCompositeReleaseOverlayWindowReq); + WindowPtr pWin; + CompOverlayClientPtr pOc; + + REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); + /* Unsupported by current architecture and porting is too much effort. */ + /* + VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); + */ + pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); + if (!pWin) + { + client->errorValue = stuff->window; + return BadWindow; + } + + /* + * Has client queried a reference to the overlay window + * on this screen? If not, generate an error. + */ + pOc = compFindOverlayClient(pWin->drawable.pScreen, client); + if (pOc == NULL) + return BadMatch; + + /* The delete function will free the client structure */ + FreeResource(pOc->resource, RT_NONE); + + return Success; +} + +static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { ProcCompositeQueryVersion, ProcCompositeRedirectWindow, ProcCompositeRedirectSubwindows, @@ -251,6 +460,7 @@ int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { ProcCompositeUnredirectSubwindows, ProcCompositeCreateRegionFromBorderClip, ProcCompositeNameWindowPixmap, + ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow, }; static int @@ -351,7 +561,31 @@ SProcCompositeNameWindowPixmap (ClientPtr client) return (*ProcCompositeVector[stuff->compositeReqType]) (client); } -int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { +static int +SProcCompositeGetOverlayWindow(ClientPtr client) +{ + int n = 0; + REQUEST(xCompositeGetOverlayWindowReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); + swapl(&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int +SProcCompositeReleaseOverlayWindow(ClientPtr client) +{ + int n = 0; + REQUEST(xCompositeReleaseOverlayWindowReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); + swapl(&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { SProcCompositeQueryVersion, SProcCompositeRedirectWindow, SProcCompositeRedirectSubwindows, @@ -359,6 +593,7 @@ int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { SProcCompositeUnredirectSubwindows, SProcCompositeCreateRegionFromBorderClip, SProcCompositeNameWindowPixmap, + SProcCompositeGetOverlayWindow, SProcCompositeReleaseOverlayWindow, }; static int @@ -372,27 +607,104 @@ SProcCompositeDispatch (ClientPtr client) return BadRequest; } +/* Both unused and incompatible due to architecture, disabled. */ +#if 0 +/** @see GetDefaultBytes */ +static void +GetCompositeClientWindowBytes(void *value, XID id, ResourceSizePtr size) +{ + WindowPtr window = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + if (window->redirectDraw != RedirectDrawNone) + { + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0 }; + ScreenPtr screen = window->drawable.pScreen; + PixmapPtr pixmap = screen->GetWindowPixmap(window); + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} +#endif /* 0 */ + void CompositeExtensionInit (void) { ExtensionEntry *extEntry; int s; + /* Assume initialization is going to fail */ + noCompositeExtension = TRUE; + + fprintf(stderr, "COMPOSITE: trying to initialize extension.\n"); + + for (s = 0; s < screenInfo.numScreens; s++) { + ScreenPtr pScreen = screenInfo.screens[s]; + VisualPtr vis; + + /* Composite on 8bpp pseudocolor root windows appears to fail, so + * just disable it on anything pseudocolor for safety. + */ + for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++); + if ((vis->class | DynamicClass) == PseudoColor) + return; + + /* Ensure that Render is initialized, which is required for automatic + * compositing. + */ + if (GetPictureScreenIfSet(pScreen) == NULL) + return; + } +#ifdef PANORAMIX + /* Xinerama's rewriting of window drawing before Composite gets to it + * breaks Composite. + */ + if (!noPanoramiXExtension) + return; +#endif + CompositeClientWindowType = CreateNewResourceType (FreeCompositeClientWindow); if (!CompositeClientWindowType) return; + /* SetResourceTypeSizeFunc(CompositeClientWindowType, + GetCompositeClientWindowBytes); + */ + CompositeClientSubwindowsType = CreateNewResourceType (FreeCompositeClientSubwindows); if (!CompositeClientSubwindowsType) return; - CompositeClientPrivateIndex = AllocateClientPrivateIndex (); - if (!AllocateClientPrivate (CompositeClientPrivateIndex, + CompositeClientOverlayType = CreateNewResourceType + (FreeCompositeClientOverlay); + if (!CompositeClientOverlayType) + return; + +#ifndef NXAGENT_SERVER + if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT, sizeof (CompositeClientRec))) return; +#else /* !defined(NXAGENT_SERVER) */ + if ((CompositeClientPrivIndex = AllocateClientPrivateIndex()) < 0) + return; + if (!AllocateClientPrivate(CompositeClientPrivIndex, sizeof (CompositeClientRec))) + return; +#endif /* !defined(NXAGENT_SERVER) */ + if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0)) return; + for (s = 0; s < screenInfo.numScreens; s++) + if (!compScreenInit (screenInfo.screens[s])) { + fprintf (stderr, "COMPOSITE: could not initialize via compScreenInit() for screen %d\n", s); + return; + } + extEntry = AddExtension (COMPOSITE_NAME, 0, 0, ProcCompositeDispatch, SProcCompositeDispatch, CompositeResetProc, StandardMinorOpcode); @@ -400,10 +712,371 @@ CompositeExtensionInit (void) return; CompositeReqCode = (CARD8) extEntry->base; - - for (s = 0; s < screenInfo.numScreens; s++) - if (!compScreenInit (screenInfo.screens[s])) - return; - miRegisterRedirectBorderClipProc (compSetRedirectBorderClip, - compGetRedirectBorderClip); + /* Initialization succeeded */ + noCompositeExtension = FALSE; +} + +/* + * This code requires features the current infrastructure does not provide + * and will thus be disabled. + */ +#if 0 + +#ifdef PANORAMIX +#include "panoramiXsrv.h" + +int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr); + +static int +PanoramiXCompositeRedirectWindow(ClientPtr client) +{ + PanoramiXRes *win; + int rc = 0, j; + + REQUEST(xCompositeRedirectWindowReq); + + REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); + + if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); + if (rc != Success) + break; + } + + return rc; +} + +static int +PanoramiXCompositeRedirectSubwindows(ClientPtr client) +{ + PanoramiXRes *win; + int rc = 0, j; + + REQUEST(xCompositeRedirectSubwindowsReq); + + REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); + + if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); + if (rc != Success) + break; + } + + return rc; +} + +static int +PanoramiXCompositeUnredirectWindow(ClientPtr client) +{ + PanoramiXRes *win; + int rc = 0, j; + + REQUEST(xCompositeUnredirectWindowReq); + + REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); + + if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); + if (rc != Success) + break; + } + + return rc; +} + +static int +PanoramiXCompositeUnredirectSubwindows(ClientPtr client) +{ + PanoramiXRes *win; + int rc = 0, j; + + REQUEST(xCompositeUnredirectSubwindowsReq); + + REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); + + if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_FORWARD(j) { + stuff->window = win->info[j].id; + rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); + if (rc != Success) + break; + } + + return rc; } + +static int +PanoramiXCompositeNameWindowPixmap(ClientPtr client) +{ + WindowPtr pWin; + CompWindowPtr cw; + PixmapPtr pPixmap; + int rc; + PanoramiXRes *win, *newPix; + int i; + + REQUEST(xCompositeNameWindowPixmapReq); + + REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); + + if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + LEGAL_NEW_RESOURCE(stuff->pixmap, client); + + if (!(newPix = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPix->type = XRT_PIXMAP; + newPix->u.pix.shared = FALSE; + panoramix_setup_ids(newPix, client, stuff->pixmap); + + FOR_NSCREENS(i) { + rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, + RT_WINDOW, client, DixGetAttrAccess); + if (rc != Success) { + client->errorValue = stuff->window; + free(newPix); + return rc; + } + + if (!pWin->viewable) { + free(newPix); + return BadMatch; + } + + cw = GetCompWindow(pWin); + if (!cw) { + free(newPix); + return BadMatch; + } + + pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); + if (!pPixmap) { + free(newPix); + return BadMatch; + } + + if (!AddResource(newPix->info[i].id, RT_PIXMAP, (void *) pPixmap)) + return BadAlloc; + + ++pPixmap->refcnt; + } + + if (!AddResource(stuff->pixmap, XRT_PIXMAP, (void *) newPix)) + return BadAlloc; + + return Success; +} + +static int +PanoramiXCompositeGetOverlayWindow(ClientPtr client) +{ + REQUEST(xCompositeGetOverlayWindowReq); + xCompositeGetOverlayWindowReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + CompScreenPtr cs; + CompOverlayClientPtr pOc; + int rc; + PanoramiXRes *win, *overlayWin = NULL; + int i; + int n = 0; + + REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); + + if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + cs = GetCompScreen(screenInfo.screens[0]); + if (!cs->pOverlayWin) { + if (!(overlayWin = malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + overlayWin->type = XRT_WINDOW; + overlayWin->u.win.root = FALSE; + } + + FOR_NSCREENS_BACKWARD(i) { + rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, + RT_WINDOW, client, DixGetAttrAccess); + if (rc != Success) { + client->errorValue = stuff->window; + free(overlayWin); + return rc; + } + pScreen = pWin->drawable.pScreen; + + /* + * Create an OverlayClient structure to mark this client's + * interest in the overlay window + */ + pOc = compCreateOverlayClient(pScreen, client); + if (pOc == NULL) { + free(overlayWin); + return BadAlloc; + } + + /* + * Make sure the overlay window exists + */ + cs = GetCompScreen(pScreen); + if (cs->pOverlayWin == NULL) + if (!compCreateOverlayWindow(pScreen)) { + FreeResource(pOc->resource, RT_NONE); + free(overlayWin); + return BadAlloc; + } + + /* + rc = XaceHook(XACE_RESOURCE_ACCESS, client, + cs->pOverlayWin->drawable.id, + RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, + DixGetAttrAccess); + */ + rc = Success; + if (rc != Success) { + FreeResource(pOc->resource, RT_NONE); + free(overlayWin); + return rc; + } + } + + if (overlayWin) { + FOR_NSCREENS(i) { + cs = GetCompScreen(screenInfo.screens[i]); + overlayWin->info[i].id = cs->pOverlayWin->drawable.id; + } + + AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin); + } + + cs = GetCompScreen(screenInfo.screens[0]); + + rep = (xCompositeGetOverlayWindowReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .overlayWin = cs->pOverlayWin->drawable.id + }; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.overlayWin, n); + } + WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep); + + return Success; +} + +static int +PanoramiXCompositeReleaseOverlayWindow(ClientPtr client) +{ + REQUEST(xCompositeReleaseOverlayWindowReq); + WindowPtr pWin; + CompOverlayClientPtr pOc; + PanoramiXRes *win; + int i, rc; + + REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); + + if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, + client, DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + FOR_NSCREENS_BACKWARD(i) { + if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, + XRT_WINDOW, client, + DixUnknownAccess))) { + client->errorValue = stuff->window; + return rc; + } + + /* + * Has client queried a reference to the overlay window + * on this screen? If not, generate an error. + */ + pOc = compFindOverlayClient(pWin->drawable.pScreen, client); + if (pOc == NULL) + return BadMatch; + + /* The delete function will free the client structure */ + FreeResource(pOc->resource, RT_NONE); + } + + return Success; +} + +void +PanoramiXCompositeInit(void) +{ + int i; + + for (i = 0; i < CompositeNumberRequests; i++) + PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i]; + /* + * Stuff in Xinerama aware request processing hooks + */ + ProcCompositeVector[X_CompositeRedirectWindow] = + PanoramiXCompositeRedirectWindow; + ProcCompositeVector[X_CompositeRedirectSubwindows] = + PanoramiXCompositeRedirectSubwindows; + ProcCompositeVector[X_CompositeUnredirectWindow] = + PanoramiXCompositeUnredirectWindow; + ProcCompositeVector[X_CompositeUnredirectSubwindows] = + PanoramiXCompositeUnredirectSubwindows; + ProcCompositeVector[X_CompositeNameWindowPixmap] = + PanoramiXCompositeNameWindowPixmap; + ProcCompositeVector[X_CompositeGetOverlayWindow] = + PanoramiXCompositeGetOverlayWindow; + ProcCompositeVector[X_CompositeReleaseOverlayWindow] = + PanoramiXCompositeReleaseOverlayWindow; +} + +void +PanoramiXCompositeReset(void) +{ + int i; + + for (i = 0; i < CompositeNumberRequests; i++) + ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i]; +} + +#endif + +#endif /* 0 */ |