Ejemplo n.º 1
0
/*
 * Free one of the per-client per-window resources, clearing
 * redirect and the per-window pointer as appropriate
 */
void
compFreeClientWindow (WindowPtr pWin, XID id)
{
    ScreenPtr		pScreen = pWin->drawable.pScreen;
    CompWindowPtr	cw = GetCompWindow (pWin);
    CompClientWindowPtr	ccw, *prev;
    Bool		anyMarked = FALSE;
    WindowPtr		pLayerWin;
    PixmapPtr           pPixmap = NULL;

    if (!cw)
	return;
    for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next)
    {
	if (ccw->id == id)
	{
	    *prev = ccw->next;
	    if (ccw->update == CompositeRedirectManual)
		cw->update = CompositeRedirectAutomatic;
	    free(ccw);
	    break;
	}
    }
    if (!cw->clients)
    {
	anyMarked = compMarkWindows (pWin, &pLayerWin);
    
	if (pWin->redirectDraw != RedirectDrawNone) {
	    pPixmap = (*pScreen->GetWindowPixmap) (pWin);
	    compSetParentPixmap (pWin);
	}

	if (cw->damage)
	    DamageDestroy (cw->damage);
	
	RegionUninit(&cw->borderClip);
    
	dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL);
	free(cw);
    }
    else if (cw->update == CompositeRedirectAutomatic &&
	     !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
    {
	anyMarked = compMarkWindows (pWin, &pLayerWin);

	DamageRegister (&pWin->drawable, cw->damage);
	cw->damageRegistered = TRUE;
	pWin->redirectDraw = RedirectDrawAutomatic;
	DamageDamageRegion(&pWin->drawable, &pWin->borderSize);
    }

    if (anyMarked)
	compHandleMarkedWindows (pWin, pLayerWin);

    if (pPixmap) {
	compRestoreWindow (pWin, pPixmap);
	(*pScreen->DestroyPixmap) (pPixmap);
    }
}
Ejemplo n.º 2
0
/*
 * Redirect one window for one client
 */
int
compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update)
{
    CompWindowPtr cw = GetCompWindow(pWin);
    CompClientWindowPtr ccw;
    CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
    WindowPtr pLayerWin = NULL;
    Bool anyMarked = FALSE;

    if (pWin == cs->pOverlayWin) {
        return Success;
    }

    if (!pWin->parent)
        return BadMatch;

    /*
     * Only one Manual update is allowed
     */
    if (cw && update == CompositeRedirectManual)
        for (ccw = cw->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 (!cw) {
        cw = malloc(sizeof(CompWindowRec));
        if (!cw) {
            free(ccw);
            return BadAlloc;
        }
        cw->damage = DamageCreate(compReportDamage,
                                  compDestroyDamage,
                                  DamageReportNonEmpty,
                                  FALSE, pWin->drawable.pScreen, pWin);
        if (!cw->damage) {
            free(ccw);
            free(cw);
            return BadAlloc;
        }

        anyMarked = compMarkWindows(pWin, &pLayerWin);

        RegionNull(&cw->borderClip);
        cw->update = CompositeRedirectAutomatic;
        cw->clients = 0;
        cw->oldx = COMP_ORIGIN_INVALID;
        cw->oldy = COMP_ORIGIN_INVALID;
        cw->damageRegistered = FALSE;
        cw->damaged = FALSE;
        cw->pOldPixmap = NullPixmap;
        dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw);
    }
    ccw->next = cw->clients;
    cw->clients = ccw;
    if (!AddResource(ccw->id, CompositeClientWindowType, pWin))
        return BadAlloc;
    if (ccw->update == CompositeRedirectManual) {
        if (!anyMarked)
            anyMarked = compMarkWindows(pWin, &pLayerWin);

        if (cw->damageRegistered) {
            DamageUnregister(&pWin->drawable, cw->damage);
            cw->damageRegistered = FALSE;
        }
        cw->update = CompositeRedirectManual;
    }
    else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) {
        if (!anyMarked)
            anyMarked = compMarkWindows(pWin, &pLayerWin);
    }

    if (!compCheckRedirect(pWin)) {
        FreeResource(ccw->id, RT_NONE);
        return BadAlloc;
    }

    if (anyMarked)
        compHandleMarkedWindows(pWin, pLayerWin);

    return Success;
}