diff options
author | Campbell Barton <campbell@blender.org> | 2022-06-18 08:10:03 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-06-18 10:16:42 +0300 |
commit | 498f079d2c3644b47ff5c004bc1cf93a9ba6604b (patch) | |
tree | 005d5f0bca3a170a5c0e9aada12ad273a44f1d78 /intern | |
parent | 881d1c9bc234e203cff033ea02998ce99f3070cd (diff) |
GHOST/Wayland: support displaying custom software cursors
Add a method to access the custom cursor from GHOST which is used
for drawing a software cursor. This means the knife tools cursor now
work as expected.
Although non-custom cursors are still not supported.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/GHOST_C-api.h | 3 | ||||
-rw-r--r-- | intern/ghost/GHOST_IWindow.h | 2 | ||||
-rw-r--r-- | intern/ghost/GHOST_Types.h | 10 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_C-api.cpp | 8 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 25 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.h | 2 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Window.cpp | 6 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Window.h | 2 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWayland.cpp | 5 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWayland.h | 2 |
10 files changed, 65 insertions, 0 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 08ca9603985..5ace0fcc9d2 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -364,6 +364,9 @@ extern GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle int hotY, bool canInvertColor); +extern GHOST_TSuccess GHOST_GetCursorBitmap(GHOST_WindowHandle windowhandle, + GHOST_CursorBitmapRef *bitmap); + /** * Returns the visibility state of the cursor. * \param windowhandle: The handle to the window. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index f9552246e89..f712d9bd9f0 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -285,6 +285,8 @@ class GHOST_IWindow { int hotY, bool canInvertColor) = 0; + virtual GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap) = 0; + /** * Returns the visibility state of the cursor. * \return The visibility state of the cursor. diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 78f2b24ea78..35bde3d4413 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -44,6 +44,16 @@ GHOST_DECLARE_HANDLE(GHOST_XrContextHandle); typedef void (*GHOST_TBacktraceFn)(void *file_handle); +/** + * A reference to cursor bitmap data. + */ +typedef struct { + /** `RGBA` bytes. */ + const uint8_t *data; + int data_size[2]; + int hot_spot[2]; +} GHOST_CursorBitmapRef; + typedef struct { int flags; } GHOST_GLSettings; diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 032ecd6aab5..2b5414cd47b 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -326,6 +326,14 @@ GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle, return window->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor); } +GHOST_TSuccess GHOST_GetCursorBitmap(GHOST_WindowHandle windowhandle, + GHOST_CursorBitmapRef *bitmap) +{ + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + + return window->getCursorBitmap(bitmap); +} + bool GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index bff96b3c0a4..aebee003145 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -96,6 +96,7 @@ struct buffer_t { struct cursor_t { bool visible = false; + bool is_custom = false; struct wl_surface *wl_surface = nullptr; struct wl_buffer *wl_buffer = nullptr; struct wl_cursor_image wl_image = {0}; @@ -2587,6 +2588,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorShape(GHOST_TStandardCursor shape) return GHOST_kFailure; } + c->is_custom = false; c->wl_buffer = buffer; c->wl_image = *image; @@ -2650,6 +2652,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap, nullptr, cursor->file_buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (cursor->file_buffer->data == MAP_FAILED) { + cursor->file_buffer->data = nullptr; close(fd); return GHOST_kFailure; } @@ -2694,6 +2697,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap, } } + cursor->is_custom = true; cursor->wl_buffer = buffer; cursor->wl_image.width = uint32_t(sizex); cursor->wl_image.height = uint32_t(sizey); @@ -2705,6 +2709,27 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap, return GHOST_kSuccess; } +GHOST_TSuccess GHOST_SystemWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitmap) +{ + cursor_t *cursor = &d->inputs[0]->cursor; + if (cursor->file_buffer->data == nullptr) { + return GHOST_kFailure; + } + if (!cursor->is_custom) { + return GHOST_kFailure; + } + + bitmap->data_size[0] = cursor->wl_image.width; + bitmap->data_size[1] = cursor->wl_image.height; + + bitmap->hot_spot[0] = cursor->wl_image.hotspot_x; + bitmap->hot_spot[1] = cursor->wl_image.hotspot_y; + + bitmap->data = (uint8_t *)static_cast<void *>(cursor->file_buffer->data); + + return GHOST_kSuccess; +} + GHOST_TSuccess GHOST_SystemWayland::setCursorVisibility(bool visible) { if (d->inputs.empty()) { diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index 6faff8d57c1..04aa4063947 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -122,6 +122,8 @@ class GHOST_SystemWayland : public GHOST_System { int hotY, bool canInvertColor); + GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap); + GHOST_TSuccess setCursorVisibility(bool visible); bool supportsCursorWarp(); diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index d6dcb269c8f..3f093840d0c 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -208,6 +208,12 @@ GHOST_TSuccess GHOST_Window::setCustomCursorShape( return GHOST_kFailure; } +GHOST_TSuccess GHOST_Window::getCursorBitmap(GHOST_CursorBitmapRef * /*bitmap*/) +{ + /* Sub-classes may override. */ + return GHOST_kFailure; +} + void GHOST_Window::setAcceptDragOperation(bool canAccept) { m_canAcceptDragOperation = canAccept; diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 6ca2651fad0..5ff91c05b16 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -117,6 +117,8 @@ class GHOST_Window : public GHOST_IWindow { int hotY, bool canInvertColor); + GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap); + /** * Returns the visibility state of the cursor. * \return The visibility state of the cursor. diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 8c7183971ab..941e08ff035 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -503,6 +503,11 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCustomCursorShape( return m_system->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor); } +GHOST_TSuccess GHOST_WindowWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitmap) +{ + return m_system->getCursorBitmap(bitmap); +} + void GHOST_WindowWayland::setTitle(const char *title) { xdg_toplevel_set_title(w->xdg_toplevel, title); diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h index f9effc636a1..d1eadd8fcd4 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.h +++ b/intern/ghost/intern/GHOST_WindowWayland.h @@ -54,6 +54,8 @@ class GHOST_WindowWayland : public GHOST_Window { bool canInvertColor) override; bool getCursorGrabUseSoftwareDisplay() override; + GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap) override; + void setTitle(const char *title) override; std::string getTitle() const override; |