diff options
author | Roland Scheidegger <sroland@vmware.com> | 2010-03-09 16:10:25 +0100 |
---|---|---|
committer | Roland Scheidegger <sroland@vmware.com> | 2010-03-09 16:10:25 +0100 |
commit | bf18be6f458a4612b2ebdd8d2b5894f8884891e4 (patch) | |
tree | 37708c17a10b2efc3b8b459b369ab358c552fd1e /src | |
parent | 257614ae9bea54d6a46e4477496500a84853ee37 (diff) |
fix a cursor refcounting bug, leading to segfaults
this is similar to what xf86_use_hw_cursor() does, which is replaced by
vmwareUseHWCursor (otherwise, the refcount could reach zero and hence the
cursor deallocated while xf86CursorEnableDisableFBAccess() could still bring
it back to life from the saved cursor).
It is probably insane to do refcounting here, but this needs a xserver fix,
and even if that's fixed this fix here shouldn't hurt (though would be
unnecessary).
Diffstat (limited to 'src')
-rw-r--r-- | src/vmware.h | 1 | ||||
-rw-r--r-- | src/vmwarecurs.c | 17 |
2 files changed, 18 insertions, 0 deletions
diff --git a/src/vmware.h b/src/vmware.h index afefd7f..a3920ab 100644 --- a/src/vmware.h +++ b/src/vmware.h @@ -132,6 +132,7 @@ typedef struct { CARD32* vmwareFIFO; xf86CursorInfoPtr CursorInfoRec; + CursorPtr oldCurs; struct { int bg, fg, x, y; int hotX, hotY; diff --git a/src/vmwarecurs.c b/src/vmwarecurs.c index 017af28..38c5988 100644 --- a/src/vmwarecurs.c +++ b/src/vmwarecurs.c @@ -113,6 +113,12 @@ vmwareUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { ScrnInfoPtr pScrn = infoFromScreen(pScreen); VMWAREPtr pVMWARE = VMWAREPTR(pScrn); + VmwareLog(("UseHWCursor new cursor %p refcnt %i old cursor %p refcnt %i\n", + pCurs, pCurs->refcnt, pVMWARE->oldCurs, pVMWARE->oldCurs ? pVMWARE->oldCurs->refcnt : 0)); + pCurs->refcnt++; + if (pVMWARE->oldCurs) + FreeCursor(pVMWARE->oldCurs, None); + pVMWARE->oldCurs = pCurs; pVMWARE->hwcur.hotX = pCurs->bits->xhot; pVMWARE->hwcur.hotY = pCurs->bits->yhot; @@ -141,6 +147,13 @@ static Bool vmwareUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs) { ScrnInfoPtr pScrn = infoFromScreen(pScreen); + VMWAREPtr pVMWARE = VMWAREPTR(pScrn); + VmwareLog(("UseHWCursorARGB new cursor %p refcnt %i old cursor %p refcnt %i\n", + pCurs, pCurs->refcnt, pVMWARE->oldCurs, pVMWARE->oldCurs ? pVMWARE->oldCurs->refcnt : 0)); + pCurs->refcnt++; + if (pVMWARE->oldCurs) + FreeCursor(pVMWARE->oldCurs, None); + pVMWARE->oldCurs = pCurs; return pCurs->bits->height <= MAX_CURS && pCurs->bits->width <= MAX_CURS && @@ -286,6 +299,7 @@ vmwareCursorInit(ScreenPtr pScreen) return FALSE; pVMWARE->CursorInfoRec = infoPtr; + pVMWARE->oldCurs = NULL; infoPtr->MaxWidth = MAX_CURS; infoPtr->MaxHeight = MAX_CURS; @@ -332,6 +346,9 @@ vmwareCursorCloseScreen(ScreenPtr pScreen) #endif /* RENDER */ vmwareHideCursor(pScrn); + if (pVMWARE->oldCurs) + FreeCursor(pVMWARE->oldCurs, None); + pVMWARE->oldCurs = NULL; xf86DestroyCursorInfoRec(pVMWARE->CursorInfoRec); } |