/* * $Id: compext.c,v 1.5 2005/07/03 07:37:34 daniels Exp $ * * Copyright © 2003 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "compint.h" #include "XI.h" #include "XIproto.h" #include "protocol-versions.h" #include "extinit.h" static CARD8 CompositeReqCode; #ifndef NXAGENT_SERVER static DevPrivateKeyRec CompositeClientPrivateKeyRec; #define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec) #else /* !defined(NXAGENT_SERVER) */ #include "../hw/nxagent/Options.h" 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; #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, void *closure, void *data) { NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; ClientPtr pClient = clientinfo->client; CompositeClientPtr pCompositeClient = GetCompositeClient (pClient); pCompositeClient->major_version = 0; pCompositeClient->minor_version = 0; } static void CompositeResetProc (ExtensionEntry *extEntry) { } static int FreeCompositeClientWindow(void *value, XID ccwid) { WindowPtr pWin = value; compFreeClientWindow(pWin, ccwid); return Success; } static int FreeCompositeClientSubwindows(void *value, XID ccwid) { WindowPtr pWin = value; compFreeClientSubwindows(pWin, ccwid); return Success; } static int FreeCompositeClientOverlay(void *value, XID ccwid) { CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; compFreeOverlayClient(pOc); return Success; } static int ProcCompositeQueryVersion (ClientPtr client) { CompositeClientPtr pCompositeClient = GetCompositeClient (client); xCompositeQueryVersionReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; REQUEST(xCompositeQueryVersionReq); REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; } else { rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION; rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION; } pCompositeClient->major_version = rep.majorVersion; pCompositeClient->minor_version = rep.minorVersion; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.majorVersion); swapl(&rep.minorVersion); } WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep); 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) { WindowPtr pWin; 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); } static int ProcCompositeRedirectSubwindows (ClientPtr client) { WindowPtr pWin; 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); } static int ProcCompositeUnredirectWindow (ClientPtr client) { WindowPtr pWin; 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); } static int ProcCompositeUnredirectSubwindows (ClientPtr client) { WindowPtr pWin; 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); } static int ProcCompositeCreateRegionFromBorderClip (ClientPtr client) { WindowPtr pWin; CompWindowPtr cw; RegionPtr pBorderClip, pRegion; 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); if (cw) pBorderClip = &cw->borderClip; else pBorderClip = &pWin->borderClip; pRegion = XFixesRegionCopy (pBorderClip); if (!pRegion) return BadAlloc; RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y); if (!AddResource (stuff->region, RegionResType, (void *) pRegion)) return BadAlloc; return Success; } static int 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 = (*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; /* 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; 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); swapl(&rep.length); swapl(&rep.overlayWin); } WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep); return Success; } 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, ProcCompositeUnredirectWindow, ProcCompositeUnredirectSubwindows, ProcCompositeCreateRegionFromBorderClip, ProcCompositeNameWindowPixmap, ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow, }; static int ProcCompositeDispatch (ClientPtr client) { REQUEST(xReq); if (stuff->data < CompositeNumberRequests) return (*ProcCompositeVector[stuff->data]) (client); else return BadRequest; } static int SProcCompositeQueryVersion (ClientPtr client) { REQUEST(xCompositeQueryVersionReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); swapl(&stuff->majorVersion); swapl(&stuff->minorVersion); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int SProcCompositeRedirectWindow (ClientPtr client) { REQUEST(xCompositeRedirectWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); swapl (&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int SProcCompositeRedirectSubwindows (ClientPtr client) { REQUEST(xCompositeRedirectSubwindowsReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); swapl (&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int SProcCompositeUnredirectWindow (ClientPtr client) { REQUEST(xCompositeUnredirectWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); swapl (&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int SProcCompositeUnredirectSubwindows (ClientPtr client) { REQUEST(xCompositeUnredirectSubwindowsReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); swapl (&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int SProcCompositeCreateRegionFromBorderClip (ClientPtr client) { REQUEST(xCompositeCreateRegionFromBorderClipReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); swapl (&stuff->region); swapl (&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int SProcCompositeNameWindowPixmap (ClientPtr client) { REQUEST(xCompositeNameWindowPixmapReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); swapl (&stuff->window); swapl (&stuff->pixmap); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int SProcCompositeGetOverlayWindow(ClientPtr client) { REQUEST(xCompositeGetOverlayWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int SProcCompositeReleaseOverlayWindow(ClientPtr client) { REQUEST(xCompositeReleaseOverlayWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { SProcCompositeQueryVersion, SProcCompositeRedirectWindow, SProcCompositeRedirectSubwindows, SProcCompositeUnredirectWindow, SProcCompositeUnredirectSubwindows, SProcCompositeCreateRegionFromBorderClip, SProcCompositeNameWindowPixmap, SProcCompositeGetOverlayWindow, SProcCompositeReleaseOverlayWindow, }; static int SProcCompositeDispatch (ClientPtr client) { REQUEST(xReq); if (stuff->data < CompositeNumberRequests) return (*SProcCompositeVector[stuff->data]) (client); else 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; #ifdef NXAGENT_SERVER if (!nxagentOption(Composite)) return; #endif 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; 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); if (!extEntry) return; CompositeReqCode = (CARD8) extEntry->base; /* 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; 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); swapl(&rep.length); swapl(&rep.overlayWin); } 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 */