GLFW: Add more standard cursor shapes

Also use an enum for the cursor shapes
This commit is contained in:
Kovid Goyal 2019-03-21 13:06:13 +05:30
parent 733158a2de
commit 5ab8a665be
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
10 changed files with 135 additions and 155 deletions

View file

@ -1940,21 +1940,26 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
return GLFW_TRUE;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
{
if (shape == GLFW_ARROW_CURSOR)
cursor->ns.object = [NSCursor arrowCursor];
else if (shape == GLFW_IBEAM_CURSOR)
cursor->ns.object = [NSCursor IBeamCursor];
else if (shape == GLFW_CROSSHAIR_CURSOR)
cursor->ns.object = [NSCursor crosshairCursor];
else if (shape == GLFW_HAND_CURSOR)
cursor->ns.object = [NSCursor pointingHandCursor];
else if (shape == GLFW_HRESIZE_CURSOR)
cursor->ns.object = [NSCursor resizeLeftRightCursor];
else if (shape == GLFW_VRESIZE_CURSOR)
cursor->ns.object = [NSCursor resizeUpDownCursor];
#define C(name, val) case name: cursor->ns.object = [NSCursor val]; break;
#define U(name, val) case name: cursor->ns.object = [[NSCursor class] performSelector:@selector(val)]; break;
switch(shape) {
C(GLFW_ARROW_CURSOR, arrowCursor);
C(GLFW_IBEAM_CURSOR, IBeamCursor);
C(GLFW_CROSSHAIR_CURSOR, crosshairCursor);
C(GLFW_HAND_CURSOR, pointingHandCursor);
C(GLFW_HRESIZE_CURSOR, resizeLeftRightCursor);
C(GLFW_VRESIZE_CURSOR, resizeUpDownCursor);
U(GLFW_NW_RESIZE_CURSOR, _windowResizeNorthWestSouthEastCursor);
U(GLFW_NE_RESIZE_CURSOR, _windowResizeNorthEastSouthWestCursor);
U(GLFW_SW_RESIZE_CURSOR, _windowResizeNorthEastSouthWestCursor);
U(GLFW_SE_RESIZE_CURSOR, _windowResizeNorthWestSouthEastCursor);
case GLFW_INVALID_CURSOR:
return GLFW_FALSE;
}
#undef C
#undef U
if (!cursor->ns.object)
{

45
glfw/glfw3.h vendored
View file

@ -1032,36 +1032,19 @@ extern "C" {
* @ingroup input
* @{ */
/*! @brief The regular arrow cursor shape.
*
* The regular arrow cursor.
*/
#define GLFW_ARROW_CURSOR 0x00036001
/*! @brief The text input I-beam cursor shape.
*
* The text input I-beam cursor shape.
*/
#define GLFW_IBEAM_CURSOR 0x00036002
/*! @brief The crosshair shape.
*
* The crosshair shape.
*/
#define GLFW_CROSSHAIR_CURSOR 0x00036003
/*! @brief The hand shape.
*
* The hand shape.
*/
#define GLFW_HAND_CURSOR 0x00036004
/*! @brief The horizontal resize arrow shape.
*
* The horizontal resize arrow shape.
*/
#define GLFW_HRESIZE_CURSOR 0x00036005
/*! @brief The vertical resize arrow shape.
*
* The vertical resize arrow shape.
*/
#define GLFW_VRESIZE_CURSOR 0x00036006
typedef enum {
GLFW_ARROW_CURSOR,
GLFW_IBEAM_CURSOR,
GLFW_CROSSHAIR_CURSOR,
GLFW_HAND_CURSOR,
GLFW_HRESIZE_CURSOR,
GLFW_VRESIZE_CURSOR,
GLFW_NW_RESIZE_CURSOR,
GLFW_NE_RESIZE_CURSOR,
GLFW_SW_RESIZE_CURSOR,
GLFW_SE_RESIZE_CURSOR,
GLFW_INVALID_CURSOR
} GLFWCursorShape;
/*! @} */
#define GLFW_CONNECTED 0x00040001
@ -4160,7 +4143,7 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot,
*
* @ingroup input
*/
GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
GLFWAPI GLFWcursor* glfwCreateStandardCursor(GLFWCursorShape shape);
/*! @brief Destroys a cursor.
*

11
glfw/input.c vendored
View file

@ -831,20 +831,15 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot,
return (GLFWcursor*) cursor;
}
GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
GLFWAPI GLFWcursor* glfwCreateStandardCursor(GLFWCursorShape shape)
{
_GLFWcursor* cursor;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (shape != GLFW_ARROW_CURSOR &&
shape != GLFW_IBEAM_CURSOR &&
shape != GLFW_CROSSHAIR_CURSOR &&
shape != GLFW_HAND_CURSOR &&
shape != GLFW_HRESIZE_CURSOR &&
shape != GLFW_VRESIZE_CURSOR)
if (shape >= GLFW_INVALID_CURSOR)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor: %d", shape);
return NULL;
}

2
glfw/internal.h vendored
View file

@ -608,7 +608,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image, int xhot, int yhot, int count);
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape);
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);

34
glfw/wl_init.c vendored
View file

@ -126,21 +126,15 @@ static void pointerHandleLeave(void* data,
_glfwInputCursorEnter(window, GLFW_FALSE);
}
static void setCursor(const char* name)
static void setCursor(GLFWCursorShape shape)
{
struct wl_buffer* buffer;
struct wl_cursor* cursor;
struct wl_cursor_image* image;
struct wl_surface* surface = _glfw.wl.cursorSurface;
cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
name);
if (!cursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Standard cursor %s not found", name);
return;
}
cursor = _glfwLoadCursor(shape);
if (!cursor) return;
// TODO: handle animated cursors too.
image = cursor->images[0];
@ -167,7 +161,7 @@ static void pointerHandleMotion(void* data,
wl_fixed_t sy)
{
_GLFWwindow* window = _glfw.wl.pointerFocus;
const char* cursorName = NULL;
GLFWCursorShape cursorShape = GLFW_ARROW_CURSOR;
if (!window)
return;
@ -189,34 +183,34 @@ static void pointerHandleMotion(void* data,
return;
case topDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
cursorName = "n-resize";
cursorShape = GLFW_VRESIZE_CURSOR;
else
cursorName = "left_ptr";
cursorShape = GLFW_ARROW_CURSOR;
break;
case leftDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
cursorName = "nw-resize";
cursorShape = GLFW_NW_RESIZE_CURSOR;
else
cursorName = "w-resize";
cursorShape = GLFW_HRESIZE_CURSOR;
break;
case rightDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
cursorName = "ne-resize";
cursorShape = GLFW_NE_RESIZE_CURSOR;
else
cursorName = "e-resize";
cursorShape = GLFW_HRESIZE_CURSOR;
break;
case bottomDecoration:
if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
cursorName = "sw-resize";
cursorShape = GLFW_SW_RESIZE_CURSOR;
else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
cursorName = "se-resize";
cursorShape = GLFW_SE_RESIZE_CURSOR;
else
cursorName = "s-resize";
cursorShape = GLFW_VRESIZE_CURSOR;
break;
default:
assert(0);
}
setCursor(cursorName);
setCursor(cursorShape);
}
static void pointerHandleButton(void* data,

1
glfw/wl_platform.h vendored
View file

@ -323,3 +323,4 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version);
void _glfwSetupWaylandDataDevice();
void _glfwSetupWaylandPrimarySelectionDevice();
void animateCursorImage(id_type timer_id, void *data);
struct wl_cursor* _glfwLoadCursor(GLFWCursorShape);

79
glfw/wl_window.c vendored
View file

@ -877,26 +877,50 @@ handleEvents(double timeout)
glfw_dbus_session_bus_dispatch();
}
// Translates a GLFW standard cursor to a theme cursor name
//
static const char *translateCursorShape(int shape)
static struct wl_cursor*
try_cursor_names(int arg_count, ...) {
struct wl_cursor* ans = NULL;
va_list ap;
va_start(ap, arg_count);
for (int i = 0; i < arg_count && !ans; i++) {
const char *name = va_arg(ap, const char *);
ans = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);
}
va_end(ap);
return ans;
}
struct wl_cursor* _glfwLoadCursor(GLFWCursorShape shape)
{
static GLFWbool warnings[GLFW_INVALID_CURSOR] = {0};
#define NUMARGS(...) (sizeof((const char*[]){__VA_ARGS__})/sizeof(const char*))
#define C(name, ...) case name: { \
ans = try_cursor_names(NUMARGS(__VA_ARGS__), __VA_ARGS__); \
if (!ans && !warnings[name]) {\
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Could not find standard cursor: %s", #name); \
warnings[name] = GLFW_TRUE; \
} \
break; }
struct wl_cursor* ans = NULL;
switch (shape)
{
case GLFW_ARROW_CURSOR:
return "left_ptr";
case GLFW_IBEAM_CURSOR:
return "xterm";
case GLFW_CROSSHAIR_CURSOR:
return "crosshair";
case GLFW_HAND_CURSOR:
return "hand2";
case GLFW_HRESIZE_CURSOR:
return "sb_h_double_arrow";
case GLFW_VRESIZE_CURSOR:
return "sb_v_double_arrow";
C(GLFW_ARROW_CURSOR, "left_ptr", "default")
C(GLFW_IBEAM_CURSOR, "xterm", "ibeam", "text")
C(GLFW_CROSSHAIR_CURSOR, "crosshair", "cross")
C(GLFW_HAND_CURSOR, "hand2", "grab", "grabbing", "closedhand")
C(GLFW_HRESIZE_CURSOR, "sb_h_double_arrow", "h_double_arrow", "col-resize")
C(GLFW_VRESIZE_CURSOR, "sb_v_double_arrow", "v_double_arrow", "row-resize")
C(GLFW_NW_RESIZE_CURSOR, "top_left_corner", "nw-resize")
C(GLFW_NE_RESIZE_CURSOR, "top_right_corner", "ne-resize")
C(GLFW_SW_RESIZE_CURSOR, "bottom_left_corner", "sw-resize")
C(GLFW_SE_RESIZE_CURSOR, "bottom_right_corner", "se-resize")
case GLFW_INVALID_CURSOR:
break;
}
return NULL;
return ans;
#undef NUMARGS
#undef C
}
//////////////////////////////////////////////////////////////////////////
@ -1405,20 +1429,12 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
return GLFW_TRUE;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
{
struct wl_cursor* standardCursor;
standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
translateCursorShape(shape));
if (!standardCursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Standard cursor \"%s\" not found",
translateCursorShape(shape));
return GLFW_FALSE;
}
standardCursor = _glfwLoadCursor(shape);
if (!standardCursor) return GLFW_FALSE;
cursor->wl.cursor = standardCursor;
cursor->wl.currentImage = 0;
return GLFW_TRUE;
@ -1555,13 +1571,8 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
setCursorImage(&cursor->wl);
else
{
defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, translateCursorShape(GLFW_ARROW_CURSOR));
if (!defaultCursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Standard arrow cursor not found");
return;
}
defaultCursor = _glfwLoadCursor(GLFW_ARROW_CURSOR);
if (!defaultCursor) return;
_GLFWcursorWayland cursorWayland = {
defaultCursor,
NULL,

33
glfw/x11_window.c vendored
View file

@ -2632,24 +2632,25 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
return GLFW_TRUE;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
{
int native = 0;
if (shape == GLFW_ARROW_CURSOR)
native = XC_left_ptr;
else if (shape == GLFW_IBEAM_CURSOR)
native = XC_xterm;
else if (shape == GLFW_CROSSHAIR_CURSOR)
native = XC_crosshair;
else if (shape == GLFW_HAND_CURSOR)
native = XC_hand2;
else if (shape == GLFW_HRESIZE_CURSOR)
native = XC_sb_h_double_arrow;
else if (shape == GLFW_VRESIZE_CURSOR)
native = XC_sb_v_double_arrow;
else
return GLFW_FALSE;
#define C(name, val) case name: native = val; break;
switch(shape) {
C(GLFW_ARROW_CURSOR, XC_left_ptr);
C(GLFW_IBEAM_CURSOR, XC_xterm);
C(GLFW_CROSSHAIR_CURSOR, XC_crosshair);
C(GLFW_HAND_CURSOR, XC_hand2);
C(GLFW_HRESIZE_CURSOR, XC_sb_h_double_arrow);
C(GLFW_VRESIZE_CURSOR, XC_sb_v_double_arrow);
C(GLFW_NW_RESIZE_CURSOR, XC_top_left_corner);
C(GLFW_NE_RESIZE_CURSOR, XC_top_right_corner);
C(GLFW_SW_RESIZE_CURSOR, XC_bottom_left_corner);
C(GLFW_SE_RESIZE_CURSOR, XC_bottom_right_corner);
case GLFW_INVALID_CURSOR:
return GLFW_FALSE;
}
#undef C
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
if (!cursor->x11.handle)

3
kitty/glfw-wrapper.c generated
View file

@ -62,6 +62,9 @@ load_glfw(const char* path) {
*(void **) (&glfwGetMonitorPos_impl) = dlsym(handle, "glfwGetMonitorPos");
if (glfwGetMonitorPos_impl == NULL) fail("Failed to load glfw function glfwGetMonitorPos with error: %s", dlerror());
*(void **) (&glfwGetMonitorWorkarea_impl) = dlsym(handle, "glfwGetMonitorWorkarea");
if (glfwGetMonitorWorkarea_impl == NULL) fail("Failed to load glfw function glfwGetMonitorWorkarea with error: %s", dlerror());
*(void **) (&glfwGetMonitorPhysicalSize_impl) = dlsym(handle, "glfwGetMonitorPhysicalSize");
if (glfwGetMonitorPhysicalSize_impl == NULL) fail("Failed to load glfw function glfwGetMonitorPhysicalSize with error: %s", dlerror());

49
kitty/glfw-wrapper.h generated
View file

@ -789,36 +789,19 @@
* @ingroup input
* @{ */
/*! @brief The regular arrow cursor shape.
*
* The regular arrow cursor.
*/
#define GLFW_ARROW_CURSOR 0x00036001
/*! @brief The text input I-beam cursor shape.
*
* The text input I-beam cursor shape.
*/
#define GLFW_IBEAM_CURSOR 0x00036002
/*! @brief The crosshair shape.
*
* The crosshair shape.
*/
#define GLFW_CROSSHAIR_CURSOR 0x00036003
/*! @brief The hand shape.
*
* The hand shape.
*/
#define GLFW_HAND_CURSOR 0x00036004
/*! @brief The horizontal resize arrow shape.
*
* The horizontal resize arrow shape.
*/
#define GLFW_HRESIZE_CURSOR 0x00036005
/*! @brief The vertical resize arrow shape.
*
* The vertical resize arrow shape.
*/
#define GLFW_VRESIZE_CURSOR 0x00036006
typedef enum {
GLFW_ARROW_CURSOR,
GLFW_IBEAM_CURSOR,
GLFW_CROSSHAIR_CURSOR,
GLFW_HAND_CURSOR,
GLFW_HRESIZE_CURSOR,
GLFW_VRESIZE_CURSOR,
GLFW_NW_RESIZE_CURSOR,
GLFW_NE_RESIZE_CURSOR,
GLFW_SW_RESIZE_CURSOR,
GLFW_SE_RESIZE_CURSOR,
GLFW_INVALID_CURSOR
} GLFWCursorShape;
/*! @} */
#define GLFW_CONNECTED 0x00040001
@ -1489,6 +1472,10 @@ typedef void (*glfwGetMonitorPos_func)(GLFWmonitor*, int*, int*);
glfwGetMonitorPos_func glfwGetMonitorPos_impl;
#define glfwGetMonitorPos glfwGetMonitorPos_impl
typedef void (*glfwGetMonitorWorkarea_func)(GLFWmonitor*, int*, int*, int*, int*);
glfwGetMonitorWorkarea_func glfwGetMonitorWorkarea_impl;
#define glfwGetMonitorWorkarea glfwGetMonitorWorkarea_impl
typedef void (*glfwGetMonitorPhysicalSize_func)(GLFWmonitor*, int*, int*);
glfwGetMonitorPhysicalSize_func glfwGetMonitorPhysicalSize_impl;
#define glfwGetMonitorPhysicalSize glfwGetMonitorPhysicalSize_impl
@ -1753,7 +1740,7 @@ typedef GLFWcursor* (*glfwCreateCursor_func)(const GLFWimage*, int, int, int);
glfwCreateCursor_func glfwCreateCursor_impl;
#define glfwCreateCursor glfwCreateCursor_impl
typedef GLFWcursor* (*glfwCreateStandardCursor_func)(int);
typedef GLFWcursor* (*glfwCreateStandardCursor_func)(GLFWCursorShape);
glfwCreateStandardCursor_func glfwCreateStandardCursor_impl;
#define glfwCreateStandardCursor glfwCreateStandardCursor_impl