summaryrefslogtreecommitdiff
path: root/miext/rootless
diff options
context:
space:
mode:
authorBen Byer <bbyer@bbyer.local>2007-11-15 00:56:54 -0800
committerJeremy Huddleston <jeremy@tifa.local>2007-11-19 02:38:23 -0800
commit148a87ff20aa5e7a6d839610aa14fa1a31505c4a (patch)
tree0f6ebe6f743cc170f91b5aec42cc18be1eafb5bd /miext/rootless
parent0cf45239c21326de8bbd3d2b6f3d68685173ceb3 (diff)
Patch to avert (some) damage / rootless crashes, courtesy of Ken Thomases
Diffstat (limited to 'miext/rootless')
-rw-r--r--miext/rootless/rootless.h1
-rw-r--r--miext/rootless/rootlessCommon.c45
-rw-r--r--miext/rootless/rootlessCommon.h1
-rw-r--r--miext/rootless/rootlessScreen.c5
-rw-r--r--miext/rootless/rootlessWindow.c1
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 fc22b1b89..9771ac9b1 100644
--- a/miext/rootless/rootlessCommon.c
+++ b/miext/rootless/rootlessCommon.c
@@ -169,8 +169,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);
+ }
}
@@ -179,6 +195,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;
@@ -195,7 +234,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 b00221400..d3f242e3f 100644
--- a/miext/rootless/rootlessCommon.h
+++ b/miext/rootless/rootlessCommon.h
@@ -56,6 +56,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 b3145815d..4af395ee6 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 cf324267a..82f54d63d 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);