emscripten, wayland, x11: Share the table of CSS cursor names

As suggested in #8939.

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 271df2fdd8)
This commit is contained in:
Simon McVittie
2024-02-16 12:43:05 +00:00
committed by Ryan C. Gordon
parent 372564299e
commit 5e51a37518
5 changed files with 102 additions and 68 deletions

View File

@@ -24,6 +24,7 @@
#define SDL_sysvideo_h_ #define SDL_sysvideo_h_
#include "SDL_messagebox.h" #include "SDL_messagebox.h"
#include "SDL_mouse.h"
#include "SDL_shape.h" #include "SDL_shape.h"
#include "SDL_thread.h" #include "SDL_thread.h"
#include "SDL_metal.h" #include "SDL_metal.h"
@@ -529,6 +530,10 @@ extern int SDL_GetPointDisplayIndex(const SDL_Point *point);
extern int SDL_GL_SwapWindowWithResult(SDL_Window *window); extern int SDL_GL_SwapWindowWithResult(SDL_Window *window);
#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_sysvideo_h_ */ #endif /* SDL_sysvideo_h_ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@@ -4780,4 +4780,93 @@ void SDL_Metal_GetDrawableSize(SDL_Window *window, int *w, int *h)
} }
} }
#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";
#if 0
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";
#endif
default:
SDL_assert(0);
return "default";
}
}
#endif
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@@ -141,49 +141,7 @@ static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int
static SDL_Cursor *Emscripten_CreateSystemCursor(SDL_SystemCursor id) static SDL_Cursor *Emscripten_CreateSystemCursor(SDL_SystemCursor id)
{ {
const char *cursor_name = NULL; const char *cursor_name = SDL_GetCSSCursorName(id, 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 = "all-scroll";
break;
case SDL_SYSTEM_CURSOR_NO:
cursor_name = "not-allowed";
break;
case SDL_SYSTEM_CURSOR_HAND:
cursor_name = "pointer";
break;
default:
SDL_assert(0);
return NULL;
}
return Emscripten_CreateCursorFromString(cursor_name, SDL_FALSE); return Emscripten_CreateCursorFromString(cursor_name, SDL_FALSE);
} }

View File

