diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 89076d6aa6..8fe9c9a0be 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -5276,3 +5276,90 @@ void *SDL_Metal_GetLayer(SDL_MetalView view) return NULL; } } + +#if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) +const char *SDL_GetCSSCursorName(SDL_SystemCursor id, const char **fallback_name) +{ + /* Reference: https://www.w3.org/TR/css-ui-4/#cursor */ + /* Also in: https://www.freedesktop.org/wiki/Specifications/cursor-spec/ */ + switch (id) { + case SDL_SYSTEM_CURSOR_ARROW: + return "default"; + + case SDL_SYSTEM_CURSOR_IBEAM: + return "text"; + + case SDL_SYSTEM_CURSOR_WAIT: + return "wait"; + + case SDL_SYSTEM_CURSOR_CROSSHAIR: + return "crosshair"; + + case SDL_SYSTEM_CURSOR_WAITARROW: + return "progress"; + + case SDL_SYSTEM_CURSOR_SIZENWSE: + if (fallback_name) { + /* only a single arrow */ + *fallback_name = "nw-resize"; + } + return "nwse-resize"; + + case SDL_SYSTEM_CURSOR_SIZENESW: + if (fallback_name) { + /* only a single arrow */ + *fallback_name = "ne-resize"; + } + return "nesw-resize"; + + case SDL_SYSTEM_CURSOR_SIZEWE: + if (fallback_name) { + *fallback_name = "col-resize"; + } + return "ew-resize"; + + case SDL_SYSTEM_CURSOR_SIZENS: + if (fallback_name) { + *fallback_name = "row-resize"; + } + return "ns-resize"; + + case SDL_SYSTEM_CURSOR_SIZEALL: + return "all-scroll"; + + case SDL_SYSTEM_CURSOR_NO: + return "not-allowed"; + + case SDL_SYSTEM_CURSOR_HAND: + return "pointer"; + + case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT: + return "nw-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_TOP: + return "n-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT: + return "ne-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_RIGHT: + return "e-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT: + return "se-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM: + return "s-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT: + return "sw-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_LEFT: + return "w-resize"; + + default: + SDL_assert(0); + return "default"; + } +} +#endif diff --git a/src/video/SDL_video_c.h b/src/video/SDL_video_c.h index ceacd4ccf4..7e06bde8d7 100644 --- a/src/video/SDL_video_c.h +++ b/src/video/SDL_video_c.h @@ -59,4 +59,8 @@ extern int SDL_SetWindowTextureVSync(SDL_Window *window, int vsync); extern int SDL_ReadSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a); +#if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) +const char *SDL_GetCSSCursorName(SDL_SystemCursor id, const char **fallback_name); +#endif + #endif /* SDL_video_c_h_ */ diff --git a/src/video/emscripten/SDL_emscriptenmouse.c b/src/video/emscripten/SDL_emscriptenmouse.c index e6beab7ecd..0593fc6368 100644 --- a/src/video/emscripten/SDL_emscriptenmouse.c +++ b/src/video/emscripten/SDL_emscriptenmouse.c @@ -29,6 +29,7 @@ #include "SDL_emscriptenmouse.h" #include "SDL_emscriptenvideo.h" +#include "../SDL_video_c.h" #include "../../events/SDL_mouse_c.h" /* older Emscriptens don't have this, but we need to for wasm64 compatibility. */ @@ -117,73 +118,7 @@ static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int static SDL_Cursor *Emscripten_CreateSystemCursor(SDL_SystemCursor id) { - const char *cursor_name = NULL; - - switch (id) { - case SDL_SYSTEM_CURSOR_ARROW: - cursor_name = "default"; - break; - case SDL_SYSTEM_CURSOR_IBEAM: - cursor_name = "text"; - break; - case SDL_SYSTEM_CURSOR_WAIT: - cursor_name = "wait"; - break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: - cursor_name = "crosshair"; - break; - case SDL_SYSTEM_CURSOR_WAITARROW: - cursor_name = "progress"; - break; - case SDL_SYSTEM_CURSOR_SIZENWSE: - cursor_name = "nwse-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZENESW: - cursor_name = "nesw-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZEWE: - cursor_name = "ew-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZENS: - cursor_name = "ns-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZEALL: - cursor_name = "move"; - break; - case SDL_SYSTEM_CURSOR_NO: - cursor_name = "not-allowed"; - break; - case SDL_SYSTEM_CURSOR_HAND: - cursor_name = "pointer"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT: - cursor_name = "nwse-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_TOP: - cursor_name = "ns-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT: - cursor_name = "nesw-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_RIGHT: - cursor_name = "ew-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT: - cursor_name = "nwse-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM: - cursor_name = "ns-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT: - cursor_name = "nesw-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_LEFT: - cursor_name = "ew-resize"; - break; - default: - SDL_assert(0); - return NULL; - } + const char *cursor_name = SDL_GetCSSCursorName(id, NULL); return Emscripten_CreateCursorFromString(cursor_name, SDL_FALSE); } diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c index 841d3da58b..a8416c5e0c 100644 --- a/src/video/wayland/SDL_waylandmouse.c +++ b/src/video/wayland/SDL_waylandmouse.c @@ -30,6 +30,7 @@ #include #include "../SDL_sysvideo.h" +#include "../SDL_video_c.h" #include "../../events/SDL_mouse_c.h" #include "SDL_waylandvideo.h" @@ -318,81 +319,7 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa vdata->cursor_themes[vdata->num_cursor_themes++].theme = theme; } - /* Next, find the cursor from the theme. Names taken from: */ - /* https://www.w3.org/TR/css-ui-4/#cursor */ - /* https://www.freedesktop.org/wiki/Specifications/cursor-spec/ */ - switch (cdata->system_cursor) { - case SDL_SYSTEM_CURSOR_ARROW: - css_name = "default"; - break; - case SDL_SYSTEM_CURSOR_IBEAM: - css_name = "text"; - break; - case SDL_SYSTEM_CURSOR_WAIT: - css_name = "wait"; - break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: - css_name = "crosshair"; - break; - case SDL_SYSTEM_CURSOR_WAITARROW: - css_name = "progress"; - break; - case SDL_SYSTEM_CURSOR_SIZENWSE: - css_name = "nwse-resize"; - /* only a single arrow */ - fallback_name = "nw-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZENESW: - css_name = "nesw-resize"; - /* only a single arrow */ - fallback_name = "ne-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZEWE: - css_name = "ew-resize"; - fallback_name = "col-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZENS: - css_name = "ns-resize"; - fallback_name = "row-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZEALL: - css_name = "all-scroll"; - break; - case SDL_SYSTEM_CURSOR_NO: - css_name = "not-allowed"; - break; - case SDL_SYSTEM_CURSOR_HAND: - css_name = "pointer"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT: - css_name = "nw-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_TOP: - css_name = "n-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT: - css_name = "ne-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_RIGHT: - css_name = "e-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT: - css_name = "se-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM: - css_name = "s-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT: - css_name = "sw-resize"; - break; - case SDL_SYSTEM_CURSOR_WINDOW_LEFT: - css_name = "w-resize"; - break; - default: - SDL_assert(0); - return SDL_FALSE; - } - + css_name = SDL_GetCSSCursorName(cdata->system_cursor, &fallback_name); cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, css_name); if (!cursor && fallback_name) { cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, fallback_name); diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index de503e09b9..d7c9e3ed4e 100644 --- a/src/video/x11/SDL_x11mouse.c +++ b/src/video/x11/SDL_x11mouse.c @@ -26,6 +26,7 @@ #include "SDL_x11video.h" #include "SDL_x11mouse.h" #include "SDL_x11xinput2.h" +#include "../SDL_video_c.h" #include "../../events/SDL_mouse_c.h" /* FIXME: Find a better place to put this... */ @@ -216,7 +217,7 @@ static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id) { SDL_Cursor *cursor = NULL; unsigned int shape = 0; - const char *xcursorname = NULL; + const char *xcursorname = SDL_GetCSSCursorName(id, NULL); switch (id) { default: @@ -226,83 +227,63 @@ static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id) /* http://tronche.com/gui/x/xlib/appendix/b/ */ case SDL_SYSTEM_CURSOR_ARROW: shape = XC_left_ptr; - xcursorname = "default"; break; case SDL_SYSTEM_CURSOR_IBEAM: shape = XC_xterm; - xcursorname = "text"; break; case SDL_SYSTEM_CURSOR_WAIT: shape = XC_watch; - xcursorname = "wait"; break; case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; - xcursorname = "crosshair"; break; case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; - xcursorname = "progress"; break; case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_top_left_corner; - xcursorname = "nwse-resize"; break; case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_top_right_corner; - xcursorname = "nesw-resize"; break; case SDL_SYSTEM_CURSOR_SIZEWE: shape = XC_sb_h_double_arrow; - xcursorname = "ew-resize"; break; case SDL_SYSTEM_CURSOR_SIZENS: shape = XC_sb_v_double_arrow; - xcursorname = "ns-resize"; break; case SDL_SYSTEM_CURSOR_SIZEALL: shape = XC_fleur; - xcursorname = "move"; break; case SDL_SYSTEM_CURSOR_NO: shape = XC_pirate; - xcursorname = "not-allowed"; break; case SDL_SYSTEM_CURSOR_HAND: shape = XC_hand2; - xcursorname = "pointer"; break; case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT: shape = XC_top_left_corner; - xcursorname = "nw-resize"; break; case SDL_SYSTEM_CURSOR_WINDOW_TOP: shape = XC_top_side; - xcursorname = "n-resize"; break; case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT: shape = XC_top_right_corner; - xcursorname = "ne-resize"; break; case SDL_SYSTEM_CURSOR_WINDOW_RIGHT: shape = XC_right_side; - xcursorname = "e-resize"; break; case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT: shape = XC_bottom_right_corner; - xcursorname = "se-resize"; break; case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM: shape = XC_bottom_side; - xcursorname = "s-resize"; break; case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT: shape = XC_bottom_left_corner; - xcursorname = "sw-resize"; break; case SDL_SYSTEM_CURSOR_WINDOW_LEFT: shape = XC_left_side; - xcursorname = "w-resize"; break; }