[PATCH] hw/xfree86: move reference counting out of the UseHWCursor[ARGB] functions

Roland Scheidegger sroland at vmware.com
Fri Mar 12 07:53:30 PST 2010

The problem is that the xf86_use_hw_cursor(_argb) functions may get this
correctly now, some drivers will replace these generic versions with their
own functions. It is pretty insane to expect them to do reference counting
of the cursor (as an example, look at driver/xf86-video-vmware to see how
that looks like as a workaround). There are even places in xserver itself
which replace these two functions.
The segfaults if no reference counting is done are caused because the
reference count of the cursor reached zero, hence the cursor was freed,
however xf86CursorEnableDisableFBAccess() brought it back to life from
the dead (from the SavedCursor).
This patch hence adds reference counting in xf86CursorSetCursor. As per Michel
Daenzer's suggestion, also free the cursor upon xf86CursorCloseScreen.
In theory with this it should be possible to remove the reference
counting in the UseHwCursor functions I think, though it should also be
safe to keep them.

Signed-off-by: Roland Scheidegger <sroland at vmware.com>
Reviewed-by: Michel Dänzer <michel at daenzer.net>
 hw/xfree86/ramdac/xf86Cursor.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 6b71f46..7f23d9e 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -129,6 +129,9 @@ xf86CursorCloseScreen(int i, ScreenPtr pScreen)
     if (ScreenPriv->isUp && pScrn->vtSema)
 	xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
+    if (ScreenPriv->CurrentCursor)
+	FreeCursor(ScreenPriv->CurrentCursor, None);
     pScreen->CloseScreen = ScreenPriv->CloseScreen;
     pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
     pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
@@ -317,6 +320,9 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
     if (pDev == inputInfo.pointer ||
         (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer))
+	pCurs->refcnt++;
+	if (ScreenPriv->CurrentCursor)
+	    FreeCursor(ScreenPriv->CurrentCursor, None);
 	ScreenPriv->CurrentCursor = pCurs;
 	ScreenPriv->x = x;
 	ScreenPriv->y = y;

More information about the xorg-devel mailing list