Commit 74663e61 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

composite: Copy the window contents back from the pixmap



Since extra expose events are no longer generated during window
unredirection, the window contents must be preserved by the server.
So copy the window contents back from the pixmap. The copy can only
be done after the clips have been recomputed, so delay the copy and
the pixmap destruction until ValidateTree is done. Window borders are
restored by HandleExposures and thus don't need to be copied back.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@nokia.com>
Reviewed-by: Daniel Stone's avatarDaniel Stone <daniel@fooishbar.org>
parent 193ecc8b
......@@ -239,6 +239,34 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
return Success;
}
void
compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
WindowPtr pParent = pWin->parent;
if (pParent->drawable.depth == pWin->drawable.depth) {
GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
int bw = (int) pWin->borderWidth;
int x = bw;
int y = bw;
int w = pWin->drawable.width;
int h = pWin->drawable.height;
if (pGC) {
ChangeGCVal val;
val.val = IncludeInferiors;
ChangeGC (NullClient, pGC, GCSubwindowMode, &val);
ValidateGC(&pWin->drawable, pGC);
(*pGC->ops->CopyArea) (&pPixmap->drawable,
&pWin->drawable,
pGC,
x, y, w, h, 0, 0);
FreeScratchGC (pGC);
}
}
}
/*
* Free one of the per-client per-window resources, clearing
* redirect and the per-window pointer as appropriate
......@@ -246,10 +274,12 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
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;
......@@ -268,8 +298,10 @@ compFreeClientWindow (WindowPtr pWin, XID id)
{
anyMarked = compMarkWindows (pWin, &pLayerWin);
if (pWin->redirectDraw != RedirectDrawNone)
compFreePixmap (pWin);
if (pWin->redirectDraw != RedirectDrawNone) {
pPixmap = (*pScreen->GetWindowPixmap) (pWin);
compSetParentPixmap (pWin);
}
if (cw->damage)
DamageDestroy (cw->damage);
......@@ -290,6 +322,11 @@ compFreeClientWindow (WindowPtr pWin, XID id)
if (anyMarked)
compHandleMarkedWindows (pWin, pLayerWin);
if (pPixmap) {
compRestoreWindow (pWin, pPixmap);
(*pScreen->DestroyPixmap) (pPixmap);
}
}
/*
......@@ -621,10 +658,10 @@ compAllocPixmap (WindowPtr pWin)
}
void
compFreePixmap (WindowPtr pWin)
compSetParentPixmap (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pRedirectPixmap, pParentPixmap;
PixmapPtr pParentPixmap;
CompWindowPtr cw = GetCompWindow (pWin);
if (cw->damageRegistered)
......@@ -640,11 +677,9 @@ compFreePixmap (WindowPtr pWin)
* parent exposed area; regions beyond the parent cause crashes
*/
RegionCopy(&pWin->borderClip, &cw->borderClip);
pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
pWin->redirectDraw = RedirectDrawNone;
compSetPixmap (pWin, pParentPixmap);
(*pScreen->DestroyPixmap) (pRedirectPixmap);
}
/*
......
......@@ -215,7 +215,10 @@ Bool
compAllocPixmap (WindowPtr pWin);
void
compFreePixmap (WindowPtr pWin);
compSetParentPixmap (WindowPtr pWin);
void
compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap);
Bool
compReallocPixmap (WindowPtr pWin, int x, int y,
......
......@@ -164,8 +164,13 @@ compCheckRedirect (WindowPtr pWin)
{
if (should)
return compAllocPixmap (pWin);
else
compFreePixmap (pWin);
else {
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
compSetParentPixmap (pWin);
compRestoreWindow (pWin, pPixmap);
(*pScreen->DestroyPixmap) (pPixmap);
}
}
return TRUE;
}
......@@ -583,8 +588,11 @@ compDestroyWindow (WindowPtr pWin)
while ((csw = GetCompSubwindows (pWin)))
FreeResource (csw->clients->id, RT_NONE);
if (pWin->redirectDraw != RedirectDrawNone)
compFreePixmap (pWin);
if (pWin->redirectDraw != RedirectDrawNone) {
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
compSetParentPixmap (pWin);
(*pScreen->DestroyPixmap) (pPixmap);
}
ret = (*pScreen->DestroyWindow) (pWin);
cs->DestroyWindow = pScreen->DestroyWindow;
pScreen->DestroyWindow = compDestroyWindow;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment