summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--composite/compalloc.c47
-rw-r--r--composite/compint.h5
-rw-r--r--composite/compwindow.c16
3 files changed, 57 insertions, 11 deletions
diff --git a/composite/compalloc.c b/composite/compalloc.c
index 23654a7bd..37d2245d4 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -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);
}
/*
diff --git a/composite/compint.h b/composite/compint.h
index 57e0b5dea..bb5335d70 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -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,
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 2440f1897..bcbdf3572 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -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;