From e8f3de0f2e89a0a8fc9749c91913b618bd786291 Mon Sep 17 00:00:00 2001 From: Ricardo Vieira Date: Fri, 23 Oct 2015 00:28:16 +0100 Subject: [PATCH] Implement glfwCreateStandardCursor for Wayland Closes #620. --- src/wl_init.c | 8 ------- src/wl_platform.h | 2 +- src/wl_window.c | 61 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index c9a41a0d..69f0e5e4 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -586,14 +586,6 @@ int _glfwPlatformInit(void) "Wayland: Unable to load default cursor theme\n"); return GLFW_FALSE; } - _glfw.wl.defaultCursor = - wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr"); - if (!_glfw.wl.defaultCursor) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Unable to load default left pointer\n"); - return GLFW_FALSE; - } _glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor); } diff --git a/src/wl_platform.h b/src/wl_platform.h index d5ba2b19..538ba12d 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -84,7 +84,6 @@ typedef struct _GLFWlibraryWayland struct wl_keyboard* keyboard; struct wl_cursor_theme* cursorTheme; - struct wl_cursor* defaultCursor; struct wl_surface* cursorSurface; uint32_t pointerSerial; @@ -130,6 +129,7 @@ typedef struct _GLFWmonitorWayland // typedef struct _GLFWcursorWayland { + struct wl_cursor_image* image; struct wl_buffer* buffer; int width, height; int xhot, yhot; diff --git a/src/wl_window.c b/src/wl_window.c index 3c65720d..079de2ef 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -207,6 +207,28 @@ createAnonymousFile(off_t size) return fd; } +// Translates a GLFW standard cursor to a theme cursor name +// +static char *translateCursorShape(int shape) +{ + 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 "grabbing"; + case GLFW_HRESIZE_CURSOR: + return "sb_h_double_arrow"; + case GLFW_VRESIZE_CURSOR: + return "sb_v_double_arrow"; + } + return NULL; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// @@ -469,19 +491,34 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) { - // TODO - fprintf(stderr, "_glfwPlatformCreateStandardCursor not implemented yet\n"); - return GLFW_FALSE; + struct wl_cursor* standard_cursor; + + standard_cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, + translateCursorShape(shape)); + if (!standard_cursor) { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Standard cursor \"%s\" not found", + translateCursorShape(shape)); + return GLFW_FALSE; + } + cursor->wl.image = standard_cursor->images[0]; + + return GLFW_TRUE; } void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) { + // If it's a standard cursor we don't need to do anything here + if (cursor->wl.image) + return; + wl_buffer_destroy(cursor->wl.buffer); } void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) { struct wl_buffer* buffer; + struct wl_cursor* defaultCursor; struct wl_cursor_image* image; struct wl_surface* surface = _glfw.wl.cursorSurface; @@ -499,7 +536,23 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) { if (cursor == NULL) { - image = _glfw.wl.defaultCursor->images[0]; + defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, + "left_ptr"); + if (!defaultCursor) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Standard cursor not found"); + return; + } + image = defaultCursor->images[0]; + } + else + { + image = cursor->wl.image; + } + + if (image) + { buffer = wl_cursor_image_get_buffer(image); if (!buffer) return;