int compUnredirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update) { CompSubwindowsPtr csw = GetCompSubwindows(pWin); CompClientWindowPtr ccw; if (!csw) return BadValue; for (ccw = csw->clients; ccw; ccw = ccw->next) if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index) { FreeResource(ccw->id, RT_NONE); return Success; } return BadValue; }
/* * Free one of the per-client per-subwindows resources, * which frees one redirect per subwindow */ void compFreeClientSubwindows (WindowPtr pWin, XID id) { CompSubwindowsPtr csw = GetCompSubwindows (pWin); CompClientWindowPtr ccw, *prev; WindowPtr pChild; if (!csw) return; for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next) { if (ccw->id == id) { ClientPtr pClient = clients[CLIENT_ID(id)]; *prev = ccw->next; if (ccw->update == CompositeRedirectManual) { /* * tell damage extension that damage events for this client are * critical output */ DamageExtSetCritical (pClient, FALSE); csw->update = CompositeRedirectAutomatic; if (pWin->mapped) (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE); } /* * Unredirect all existing subwindows */ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) (void) compUnredirectWindow (pClient, pChild, ccw->update); free(ccw); break; } } /* * Check if all of the per-client records are gone */ if (!csw->clients) { dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, NULL); free(csw); } }
int compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin) { CompSubwindowsPtr csw = GetCompSubwindows (pParent); CompClientWindowPtr ccw; if (!csw) return Success; for (ccw = csw->clients; ccw; ccw = ccw->next) { int ret = compUnredirectWindow (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; }