From: Ville Syrjälä <[email protected]>

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: Ville Syrjälä <[email protected]>
---
 composite/compalloc.c  |   42 +++++++++++++++++++++++++++++++++++++++---
 composite/compint.h    |    5 ++++-
 composite/compwindow.c |   14 ++++++++++----
 3 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 233fb10..f3dbde8 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -206,6 +206,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
@@ -217,6 +245,7 @@ compFreeClientWindow (WindowPtr pWin, XID id)
     CompClientWindowPtr        ccw, *prev;
     Bool               anyMarked = FALSE;
     WindowPtr          pLayerWin;
+    PixmapPtr           pPixmap = NULL;
 
     if (!cw)
        return;
@@ -237,7 +266,7 @@ compFreeClientWindow (WindowPtr pWin, XID id)
            anyMarked = compMarkWindows (pWin, &pLayerWin);
     
        if (pWin->redirectDraw != RedirectDrawNone)
-           compFreePixmap (pWin);
+           pPixmap = compFreePixmap (pWin);
 
        if (cw->damage)
            DamageDestroy (cw->damage);
@@ -258,6 +287,12 @@ compFreeClientWindow (WindowPtr pWin, XID id)
 
     if (anyMarked)
        compHandleMarkedWindows (pWin, pLayerWin);
+
+    if (pPixmap) {
+       ScreenPtr pScreen = pWin->drawable.pScreen;
+       compRestoreWindow (pWin, pPixmap);
+       (*pScreen->DestroyPixmap) (pPixmap);
+    }
 }
 
 /*
@@ -588,7 +623,7 @@ compAllocPixmap (WindowPtr pWin)
     return TRUE;
 }
 
-void
+PixmapPtr
 compFreePixmap (WindowPtr pWin)
 {
     ScreenPtr      pScreen = pWin->drawable.pScreen;
@@ -612,7 +647,8 @@ compFreePixmap (WindowPtr pWin)
     pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
     pWin->redirectDraw = RedirectDrawNone;
     compSetPixmap (pWin, pParentPixmap);
-    (*pScreen->DestroyPixmap) (pRedirectPixmap);
+
+    return pRedirectPixmap;
 }
 
 /*
diff --git a/composite/compint.h b/composite/compint.h
index 80083b0..9e1636b 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -213,9 +213,12 @@ compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr 
pWin);
 Bool
 compAllocPixmap (WindowPtr pWin);
 
-void
+PixmapPtr
 compFreePixmap (WindowPtr pWin);
 
+void
+compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap);
+
 Bool
 compReallocPixmap (WindowPtr pWin, int x, int y,
                   unsigned int w, unsigned int h, int bw);
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 4dab135..3666def 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -160,8 +160,12 @@ compCheckRedirect (WindowPtr pWin)
     {
        if (should)
            return compAllocPixmap (pWin);
-       else
-           compFreePixmap (pWin);
+       else {
+           ScreenPtr pScreen = pWin->drawable.pScreen;
+           PixmapPtr pPixmap = compFreePixmap (pWin);
+           compRestoreWindow (pWin, pPixmap);
+           (*pScreen->DestroyPixmap) (pPixmap);
+       }
     }
     return TRUE;
 }
@@ -569,8 +573,10 @@ 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 = compFreePixmap (pWin);
+       (*pScreen->DestroyPixmap) (pPixmap);
+    }
     ret = (*pScreen->DestroyWindow) (pWin);
     cs->DestroyWindow = pScreen->DestroyWindow;
     pScreen->DestroyWindow = compDestroyWindow;
-- 
1.7.2.2

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to