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

As suggested in #8939.

This results in some minor changes for emscripten and x11. Both
previously mapped SIZEALL to "move", but "move" is not guaranteed to be
a four-pointed arrow: according to the CSS spec, it's actually intended
to be a drag-and-drop cursor, analogous to "alias" and "copy".
Map it to "all-scroll" instead, as in Wayland: while this is *also* not
semantically guaranteed to be a four-pointed arrow, it is at least
*suggested* to make it a four-pointed arrow.

Also, emscripten was previously using two-pointed arrows for resizing
(BOTTOMLEFT mapped to "nesw-resize", and so on). This commit changes
it to use the more specific "sw-resize" and so on, which might be
single-directional.

Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie 2024-02-16 12:20:21 +00:00 committed by Ryan C. Gordon
parent 7dbd6669c3
commit b986bc8be9
5 changed files with 97 additions and 163 deletions

View File

@ -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

View File

@ -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_ */

View File

@ -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);
}

View File

@ -30,6 +30,7 @@
#include <limits.h>
#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);

View File

@ -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;
}