summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@vmware.com>2010-03-09 16:10:25 +0100
committerRoland Scheidegger <sroland@vmware.com>2010-03-09 16:10:25 +0100
commitbf18be6f458a4612b2ebdd8d2b5894f8884891e4 (patch)
tree37708c17a10b2efc3b8b459b369ab358c552fd1e
parent257614ae9bea54d6a46e4477496500a84853ee37 (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).
-rw-r--r--src/vmware.h1
-rw-r--r--src/vmwarecurs.c17
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);
}