From 95573c3314d24eeefb3481a0a48e9dcb27fc4b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tau=20G=C3=A4rtli?= Date: Thu, 4 Sep 2025 13:02:02 +0200 Subject: [PATCH] Load DBus at runtime --- src/CMakeLists.txt | 4 +- src/wl_init.c | 67 ++++++++++++++++++++++++++ src/wl_platform.h | 114 +++++++++++++++++++++++++++++++++++++++++++++ src/wl_window.c | 7 +-- 4 files changed, 186 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63d51304..cdb5facf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -161,9 +161,7 @@ if (GLFW_BUILD_WAYLAND) wayland-egl>=0.2.7 xkbcommon>=0.5.0) - pkg_check_modules(DBUS REQUIRED dbus-1) - target_include_directories(glfw PRIVATE ${DBUS_INCLUDE_DIRS}) - target_link_libraries(glfw PRIVATE ${DBUS_LIBRARIES}) + set(DBUS_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS}) diff --git a/src/wl_init.c b/src/wl_init.c index ef9e4503..c0d51b0b 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -829,6 +829,73 @@ int _glfwInitWayland(void) } } + _glfw.wl.dbus.handle = _glfwPlatformLoadModule("libdbus-1.so.3"); + + if (_glfw.wl.dbus.handle) + { + _glfw.wl.dbus.dbus_error_init_ = (PFN_dbus_error_init) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_error_init"); + _glfw.wl.dbus.dbus_error_free_ = (PFN_dbus_error_free) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_error_free"); + _glfw.wl.dbus.dbus_error_is_set_ = (PFN_dbus_error_is_set) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_error_is_set"); + _glfw.wl.dbus.dbus_bus_get_ = (PFN_dbus_bus_get) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_bus_get"); + _glfw.wl.dbus.dbus_connection_set_exit_on_disconnect_ = (PFN_dbus_connection_set_exit_on_disconnect) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_connection_set_exit_on_disconnect"); + _glfw.wl.dbus.dbus_connection_send_with_reply_and_block_ = (PFN_dbus_connection_send_with_reply_and_block) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_connection_send_with_reply_and_block"); + _glfw.wl.dbus.dbus_message_new_method_call_ = (PFN_dbus_message_new_method_call) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_new_method_call"); + _glfw.wl.dbus.dbus_message_unref_ = (PFN_dbus_message_unref) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_unref"); + _glfw.wl.dbus.dbus_message_iter_init_ = (PFN_dbus_message_iter_init) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_init"); + _glfw.wl.dbus.dbus_message_iter_init_append_ = (PFN_dbus_message_iter_init_append) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_init_append"); + _glfw.wl.dbus.dbus_message_iter_append_basic_ = (PFN_dbus_message_iter_append_basic) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_append_basic"); + _glfw.wl.dbus.dbus_message_iter_open_container_ = (PFN_dbus_message_iter_open_container) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_open_container"); + _glfw.wl.dbus.dbus_message_iter_close_container_ = (PFN_dbus_message_iter_close_container) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_close_container"); + _glfw.wl.dbus.dbus_message_iter_get_arg_type_ = (PFN_dbus_message_iter_get_arg_type) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_get_arg_type"); + _glfw.wl.dbus.dbus_message_iter_get_element_type_ = (PFN_dbus_message_iter_get_element_type) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_get_element_type"); + _glfw.wl.dbus.dbus_message_iter_recurse_ = (PFN_dbus_message_iter_recurse) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_recurse"); + _glfw.wl.dbus.dbus_message_iter_get_element_count_ = (PFN_dbus_message_iter_get_element_count) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_get_element_count"); + _glfw.wl.dbus.dbus_message_iter_get_basic_ = (PFN_dbus_message_iter_get_basic) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_get_basic"); + _glfw.wl.dbus.dbus_message_iter_next_ = (PFN_dbus_message_iter_next) + _glfwPlatformGetModuleSymbol(_glfw.wl.dbus.handle, "dbus_message_iter_next"); + if (!_glfw.wl.dbus.dbus_error_init_ || + !_glfw.wl.dbus.dbus_error_free_ || + !_glfw.wl.dbus.dbus_error_is_set_ || + !_glfw.wl.dbus.dbus_bus_get_ || + !_glfw.wl.dbus.dbus_connection_set_exit_on_disconnect_ || + !_glfw.wl.dbus.dbus_connection_send_with_reply_and_block_ || + !_glfw.wl.dbus.dbus_message_new_method_call_ || + !_glfw.wl.dbus.dbus_message_unref_ || + !_glfw.wl.dbus.dbus_message_iter_init_ || + !_glfw.wl.dbus.dbus_message_iter_init_append_ || + !_glfw.wl.dbus.dbus_message_iter_append_basic_ || + !_glfw.wl.dbus.dbus_message_iter_open_container_ || + !_glfw.wl.dbus.dbus_message_iter_close_container_ || + !_glfw.wl.dbus.dbus_message_iter_get_arg_type_ || + !_glfw.wl.dbus.dbus_message_iter_get_element_type_ || + !_glfw.wl.dbus.dbus_message_iter_recurse_ || + !_glfw.wl.dbus.dbus_message_iter_get_element_count_ || + !_glfw.wl.dbus.dbus_message_iter_get_basic_ || + !_glfw.wl.dbus.dbus_message_iter_next_) + { + _glfwPlatformFreeModule(_glfw.wl.dbus.handle); + memset(&_glfw.wl.dbus, 0, sizeof(_glfw.wl.dbus)); + } + } + _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); diff --git a/src/wl_platform.h b/src/wl_platform.h index aa724a16..35647c5c 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -326,6 +326,97 @@ typedef void (* PFN_libdecor_state_free)(struct libdecor_state*); #define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_ #define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_ +#define DBUS_FALSE 0 +#define DBUS_TYPE_STRING ((int) 's') +#define DBUS_TYPE_ARRAY ((int) 'a') +#define DBUS_TIMEOUT_INFINITE ((int) 0x7fffffff) + +typedef uint32_t dbus_bool_t; + +typedef struct DBusError +{ + const char *name; + const char *message; + unsigned int dummy1 : 1; + unsigned int dummy2 : 1; + unsigned int dummy3 : 1; + unsigned int dummy4 : 1; + unsigned int dummy5 : 1; + void *padding1; +} DBusError; + +typedef struct DBusConnection DBusConnection; + +typedef enum DBusBusType +{ + DBUS_BUS_SESSION, + DBUS_BUS_SYSTEM, + DBUS_BUS_STARTER, +} DBusBusType; + +typedef struct DBusMessage DBusMessage; + +typedef struct DBusMessageIter +{ +#if DBUS_SIZEOF_VOID_P > 8 + void *dummy[16]; +#else + void *dummy1; + void *dummy2; + uint32_t dummy3; + int dummy4; + int dummy5; + int dummy6; + int dummy7; + int dummy8; + int dummy9; + int dummy10; + int dummy11; + int pad1; + void *pad2; + void *pad3; +#endif +} DBusMessageIter; + +typedef void (* PFN_dbus_error_init) (DBusError*); +typedef void (* PFN_dbus_error_free) (DBusError*); +typedef dbus_bool_t (* PFN_dbus_error_is_set) (const DBusError*); +typedef DBusConnection* (* PFN_dbus_bus_get) (enum DBusBusType, DBusError*); +typedef void (* PFN_dbus_connection_set_exit_on_disconnect) (DBusConnection*, dbus_bool_t); +typedef DBusMessage* (* PFN_dbus_connection_send_with_reply_and_block) (DBusConnection*, DBusMessage*, int, DBusError*); +typedef DBusMessage* (* PFN_dbus_message_new_method_call) (const char*, const char*, const char*, const char*); +typedef void (* PFN_dbus_message_unref) (DBusMessage*); +typedef dbus_bool_t (* PFN_dbus_message_iter_init) (DBusMessage*, DBusMessageIter*); +typedef void (* PFN_dbus_message_iter_init_append) (DBusMessage*, DBusMessageIter*); +typedef dbus_bool_t (* PFN_dbus_message_iter_append_basic) (DBusMessageIter*, int, const void*); +typedef dbus_bool_t (* PFN_dbus_message_iter_open_container) (DBusMessageIter*, int, const char*, DBusMessageIter*); +typedef dbus_bool_t (* PFN_dbus_message_iter_close_container) (DBusMessageIter*, DBusMessageIter*); +typedef int (* PFN_dbus_message_iter_get_arg_type) (DBusMessageIter*); +typedef int (* PFN_dbus_message_iter_get_element_type) (DBusMessageIter*); +typedef void (* PFN_dbus_message_iter_recurse) (DBusMessageIter*, DBusMessageIter*); +typedef int (* PFN_dbus_message_iter_get_element_count) (DBusMessageIter*); +typedef void (* PFN_dbus_message_iter_get_basic) (DBusMessageIter*, void*); +typedef dbus_bool_t (* PFN_dbus_message_iter_next) (DBusMessageIter*); +#define dbus_error_init _glfw.wl.dbus.dbus_error_init_ +#define dbus_error_free _glfw.wl.dbus.dbus_error_free_ +#define dbus_error_is_set _glfw.wl.dbus.dbus_error_is_set_ +#define dbus_bus_get _glfw.wl.dbus.dbus_bus_get_ +#define dbus_connection_set_exit_on_disconnect _glfw.wl.dbus.dbus_connection_set_exit_on_disconnect_ +#define dbus_connection_send_with_reply_and_block _glfw.wl.dbus.dbus_connection_send_with_reply_and_block_ +#define dbus_message_new_method_call _glfw.wl.dbus.dbus_message_new_method_call_ +#define dbus_message_unref _glfw.wl.dbus.dbus_message_unref_ +#define dbus_message_iter_init _glfw.wl.dbus.dbus_message_iter_init_ +#define dbus_message_iter_init_append _glfw.wl.dbus.dbus_message_iter_init_append_ +#define dbus_message_iter_append_basic _glfw.wl.dbus.dbus_message_iter_append_basic_ +#define dbus_message_iter_open_container _glfw.wl.dbus.dbus_message_iter_open_container_ +#define dbus_message_iter_close_container _glfw.wl.dbus.dbus_message_iter_close_container_ +#define dbus_message_iter_get_arg_type _glfw.wl.dbus.dbus_message_iter_get_arg_type_ +#define dbus_message_iter_get_element_type _glfw.wl.dbus.dbus_message_iter_get_element_type_ +#define dbus_message_iter_recurse _glfw.wl.dbus.dbus_message_iter_recurse_ +#define dbus_message_iter_get_element_count _glfw.wl.dbus.dbus_message_iter_get_element_count_ +#define dbus_message_iter_get_basic _glfw.wl.dbus.dbus_message_iter_get_basic_ +#define dbus_message_iter_next _glfw.wl.dbus.dbus_message_iter_next_ + typedef struct _GLFWfallbackEdgeWayland { struct wl_surface* surface; @@ -587,6 +678,29 @@ typedef struct _GLFWlibraryWayland PFN_libdecor_state_new libdecor_state_new_; PFN_libdecor_state_free libdecor_state_free_; } libdecor; + + struct { + void* handle; + PFN_dbus_error_init dbus_error_init_; + PFN_dbus_error_free dbus_error_free_; + PFN_dbus_error_is_set dbus_error_is_set_; + PFN_dbus_bus_get dbus_bus_get_; + PFN_dbus_connection_set_exit_on_disconnect dbus_connection_set_exit_on_disconnect_; + PFN_dbus_connection_send_with_reply_and_block dbus_connection_send_with_reply_and_block_; + PFN_dbus_message_new_method_call dbus_message_new_method_call_; + PFN_dbus_message_unref dbus_message_unref_; + PFN_dbus_message_iter_init dbus_message_iter_init_; + PFN_dbus_message_iter_init_append dbus_message_iter_init_append_; + PFN_dbus_message_iter_append_basic dbus_message_iter_append_basic_; + PFN_dbus_message_iter_open_container dbus_message_iter_open_container_; + PFN_dbus_message_iter_close_container dbus_message_iter_close_container_; + PFN_dbus_message_iter_get_arg_type dbus_message_iter_get_arg_type_; + PFN_dbus_message_iter_get_element_type dbus_message_iter_get_element_type_; + PFN_dbus_message_iter_recurse dbus_message_iter_recurse_; + PFN_dbus_message_iter_get_element_count dbus_message_iter_get_element_count_; + PFN_dbus_message_iter_get_basic dbus_message_iter_get_basic_; + PFN_dbus_message_iter_next dbus_message_iter_next_; + } dbus; } _GLFWlibraryWayland; // Wayland-specific per-monitor data diff --git a/src/wl_window.c b/src/wl_window.c index babc3117..8dd33e01 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -41,7 +41,6 @@ #include #include #include -#include #include "wayland-client-protocol.h" #include "xdg-shell-client-protocol.h" @@ -2035,7 +2034,7 @@ static void dataDeviceHandleEnter(void* userData, _GLFWwindow* window = wl_surface_get_user_data(surface); if (window->wl.surface == surface) { - GLFWbool portal = _glfw.wl.offers[i].portal_file_transfer; + GLFWbool portal = _glfw.wl.offers[i].portal_file_transfer && _glfw.wl.dbus.handle; if (_glfw.wl.offers[i].text_uri_list || portal) { _glfw.wl.dragOffer = offer; @@ -2087,6 +2086,8 @@ static void dataDeviceHandleMotion(void* userData, static void dataDeviceHandleFileTransferPortalDrop(void* userData, struct wl_data_device* device) { + assert(_glfw.wl.dbus.handle != NULL); + char* key = readDataOfferAsString(_glfw.wl.dragOffer, FILE_TRANSFER_PORTAL_MIME_TYPE); if (!key) return; @@ -2101,7 +2102,7 @@ static void dataDeviceHandleFileTransferPortalDrop(void* userData, _glfw_free(key); return; } - dbus_connection_set_exit_on_disconnect(connection, FALSE); + dbus_connection_set_exit_on_disconnect(connection, DBUS_FALSE); DBusMessage* message = dbus_message_new_method_call( "org.freedesktop.portal.Documents",