Beispiel #1
0
/* 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;
}
Beispiel #2
0
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;
    }
}
Beispiel #3
0
static int
ProcCompositeUnredirectWindow (ClientPtr client)
{
    WindowPtr	pWin;
    REQUEST(xCompositeUnredirectWindowReq);

    REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
    pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
    if (!pWin)
    {
	client->errorValue = stuff->window;
	return BadWindow;
    }
    return compUnredirectWindow (client, pWin, stuff->update);
}
Beispiel #4
0
/*
 * 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);
    }
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}