From 4e51008a826f178171a510126e905495c6f78a45 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 27 Mar 2023 10:12:19 +1100 Subject: [PATCH] GHOST: replace multiple functions with a single capabilities flag Adding checks for platform capabilities involved adding functions to multiple classes and was too involved. Replace this with a single GHOST_System::getCapabilities() function. --- intern/ghost/GHOST_C-api.h | 14 ++------- intern/ghost/GHOST_ISystem.h | 16 +++------- intern/ghost/GHOST_Types.h | 31 +++++++++++++++++++ intern/ghost/intern/GHOST_C-api.cpp | 16 ++-------- intern/ghost/intern/GHOST_System.cpp | 15 --------- intern/ghost/intern/GHOST_System.h | 4 --- intern/ghost/intern/GHOST_SystemCocoa.h | 2 ++ intern/ghost/intern/GHOST_SystemCocoa.mm | 8 +++++ intern/ghost/intern/GHOST_SystemHeadless.h | 7 +++++ intern/ghost/intern/GHOST_SystemSDL.cpp | 9 ++++++ intern/ghost/intern/GHOST_SystemSDL.h | 2 ++ intern/ghost/intern/GHOST_SystemWayland.cpp | 26 ++++++---------- intern/ghost/intern/GHOST_SystemWayland.h | 4 +-- intern/ghost/intern/GHOST_SystemWin32.cpp | 8 +++++ intern/ghost/intern/GHOST_SystemWin32.h | 2 ++ intern/ghost/intern/GHOST_SystemX11.cpp | 4 +-- intern/ghost/intern/GHOST_SystemX11.h | 2 +- source/blender/windowmanager/intern/wm_draw.c | 2 +- .../windowmanager/intern/wm_event_system.cc | 3 +- .../blender/windowmanager/intern/wm_window.c | 20 ++++++++---- 20 files changed, 108 insertions(+), 87 deletions(-) diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index bc1da581580..683c1af120c 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -924,19 +924,9 @@ extern bool GHOST_setConsoleWindowState(GHOST_TConsoleWindowState action); extern bool GHOST_UseNativePixels(void); /** - * Warp the cursor, if supported. + * Return features which are supported by the GHOST back-end. */ -extern bool GHOST_SupportsCursorWarp(void); - -/** - * Support positioning windows (when false `wmWindow.x,y` are meaningless). - */ -extern bool GHOST_SupportsWindowPosition(void); - -/** - * Support a separate primary clipboard. - */ -extern bool GHOST_SupportsPrimaryClipboard(void); +extern GHOST_TCapabilityFlag GHOST_GetCapabilities(void); /** * Assign the callback which generates a back-trace (may be NULL). diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 11faaa84045..45e757eb525 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -318,19 +318,11 @@ class GHOST_ISystem { virtual bool useNativePixel(void) = 0; /** - * Return true when warping the cursor is supported. + * Return features supported by the system back-end. + * + * The resulting value doesn't change at run-time. */ - virtual bool supportsCursorWarp() = 0; - - /** - * Return true getting/setting the window position is supported. - */ - virtual bool supportsWindowPosition() = 0; - - /** - * Return true when a separate primary clipboard is supported. - */ - virtual bool supportsPrimaryClipboard() = 0; + virtual GHOST_TCapabilityFlag getCapabilities() const = 0; /** * Focus window after opening, or put them in the background. diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 72807b354bf..1886306976c 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -74,6 +74,37 @@ typedef void *GHOST_TUserDataPtr; typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess; +/** + * Static flag (relating to the back-ends support for features). + * + * \note When adding new capabilities, add to #GHOST_CAPABILITY_FLAG_ALL, + * then mask out of from the `getCapabilities(..)` callback with an explanation for why + * the feature is not supported. + */ +typedef enum { + /** + * Set when warping the cursor is supported (re-positioning the users cursor). + */ + GHOST_kCapabilityCursorWarp = (1 << 0), + /** + * Set when getting/setting the window position is supported. + */ + GHOST_kCapabilityWindowPosition = (1 << 1), + /** + * Set when a separate primary clipboard is supported. + * This is a convention for X11/WAYLAND, select text & MMB to paste (without an explicit copy). + */ + GHOST_kCapabilityPrimaryClipboard = (1 << 2), +} GHOST_TCapabilityFlag; + +/** + * Back-ends should use this, masking out features which are not supported + * with notes as to why those features cannot be supported. + */ +#define GHOST_CAPABILITY_FLAG_ALL \ + (GHOST_kCapabilityCursorWarp | GHOST_kCapabilityWindowPosition | \ + GHOST_kCapabilityPrimaryClipboard) + /* Xtilt and Ytilt represent how much the pen is tilted away from * vertically upright in either the X or Y direction, with X and Y the * axes of the tablet surface. diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index f55dacf902b..00436ceb4cc 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -895,22 +895,10 @@ bool GHOST_UseNativePixels(void) return system->useNativePixel(); } -bool GHOST_SupportsCursorWarp(void) +GHOST_TCapabilityFlag GHOST_GetCapabilities(void) { GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->supportsCursorWarp(); -} - -bool GHOST_SupportsWindowPosition(void) -{ - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->supportsWindowPosition(); -} - -bool GHOST_SupportsPrimaryClipboard(void) -{ - GHOST_ISystem *system = GHOST_ISystem::getSystem(); - return system->supportsPrimaryClipboard(); + return system->getCapabilities(); } void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn) diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index 32db34e8c30..9094e5a5b97 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -418,21 +418,6 @@ void GHOST_System::setAutoFocus(const bool auto_focus) m_autoFocus = auto_focus; } -bool GHOST_System::supportsCursorWarp() -{ - return true; -} - -bool GHOST_System::supportsWindowPosition() -{ - return true; -} - -bool GHOST_System::supportsPrimaryClipboard() -{ - return false; -} - void GHOST_System::initDebug(GHOST_Debug debug) { m_is_debug_enabled = debug.flags & GHOST_kDebugDefault; diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index 19ba34a0693..4ceb2ff81bc 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -150,10 +150,6 @@ class GHOST_System : public GHOST_ISystem { bool useNativePixel(void); bool m_nativePixel; - bool supportsCursorWarp(void); - bool supportsWindowPosition(void); - bool supportsPrimaryClipboard(void); - /** * Focus window after opening, or put them in the background. */ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 0211694aad4..2a9056619be 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -193,6 +193,8 @@ class GHOST_SystemCocoa : public GHOST_System { */ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; + GHOST_TCapabilityFlag getCapabilities() const; + /** * Returns Clipboard data * \param selection: Indicate which buffer to return. diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 9dabf704ad6..fc1032bfe3e 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -900,6 +900,14 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons &buttons) const return GHOST_kSuccess; } +GHOST_TCapabilityFlag GHOST_SystemCocoa::getCapabilities() const +{ + return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL & + ~( + /* Cocoa has no support for a primary selection clipboard. */ + GHOST_kCapabilityPrimaryClipboard)); +} + #pragma mark Event handlers /** diff --git a/intern/ghost/intern/GHOST_SystemHeadless.h b/intern/ghost/intern/GHOST_SystemHeadless.h index 66af65f763d..02a09dd6c9e 100644 --- a/intern/ghost/intern/GHOST_SystemHeadless.h +++ b/intern/ghost/intern/GHOST_SystemHeadless.h @@ -42,6 +42,13 @@ class GHOST_SystemHeadless : public GHOST_System { { return GHOST_kSuccess; } + GHOST_TCapabilityFlag getCapabilities() const override + { + return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL & + /* No windowing functionality supported. */ + ~(GHOST_kCapabilityWindowPosition | GHOST_kCapabilityCursorWarp | + GHOST_kCapabilityPrimaryClipboard)); + } char *getClipboard(bool /*selection*/) const override { return nullptr; diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index e02b3817687..383cc1dcebf 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -751,6 +751,15 @@ GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons &buttons) const return GHOST_kSuccess; } +GHOST_TCapabilityFlag GHOST_SystemSDL::getCapabilities() const +{ + return GHOST_TCapabilityFlag( + GHOST_CAPABILITY_FLAG_ALL & + ~( + /* This SDL back-end has not yet implemented primary clipboard. */ + GHOST_kCapabilityPrimaryClipboard)); +} + char *GHOST_SystemSDL::getClipboard(bool /*selection*/) const { return (char *)SDL_GetClipboardText(); diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h index 385bfb841e3..36321757c0d 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.h +++ b/intern/ghost/intern/GHOST_SystemSDL.h @@ -42,6 +42,8 @@ class GHOST_SystemSDL : public GHOST_System { GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; + GHOST_TCapabilityFlag getCapabilities() const; + char *getClipboard(bool selection) const; void putClipboard(const char *buffer, bool selection) const; diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 6bbb8527971..77f1086348c 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -6675,22 +6675,16 @@ GHOST_TSuccess GHOST_SystemWayland::cursor_visibility_set(const bool visible) return GHOST_kSuccess; } -bool GHOST_SystemWayland::supportsCursorWarp() +GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const { - /* WAYLAND doesn't support setting the cursor position directly, - * this is an intentional choice, forcing us to use a software cursor in this case. */ - return false; -} - -bool GHOST_SystemWayland::supportsWindowPosition() -{ - /* WAYLAND doesn't support accessing the window position. */ - return false; -} - -bool GHOST_SystemWayland::supportsPrimaryClipboard() -{ - return true; + return GHOST_TCapabilityFlag( + GHOST_CAPABILITY_FLAG_ALL & + ~( + /* WAYLAND doesn't support accessing the window position. */ + GHOST_kCapabilityWindowPosition | + /* WAYLAND doesn't support setting the cursor position directly, + * this is an intentional choice, forcing us to use a software cursor in this case. */ + GHOST_kCapabilityCursorWarp)); } bool GHOST_SystemWayland::cursor_grab_use_software_display_get(const GHOST_TGrabCursorMode mode) @@ -7038,7 +7032,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod const struct GWL_SeatStateGrab grab_state_next = seat_grab_state_from_mode(mode, use_software_confine); - /* Check for wrap as #supportsCursorWarp isn't supported. */ + /* Check for wrap as #GHOST_kCapabilityCursorWarp isn't supported. */ const bool use_visible = !(ELEM(mode, GHOST_kGrabHide, GHOST_kGrabWrap) || use_software_confine); const bool is_hardware_cursor = !cursor_is_software(mode, use_software_confine); diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index c830c9b06f2..5bc555051a2 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -142,9 +142,7 @@ class GHOST_SystemWayland : public GHOST_System { const bool is_dialog, const GHOST_IWindow *parentWindow) override; - bool supportsCursorWarp() override; - bool supportsWindowPosition() override; - bool supportsPrimaryClipboard() override; + GHOST_TCapabilityFlag getCapabilities() const override; /* WAYLAND utility functions (share window/system logic). */ diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index b66c59038af..f49bac243f1 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -496,6 +496,14 @@ GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons &buttons) const return GHOST_kSuccess; } +GHOST_TCapabilityFlag GHOST_SystemWin32::getCapabilities() const +{ + return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL & + ~( + /* WIN32 has no support for a primary selection clipboard. */ + GHOST_kCapabilityPrimaryClipboard)); +} + GHOST_TSuccess GHOST_SystemWin32::init() { GHOST_TSuccess success = GHOST_System::init(); diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index 48443d56dc2..29c35891062 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -199,6 +199,8 @@ class GHOST_SystemWin32 : public GHOST_System { */ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; + GHOST_TCapabilityFlag getCapabilities() const; + /** * Returns unsigned char from CUT_BUFFER0 * \param selection: Used by X11 only. diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 3eb73834bf8..bd389538530 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -1740,9 +1740,9 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y) return GHOST_kSuccess; } -bool GHOST_SystemX11::supportsPrimaryClipboard() +GHOST_TCapabilityFlag GHOST_SystemX11::getCapabilities() const { - return true; + return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL); } void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind) diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index d8440048a89..5f96dd49db6 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -168,7 +168,7 @@ class GHOST_SystemX11 : public GHOST_System { */ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; - bool supportsPrimaryClipboard() override; + GHOST_TCapabilityFlag getCapabilities() const; /** * Flag a window as dirty. This will diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 1e0002a4f11..93688c89da9 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -179,7 +179,7 @@ struct GrabState { static bool wm_software_cursor_needed(void) { if (UNLIKELY(g_software_cursor.enabled == -1)) { - g_software_cursor.enabled = !GHOST_SupportsCursorWarp(); + g_software_cursor.enabled = !(WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP); } return g_software_cursor.enabled; } diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 9b36c77abfa..16dc17e2e0c 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -5165,7 +5165,8 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event) { /* If GHOST doesn't support window positioning, don't use this feature at all. */ - const static int8_t supports_window_position = GHOST_SupportsWindowPosition(); + const static int8_t supports_window_position = (WM_capabilities_flag() & + WM_CAPABILITY_WINDOW_POSITION) != 0; if (!supports_window_position) { return nullptr; } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 812a0744681..884c40651fd 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -998,7 +998,11 @@ wmWindow *WM_window_open(bContext *C, return NULL; } -/* ****************** Operators ****************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Operators + * \{ */ int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -1063,7 +1067,11 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -/* ************ events *************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Events + * \{ */ void wm_cursor_position_from_ghost_client_coords(wmWindow *win, int *x, int *y) { @@ -1827,14 +1835,14 @@ eWM_CapabilitiesFlag WM_capabilities_flag(void) return flag; } - flag = 0; - if (GHOST_SupportsCursorWarp()) { + const GHOST_TCapabilityFlag ghost_flag = GHOST_GetCapabilities(); + if (ghost_flag & GHOST_kCapabilityCursorWarp) { flag |= WM_CAPABILITY_CURSOR_WARP; } - if (GHOST_SupportsWindowPosition()) { + if (ghost_flag & GHOST_kCapabilityWindowPosition) { flag |= WM_CAPABILITY_WINDOW_POSITION; } - if (GHOST_SupportsPrimaryClipboard()) { + if (ghost_flag & GHOST_kCapabilityPrimaryClipboard) { flag |= WM_CAPABILITY_PRIMARY_CLIPBOARD; }