/* Fake backing store via automatic redirection */ static Bool compChangeWindowAttributes(WindowPtr pWin, unsigned long mask) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen (pScreen); Bool ret; pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; ret = pScreen->ChangeWindowAttributes(pWin, mask); if (ret && (mask & CWBackingStore) && pScreen->backingStoreSupport != NotUseful) { if (pWin->backingStore != NotUseful) { compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); pWin->backStorage = (pointer) (intptr_t) 1; } else { compUnredirectWindow(serverClient, pWin, CompositeRedirectAutomatic); pWin->backStorage = NULL; } } pScreen->ChangeWindowAttributes = compChangeWindowAttributes; return ret; }
static void compCheckBackingStore(WindowPtr pWin) { if (pWin->backingStore != NotUseful && !pWin->backStorage) { compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); pWin->backStorage = TRUE; } else if (pWin->backingStore == NotUseful && pWin->backStorage) { compUnredirectWindow(serverClient, pWin, CompositeRedirectAutomatic); pWin->backStorage = FALSE; } }
static int ProcCompositeRedirectWindow (ClientPtr client) { WindowPtr pWin; REQUEST(xCompositeRedirectWindowReq); REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); if (!pWin) { client->errorValue = stuff->window; return BadWindow; } return compRedirectWindow (client, pWin, stuff->update); }
int compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin) { CompSubwindowsPtr csw = GetCompSubwindows (pParent); CompClientWindowPtr ccw; if (!csw) return Success; for (ccw = csw->clients; ccw; ccw = ccw->next) { int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)], pWin, ccw->update); if (ret != Success) return ret; } return Success; }
int compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update) { CompSubwindowsPtr csw = GetCompSubwindows (pWin); CompClientWindowPtr ccw; WindowPtr pChild; /* * Only one Manual update is allowed */ if (csw && update == CompositeRedirectManual) for (ccw = csw->clients; ccw; ccw = ccw->next) if (ccw->update == CompositeRedirectManual) return BadAccess; /* * Allocate per-client per-window structure * The client *could* allocate multiple, but while supported, * it is not expected to be common */ ccw = malloc(sizeof (CompClientWindowRec)); if (!ccw) return BadAlloc; ccw->id = FakeClientID (pClient->index); ccw->update = update; /* * Now make sure there's a per-window structure to hang this from */ if (!csw) { csw = malloc(sizeof (CompSubwindowsRec)); if (!csw) { free(ccw); return BadAlloc; } csw->update = CompositeRedirectAutomatic; csw->clients = 0; dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, csw); } /* * Redirect all existing windows */ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) { int ret = compRedirectWindow (pClient, pChild, update); if (ret != Success) { for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib) (void) compUnredirectWindow (pClient, pChild, update); if (!csw->clients) { free(csw); dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, 0); } free(ccw); return ret; } } /* * Hook into subwindows list */ ccw->next = csw->clients; csw->clients = ccw; if (!AddResource (ccw->id, CompositeClientSubwindowsType, pWin)) return BadAlloc; if (ccw->update == CompositeRedirectManual) { csw->update = CompositeRedirectManual; /* * tell damage extension that damage events for this client are * critical output */ DamageExtSetCritical (pClient, TRUE); } return Success; }