diff options
-rw-r--r-- | composite/compalloc.c | 47 | ||||
-rw-r--r-- | composite/compint.h | 5 | ||||
-rw-r--r-- | composite/compwindow.c | 16 |
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; |