diff options
author | Ben Byer <bbyer@bbyer.local> | 2007-11-15 00:56:54 -0800 |
---|---|---|
committer | Jeremy Huddleston <jeremy@tifa.local> | 2007-11-21 23:18:34 -0800 |
commit | 74214a9f42b931f99d83ddb4efb3720881a2de16 (patch) | |
tree | 2ee8e383a1a24cc8073f893f01e48e22824dd063 /miext | |
parent | f5f833b80609f1f98c93113183bd2b1bab3bfec9 (diff) |
Darwin: Patch to avert (some) damage / rootless crashes, courtesy of Ken Thomases
(cherry picked from commit 148a87ff20aa5e7a6d839610aa14fa1a31505c4a)
Diffstat (limited to 'miext')
-rw-r--r-- | miext/rootless/rootless.h | 1 | ||||
-rw-r--r-- | miext/rootless/rootlessCommon.c | 45 | ||||
-rw-r--r-- | miext/rootless/rootlessCommon.h | 1 | ||||
-rw-r--r-- | miext/rootless/rootlessScreen.c | 5 | ||||
-rw-r--r-- | miext/rootless/rootlessWindow.c | 1 |
5 files changed, 49 insertions, 4 deletions
diff --git a/miext/rootless/rootless.h b/miext/rootless/rootless.h index b4a5b2a3d..5224dca2b 100644 --- a/miext/rootless/rootless.h +++ b/miext/rootless/rootless.h @@ -66,7 +66,6 @@ typedef struct _RootlessWindowRec { int bytesPerRow; PixmapPtr pixmap; - PixmapPtr oldPixmap; #ifdef ROOTLESS_TRACK_DAMAGE RegionRec damage; diff --git a/miext/rootless/rootlessCommon.c b/miext/rootless/rootlessCommon.c index 03842e4be..562f65577 100644 --- a/miext/rootless/rootlessCommon.c +++ b/miext/rootless/rootlessCommon.c @@ -172,8 +172,24 @@ void RootlessStartDrawing(WindowPtr pWindow) winRec->is_drawing = TRUE; } - winRec->oldPixmap = pScreen->GetWindowPixmap(pWindow); - pScreen->SetWindowPixmap(pWindow, winRec->pixmap); + PixmapPtr curPixmap = pScreen->GetWindowPixmap(pWindow); + if (curPixmap == winRec->pixmap) + { + RL_DEBUG_MSG("Window %p already has winRec->pixmap %p; not pushing\n", pWindow, winRec->pixmap); + } + else + { + PixmapPtr oldPixmap = pWindow->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr; + if (oldPixmap != NULL) + { + if (oldPixmap == curPixmap) + RL_DEBUG_MSG("Window %p's curPixmap %p is the same as its oldPixmap; strange\n", pWindow, curPixmap); + else + RL_DEBUG_MSG("Window %p's existing oldPixmap %p being lost!\n", pWindow, oldPixmap); + } + pWindow->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr = curPixmap; + pScreen->SetWindowPixmap(pWindow, winRec->pixmap); + } } @@ -182,6 +198,29 @@ void RootlessStartDrawing(WindowPtr pWindow) * Stop drawing to a window's backing buffer. If flush is true, * damaged regions are flushed to the screen. */ +static int RestorePreDrawingPixmapVisitor(WindowPtr pWindow, pointer data) +{ + RootlessWindowRec *winRec = (RootlessWindowRec*)data; + ScreenPtr pScreen = pWindow->drawable.pScreen; + PixmapPtr exPixmap = pScreen->GetWindowPixmap(pWindow); + PixmapPtr oldPixmap = pWindow->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr; + if (oldPixmap == NULL) + { + if (exPixmap == winRec->pixmap) + RL_DEBUG_MSG("Window %p appears to be in drawing mode (ex-pixmap %p equals winRec->pixmap, which is being freed) but has no oldPixmap!\n", pWindow, exPixmap); + } + else + { + if (exPixmap != winRec->pixmap) + RL_DEBUG_MSG("Window %p appears to be in drawing mode (oldPixmap %p) but ex-pixmap %p not winRec->pixmap %p!\n", pWindow, oldPixmap, exPixmap, winRec->pixmap); + if (oldPixmap == winRec->pixmap) + RL_DEBUG_MSG("Window %p's oldPixmap %p is winRec->pixmap, which has just been freed!\n", pWindow, oldPixmap); + pScreen->SetWindowPixmap(pWindow, oldPixmap); + pWindow->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr = NULL; + } + return WT_WALKCHILDREN; +} + void RootlessStopDrawing(WindowPtr pWindow, Bool flush) { ScreenPtr pScreen = pWindow->drawable.pScreen; @@ -198,7 +237,7 @@ void RootlessStopDrawing(WindowPtr pWindow, Bool flush) SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush); FreeScratchPixmapHeader(winRec->pixmap); - pScreen->SetWindowPixmap(pWindow, winRec->oldPixmap); + TraverseTree(top, RestorePreDrawingPixmapVisitor, (pointer)winRec); winRec->pixmap = NULL; winRec->is_drawing = FALSE; diff --git a/miext/rootless/rootlessCommon.h b/miext/rootless/rootlessCommon.h index d6a0161ce..fd8725a0c 100644 --- a/miext/rootless/rootlessCommon.h +++ b/miext/rootless/rootlessCommon.h @@ -60,6 +60,7 @@ extern int rootlessGCPrivateIndex; extern int rootlessScreenPrivateIndex; extern int rootlessWindowPrivateIndex; +extern int rootlessWindowOldPixmapPrivateIndex; // RootlessGCRec: private per-gc data diff --git a/miext/rootless/rootlessScreen.c b/miext/rootless/rootlessScreen.c index 6b54042a8..538b698c8 100644 --- a/miext/rootless/rootlessScreen.c +++ b/miext/rootless/rootlessScreen.c @@ -65,6 +65,7 @@ extern Bool RootlessCreateGC(GCPtr pGC); int rootlessGCPrivateIndex = -1; int rootlessScreenPrivateIndex = -1; int rootlessWindowPrivateIndex = -1; +int rootlessWindowOldPixmapPrivateIndex = -1; /* @@ -618,6 +619,8 @@ RootlessAllocatePrivates(ScreenPtr pScreen) if (rootlessGCPrivateIndex == -1) return FALSE; rootlessWindowPrivateIndex = AllocateWindowPrivateIndex(); if (rootlessWindowPrivateIndex == -1) return FALSE; + rootlessWindowOldPixmapPrivateIndex = AllocateWindowPrivateIndex(); + if (rootlessWindowOldPixmapPrivateIndex == -1) return FALSE; rootlessGeneration = serverGeneration; } @@ -627,6 +630,8 @@ RootlessAllocatePrivates(ScreenPtr pScreen) return FALSE; if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0)) return FALSE; + if (!AllocateWindowPrivate(pScreen, rootlessWindowOldPixmapPrivateIndex, 0)) + return FALSE; s = xalloc(sizeof(RootlessScreenRec)); if (! s) return FALSE; diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c index 3074a3fc5..14bc67452 100644 --- a/miext/rootless/rootlessWindow.c +++ b/miext/rootless/rootlessWindow.c @@ -198,6 +198,7 @@ RootlessCreateWindow(WindowPtr pWin) RegionRec saveRoot; WINREC(pWin) = NULL; + pWin->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr = NULL; SCREEN_UNWRAP(pWin->drawable.pScreen, CreateWindow); |