@@ -161,6 +161,7 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa
struct wl_cursor_theme *theme = NULL; struct wl_cursor_theme *theme = NULL;
struct wl_cursor *cursor; struct wl_cursor *cursor;
const char *cssname = NULL; const char *cssname = NULL;
const char *fallback_name = NULL;
const char *legacyname = NULL; const char *legacyname = NULL;
char *xcursor_size; char *xcursor_size;
@@ -235,51 +236,39 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa
/* Next, find the cursor from the theme... */ /* Next, find the cursor from the theme... */
switch (cdata->system_cursor) { switch (cdata->system_cursor) {
case SDL_SYSTEM_CURSOR_ARROW: case SDL_SYSTEM_CURSOR_ARROW:
cssname = "default";
legacyname = "left_ptr"; legacyname = "left_ptr";
break; break;
case SDL_SYSTEM_CURSOR_IBEAM: case SDL_SYSTEM_CURSOR_IBEAM:
cssname = "text";
legacyname = "xterm"; legacyname = "xterm";
break; break;
case SDL_SYSTEM_CURSOR_WAIT: case SDL_SYSTEM_CURSOR_WAIT:
cssname = "wait";
legacyname = "watch"; legacyname = "watch";
break; break;
case SDL_SYSTEM_CURSOR_CROSSHAIR: case SDL_SYSTEM_CURSOR_CROSSHAIR:
cssname = "crosshair";
legacyname = "tcross"; legacyname = "tcross";
break; break;
case SDL_SYSTEM_CURSOR_WAITARROW: case SDL_SYSTEM_CURSOR_WAITARROW:
cssname = "progress";
legacyname = "watch"; legacyname = "watch";
break; break;
case SDL_SYSTEM_CURSOR_SIZENWSE: case SDL_SYSTEM_CURSOR_SIZENWSE:
cssname = "nwse-resize";
legacyname = "top_left_corner"; legacyname = "top_left_corner";
break; break;
case SDL_SYSTEM_CURSOR_SIZENESW: case SDL_SYSTEM_CURSOR_SIZENESW:
cssname = "nesw-resize";
legacyname = "top_right_corner"; legacyname = "top_right_corner";
break; break;
case SDL_SYSTEM_CURSOR_SIZEWE: case SDL_SYSTEM_CURSOR_SIZEWE:
cssname = "ew-resize";
legacyname = "sb_h_double_arrow"; legacyname = "sb_h_double_arrow";
break; break;
case SDL_SYSTEM_CURSOR_SIZENS: case SDL_SYSTEM_CURSOR_SIZENS:
cssname = "ns-resize";
legacyname = "sb_v_double_arrow"; legacyname = "sb_v_double_arrow";
break; break;
case SDL_SYSTEM_CURSOR_SIZEALL: case SDL_SYSTEM_CURSOR_SIZEALL:
cssname = "all-scroll";
legacyname = "fleur"; legacyname = "fleur";
break; break;
case SDL_SYSTEM_CURSOR_NO: case SDL_SYSTEM_CURSOR_NO:
cssname = "not-allowed";
legacyname = "pirate"; legacyname = "pirate";
break; break;
case SDL_SYSTEM_CURSOR_HAND: case SDL_SYSTEM_CURSOR_HAND:
cssname = "pointer";
legacyname = "hand2"; legacyname = "hand2";
break; break;
default: default:
@@ -287,7 +276,12 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa
return SDL_FALSE; return SDL_FALSE;
} }
cssname = SDL_GetCSSCursorName(cdata->system_cursor, &fallback_name);
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, cssname); cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, cssname);
if (!cursor) {
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, fallback_name);
}
/* try the legacy name if the fancy new CSS name doesn't work... */ /* try the legacy name if the fancy new CSS name doesn't work... */
if (!cursor) { if (!cursor) {

View File

@@ -224,7 +224,7 @@ static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id)
{ {
SDL_Cursor *cursor = NULL; SDL_Cursor *cursor = NULL;
unsigned int shape = 0; unsigned int shape = 0;
const char *xcursorname = NULL; const char *xcursorname = SDL_GetCSSCursorName(id, NULL);
switch (id) { switch (id) {
default: default:
@@ -234,51 +234,39 @@ static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id)
/* http://tronche.com/gui/x/xlib/appendix/b/ */ /* http://tronche.com/gui/x/xlib/appendix/b/ */
case SDL_SYSTEM_CURSOR_ARROW: case SDL_SYSTEM_CURSOR_ARROW:
shape = XC_left_ptr; shape = XC_left_ptr;
xcursorname = "default";
break; break;
case SDL_SYSTEM_CURSOR_IBEAM: case SDL_SYSTEM_CURSOR_IBEAM:
shape = XC_xterm; shape = XC_xterm;
xcursorname = "text";
break; break;
case SDL_SYSTEM_CURSOR_WAIT: case SDL_SYSTEM_CURSOR_WAIT:
shape = XC_watch; shape = XC_watch;
xcursorname = "wait";
break; break;
case SDL_SYSTEM_CURSOR_CROSSHAIR: case SDL_SYSTEM_CURSOR_CROSSHAIR:
shape = XC_tcross; shape = XC_tcross;
xcursorname = "crosshair";
break; break;
case SDL_SYSTEM_CURSOR_WAITARROW: case SDL_SYSTEM_CURSOR_WAITARROW:
shape = XC_watch; shape = XC_watch;
xcursorname = "progress";
break; break;
case SDL_SYSTEM_CURSOR_SIZENWSE: case SDL_SYSTEM_CURSOR_SIZENWSE:
shape = XC_top_left_corner; shape = XC_top_left_corner;
xcursorname = "nwse-resize";
break; break;
case SDL_SYSTEM_CURSOR_SIZENESW: case SDL_SYSTEM_CURSOR_SIZENESW:
shape = XC_top_right_corner; shape = XC_top_right_corner;
xcursorname = "nesw-resize";
break; break;
case SDL_SYSTEM_CURSOR_SIZEWE: case SDL_SYSTEM_CURSOR_SIZEWE:
shape = XC_sb_h_double_arrow; shape = XC_sb_h_double_arrow;
xcursorname = "ew-resize";
break; break;
case SDL_SYSTEM_CURSOR_SIZENS: case SDL_SYSTEM_CURSOR_SIZENS:
shape = XC_sb_v_double_arrow; shape = XC_sb_v_double_arrow;
xcursorname = "ns-resize";
break; break;
case SDL_SYSTEM_CURSOR_SIZEALL: case SDL_SYSTEM_CURSOR_SIZEALL:
shape = XC_fleur; shape = XC_fleur;
xcursorname = "all-scroll";
break; break;
case SDL_SYSTEM_CURSOR_NO: case SDL_SYSTEM_CURSOR_NO:
shape = XC_pirate; shape = XC_pirate;
xcursorname = "not-allowed";
break; break;
case SDL_SYSTEM_CURSOR_HAND: case SDL_SYSTEM_CURSOR_HAND:
shape = XC_hand2; shape = XC_hand2;
xcursorname = "pointer";
break; break;
} }