xfixes: backup the DisplayCursor/CloseScreen proc before restoring it (#23034)

The screen's DisplayCursor func is wrapped as
AnimCurDisplayCursor -> CursorDisplayCursor -> miPointerDisplayCursor.

Calling CursorDisplayCursor while an animated cursor was currently displayed
would remove AnimCurDisplayCursor from the wrap stack. Thus, the next call
to ChangeToCursor wouldn't update the animated cursor state. The block
handler for animated cursors would then continuously overwrite the actual
cursor, leaving an animated cursor everywhere on the screen.

X.Org Bug 23034 <http://bugs.freedesktop.org/show_bug.cgi?id=23034>
This commit is contained in:
Peter Hutterer 2009-07-31 14:38:35 +10:00
parent f48dfcc1b7
commit 664ac92d8b

View File

@ -131,7 +131,7 @@ typedef struct _CursorScreen {
#define GetCursorScreenIfSet(s) GetCursorScreen(s)
#define SetCursorScreen(s,p) dixSetPrivate(&(s)->devPrivates, CursorScreenPrivateKey, p)
#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
#define Unwrap(as,s,elt) ((s)->elt = (as)->elt)
#define Unwrap(as,s,elt,backup) (((backup) = (s)->elt), (s)->elt = (as)->elt)
/* The cursor doesn't show up until the first XDefineCursor() */
static Bool CursorVisible = FALSE;
@ -145,8 +145,9 @@ CursorDisplayCursor (DeviceIntPtr pDev,
{
CursorScreenPtr cs = GetCursorScreen(pScreen);
Bool ret;
DisplayCursorProcPtr backupProc;
Unwrap (cs, pScreen, DisplayCursor);
Unwrap (cs, pScreen, DisplayCursor, backupProc);
/*
* Have to check ConnectionInfo to distinguish client requests from
@ -184,7 +185,8 @@ CursorDisplayCursor (DeviceIntPtr pDev,
}
}
}
Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
Wrap (cs, pScreen, DisplayCursor, backupProc);
return ret;
}
@ -193,9 +195,11 @@ CursorCloseScreen (int index, ScreenPtr pScreen)
{
CursorScreenPtr cs = GetCursorScreen (pScreen);
Bool ret;
CloseScreenProcPtr close_proc;
DisplayCursorProcPtr display_proc;
Unwrap (cs, pScreen, CloseScreen);
Unwrap (cs, pScreen, DisplayCursor);
Unwrap (cs, pScreen, CloseScreen, close_proc);
Unwrap (cs, pScreen, DisplayCursor, display_proc);
deleteCursorHideCountsForScreen(pScreen);
ret = (*pScreen->CloseScreen) (index, pScreen);
xfree (cs);