Commit c02f6a68 authored by Michael Thayer's avatar Michael Thayer Committed by Adam Jackson

xfree86: Immediately handle failure to set HW cursor, v5

Based on v4 by Alexandre Courbot <acourbot@nvidia.com>

There is currently no reliable way to report failure to set a HW
cursor. Still such failures can happen if e.g. the MODE_CURSOR DRM
ioctl fails (which currently happens at least with modesetting on Tegra
for format incompatibility reasons).

As failures are currently handled by setting the HW cursor size to
(0,0), the fallback to SW cursor will not happen until the next time the
cursor changes and xf86CursorSetCursor() is called again. In the
meantime, the cursor will be invisible to the user.

This patch addresses that by adding _xf86CrtcFuncs::set_cursor_check and
_xf86CursorInfoRec::ShowCursorCheck hook variants that return booleans.
This allows to propagate errors up to xf86CursorSetCursor(), which can
then fall back to using the SW cursor immediately.

v5: Updated the patch to apply to current git HEAD, split up into two
patches (server and modesetting driver) and adjusted the code slightly
to match surrounding code.  I also removed the new exported function
ShowCursorCheck(), as instead just changing ShowCursor() to return Bool
should not affect its current callers.
Reviewed-by: Adam Jackson's avatarAdam Jackson <ajax@redhat.com>
Signed-off-by: Michael Thayer's avatarMichael Thayer <michael.thayer@oracle.com>
parent 3ef16dfb
...@@ -195,6 +195,8 @@ typedef struct _xf86CrtcFuncs { ...@@ -195,6 +195,8 @@ typedef struct _xf86CrtcFuncs {
*/ */
void void
(*show_cursor) (xf86CrtcPtr crtc); (*show_cursor) (xf86CrtcPtr crtc);
Bool
(*show_cursor_check) (xf86CrtcPtr crtc);
/** /**
* Hide cursor * Hide cursor
...@@ -993,7 +995,7 @@ static _X_INLINE _X_DEPRECATED void xf86_reload_cursors(ScreenPtr screen) {} ...@@ -993,7 +995,7 @@ static _X_INLINE _X_DEPRECATED void xf86_reload_cursors(ScreenPtr screen) {}
/** /**
* Called from EnterVT to turn the cursors back on * Called from EnterVT to turn the cursors back on
*/ */
extern _X_EXPORT void extern _X_EXPORT Bool
xf86_show_cursors(ScrnInfoPtr scrn); xf86_show_cursors(ScrnInfoPtr scrn);
/** /**
......
...@@ -210,8 +210,14 @@ set_bit(CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask) ...@@ -210,8 +210,14 @@ set_bit(CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
/* /*
* Wrappers to deal with API compatibility with drivers that don't expose * Wrappers to deal with API compatibility with drivers that don't expose
* load_cursor_*_check * *_cursor_*_check
*/ */
static inline Bool
xf86_driver_has_show_cursor(xf86CrtcPtr crtc)
{
return crtc->funcs->show_cursor_check || crtc->funcs->show_cursor;
}
static inline Bool static inline Bool
xf86_driver_has_load_cursor_image(xf86CrtcPtr crtc) xf86_driver_has_load_cursor_image(xf86CrtcPtr crtc)
{ {
...@@ -224,6 +230,15 @@ xf86_driver_has_load_cursor_argb(xf86CrtcPtr crtc) ...@@ -224,6 +230,15 @@ xf86_driver_has_load_cursor_argb(xf86CrtcPtr crtc)
return crtc->funcs->load_cursor_argb_check || crtc->funcs->load_cursor_argb; return crtc->funcs->load_cursor_argb_check || crtc->funcs->load_cursor_argb;
} }
static inline Bool
xf86_driver_show_cursor(xf86CrtcPtr crtc)
{
if (crtc->funcs->show_cursor_check)
return crtc->funcs->show_cursor_check(crtc);
crtc->funcs->show_cursor(crtc);
return TRUE;
}
static inline Bool static inline Bool
xf86_driver_load_cursor_image(xf86CrtcPtr crtc, CARD8 *cursor_image) xf86_driver_load_cursor_image(xf86CrtcPtr crtc, CARD8 *cursor_image)
{ {
...@@ -333,16 +348,19 @@ xf86_hide_cursors(ScrnInfoPtr scrn) ...@@ -333,16 +348,19 @@ xf86_hide_cursors(ScrnInfoPtr scrn)
} }
} }
static void static Bool
xf86_crtc_show_cursor(xf86CrtcPtr crtc) xf86_crtc_show_cursor(xf86CrtcPtr crtc)
{ {
if (!crtc->cursor_shown && crtc->cursor_in_range) { if (!crtc->cursor_in_range)
crtc->funcs->show_cursor(crtc); return TRUE;
crtc->cursor_shown = TRUE;
} if (!crtc->cursor_shown)
crtc->cursor_shown = xf86_driver_show_cursor(crtc);
return crtc->cursor_shown;
} }
void Bool
xf86_show_cursors(ScrnInfoPtr scrn) xf86_show_cursors(ScrnInfoPtr scrn)
{ {
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
...@@ -352,9 +370,11 @@ xf86_show_cursors(ScrnInfoPtr scrn) ...@@ -352,9 +370,11 @@ xf86_show_cursors(ScrnInfoPtr scrn)
for (c = 0; c < xf86_config->num_crtc; c++) { for (c = 0; c < xf86_config->num_crtc; c++) {
xf86CrtcPtr crtc = xf86_config->crtc[c]; xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled) if (crtc->enabled && !xf86_crtc_show_cursor(crtc))
xf86_crtc_show_cursor(crtc); return FALSE;
} }
return TRUE;
} }
static void static void
...@@ -653,7 +673,7 @@ xf86_cursors_init(ScreenPtr screen, int max_width, int max_height, int flags) ...@@ -653,7 +673,7 @@ xf86_cursors_init(ScreenPtr screen, int max_width, int max_height, int flags)
cursor_info->SetCursorPosition = xf86_set_cursor_position; cursor_info->SetCursorPosition = xf86_set_cursor_position;
cursor_info->LoadCursorImageCheck = xf86_load_cursor_image; cursor_info->LoadCursorImageCheck = xf86_load_cursor_image;
cursor_info->HideCursor = xf86_hide_cursors; cursor_info->HideCursor = xf86_hide_cursors;
cursor_info->ShowCursor = xf86_show_cursors; cursor_info->ShowCursorCheck = xf86_show_cursors;
cursor_info->UseHWCursor = xf86_use_hw_cursor; cursor_info->UseHWCursor = xf86_use_hw_cursor;
if (flags & HARDWARE_CURSOR_ARGB) { if (flags & HARDWARE_CURSOR_ARGB) {
cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb; cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
......
...@@ -16,6 +16,7 @@ typedef struct _xf86CursorInfoRec { ...@@ -16,6 +16,7 @@ typedef struct _xf86CursorInfoRec {
Bool (*LoadCursorImageCheck) (ScrnInfoPtr pScrn, unsigned char *bits); Bool (*LoadCursorImageCheck) (ScrnInfoPtr pScrn, unsigned char *bits);
void (*HideCursor) (ScrnInfoPtr pScrn); void (*HideCursor) (ScrnInfoPtr pScrn);
void (*ShowCursor) (ScrnInfoPtr pScrn); void (*ShowCursor) (ScrnInfoPtr pScrn);
Bool (*ShowCursorCheck) (ScrnInfoPtr pScrn);
unsigned char *(*RealizeCursor) (struct _xf86CursorInfoRec *, CursorPtr); unsigned char *(*RealizeCursor) (struct _xf86CursorInfoRec *, CursorPtr);
Bool (*UseHWCursor) (ScreenPtr, CursorPtr); Bool (*UseHWCursor) (ScreenPtr, CursorPtr);
...@@ -40,6 +41,21 @@ xf86DriverLoadCursorImage(xf86CursorInfoPtr infoPtr, unsigned char *bits) ...@@ -40,6 +41,21 @@ xf86DriverLoadCursorImage(xf86CursorInfoPtr infoPtr, unsigned char *bits)
return TRUE; return TRUE;
} }
static inline Bool
xf86DriverHasShowCursor(xf86CursorInfoPtr infoPtr)
{
return infoPtr->ShowCursorCheck || infoPtr->ShowCursor;
}
static inline Bool
xf86DriverShowCursor(xf86CursorInfoPtr infoPtr)
{
if(infoPtr->ShowCursorCheck)
return infoPtr->ShowCursorCheck(infoPtr->pScrn);
infoPtr->ShowCursor(infoPtr->pScrn);
return TRUE;
}
static inline Bool static inline Bool
xf86DriverHasLoadCursorARGB(xf86CursorInfoPtr infoPtr) xf86DriverHasLoadCursorARGB(xf86CursorInfoPtr infoPtr)
{ {
......
...@@ -93,7 +93,8 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) ...@@ -93,7 +93,8 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
if (!infoPtr->SetCursorPosition || if (!infoPtr->SetCursorPosition ||
!xf86DriverHasLoadCursorImage(infoPtr) || !xf86DriverHasLoadCursorImage(infoPtr) ||
!infoPtr->HideCursor || !infoPtr->HideCursor ||
!infoPtr->ShowCursor || !infoPtr->SetCursorColors) !xf86DriverHasShowCursor(infoPtr) ||
!infoPtr->SetCursorColors)
return FALSE; return FALSE;
if (infoPtr->RealizeCursor) { if (infoPtr->RealizeCursor) {
...@@ -224,8 +225,7 @@ xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) ...@@ -224,8 +225,7 @@ xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
(*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y); (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
(*infoPtr->ShowCursor) (infoPtr->pScrn); return xf86DriverShowCursor(infoPtr);
return TRUE;
} }
Bool Bool
...@@ -287,7 +287,7 @@ xf86SetTransparentCursor(ScreenPtr pScreen) ...@@ -287,7 +287,7 @@ xf86SetTransparentCursor(ScreenPtr pScreen)
xf86DriverLoadCursorImage (infoPtr, xf86DriverLoadCursorImage (infoPtr,
ScreenPriv->transparentData); ScreenPriv->transparentData);
(*infoPtr->ShowCursor) (infoPtr->pScrn); xf86DriverShowCursor(infoPtr);
input_unlock(); input_unlock();
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment