From a5f81ab7aac0932d3dff6c53933386a33824bcbb Mon Sep 17 00:00:00 2001 From: Nikita Gubarkov Date: Tue, 12 Sep 2023 22:22:49 +0200 Subject: [PATCH] X11:: Add native access to X11 visual and XCB connection Exposed via glfwGetX11Visual and glfwGetXCBConnection, these are useful when doing custom Vulkan surface creation. --- README.md | 2 ++ docs/news.dox | 7 +++++++ include/GLFW/glfw3native.h | 33 ++++++++++++++++++++++++++++++++ src/x11_window.c | 39 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) diff --git a/README.md b/README.md index e3d18ec8..65da2de4 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,8 @@ information on what to include when reporting a bug. ## Changelog + - Added `glfwGetX11Visual` and `glfwGetXCBConnection` + native functions for accessing X11 visual and XCB connection handle - Added `GLFW_PLATFORM` init hint for runtime platform selection (#1958) - Added `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and `GLFW_PLATFORM_NULL` symbols to diff --git a/docs/news.dox b/docs/news.dox index e16267b2..ed4d493f 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -9,6 +9,13 @@ @subsection features_34 New features in version 3.4 +@subsection native_x11_visual_and_xcb_connection_34 X11 native Visual and XCB connection access + +GLFW now supports X11 platform specific native functions for accessing +the X11 visual and XCB connection handle: +@ref glfwGetX11Visual and @ref glfwGetXCBConnection. + + @subsubsection runtime_platform_34 Runtime platform selection GLFW now supports being compiled for multiple backends and selecting between diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index 171abe36..af0d96de 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -117,6 +117,7 @@ extern "C" { #if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) #include #include + typedef struct xcb_connection_t xcb_connection_t; #endif #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) @@ -416,6 +417,38 @@ GLFWAPI void glfwSetX11SelectionString(const char* string); * @ingroup native */ GLFWAPI const char* glfwGetX11SelectionString(void); + +/*! @brief Returns the default `VisualID` used by GLFW. + * + * @return The `VisualID` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.4. + * + * @ingroup native + */ +GLFWAPI VisualID glfwGetX11Visual(void); + +/*! @brief Returns the XCB connection used by GLFW, if any. + * + * @return The XCB connection used by GLFW, or `NULL` if XCB is not used, or an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.4. + * + * @ingroup native + */ +GLFWAPI xcb_connection_t* glfwGetXCBConnection(void); #endif #if defined(GLFW_EXPOSE_NATIVE_GLX) diff --git a/src/x11_window.c b/src/x11_window.c index 7da9b965..f2dacd4c 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -3351,5 +3351,44 @@ GLFWAPI const char* glfwGetX11SelectionString(void) return getSelectionString(_glfw.x11.PRIMARY); } +GLFWAPI VisualID glfwGetX11Visual(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(0); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return 0; + } + + return XVisualIDFromVisual(DefaultVisual(_glfw.x11.display, _glfw.x11.screen)); +} + +GLFWAPI xcb_connection_t* glfwGetXCBConnection(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (_glfw.platform.platformID != GLFW_PLATFORM_X11) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized"); + return NULL; + } + + if (!_glfw.x11.x11xcb.handle) + { + return NULL; + } + + xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display); + if (!connection) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to retrieve XCB connection"); + return NULL; + } + + return connection; +} + #endif // _GLFW_X11