Skip to content

Commit

Permalink
Patch to avert (some) damage / rootless crashes, courtesy of Ken Thom…
Browse files Browse the repository at this point in the history
…ases
  • Loading branch information
Ben Byer authored and Jeremy Huddleston committed Nov 19, 2007
1 parent 0cf4523 commit 148a87f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 4 deletions.
1 change: 0 additions & 1 deletion miext/rootless/rootless.h
Expand Up @@ -66,7 +66,6 @@ typedef struct _RootlessWindowRec {
int bytesPerRow;

PixmapPtr pixmap;
PixmapPtr oldPixmap;

#ifdef ROOTLESS_TRACK_DAMAGE
RegionRec damage;
Expand Down
45 changes: 42 additions & 3 deletions miext/rootless/rootlessCommon.c
Expand Up @@ -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);
}
}


Expand All @@ -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;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions miext/rootless/rootlessCommon.h
Expand Up @@ -56,6 +56,7 @@
extern int rootlessGCPrivateIndex;
extern int rootlessScreenPrivateIndex;
extern int rootlessWindowPrivateIndex;
extern int rootlessWindowOldPixmapPrivateIndex;


// RootlessGCRec: private per-gc data
Expand Down
5 changes: 5 additions & 0 deletions miext/rootless/rootlessScreen.c
Expand Up @@ -65,6 +65,7 @@ extern Bool RootlessCreateGC(GCPtr pGC);
int rootlessGCPrivateIndex = -1;
int rootlessScreenPrivateIndex = -1;
int rootlessWindowPrivateIndex = -1;
int rootlessWindowOldPixmapPrivateIndex = -1;


/*
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions miext/rootless/rootlessWindow.c
Expand Up @@ -198,6 +198,7 @@ RootlessCreateWindow(WindowPtr pWin)
RegionRec saveRoot;

WINREC(pWin) = NULL;
pWin->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr = NULL;

SCREEN_UNWRAP(pWin->drawable.pScreen, CreateWindow);

Expand Down

0 comments on commit 148a87f

Please sign in to comment.