Wayland: Make libwayland-client dynamically loaded
The insight to use wayland.xml to resolve the difficult-to-redirect interface symbols was gleaned from SDL. Instead of compiling the code output of wayland-scanner separately it is made part of the wl_init compilation unit. This lets us do things like transparently rename our copies of Wayland globals. The OS version of wayland-client-protocol.h is no longer used by GLFW, but it is presumably ABI compatible with the output of wayland-scanner. Closes #1174. Closes #1338. Related to #1655. Closes #1943.
This commit is contained in:
parent
87d5646f5d
commit
dffe203c17
@ -205,7 +205,6 @@ if (_GLFW_WAYLAND)
|
||||
list(APPEND glfw_PKG_DEPS "wayland-client")
|
||||
|
||||
list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
|
||||
list(APPEND glfw_LIBRARIES "${Wayland_LINK_LIBRARIES}")
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckFunctionExists)
|
||||
|
@ -226,6 +226,7 @@ information on what to include when reporting a bug.
|
||||
reported (#1112,#1415,#1472,#1616)
|
||||
- [X11] Bugfix: Some window attributes were not applied on leaving fullscreen
|
||||
(#1863)
|
||||
- [Wayland] Added dynamic loading of all Wayland libraries
|
||||
- [Wayland] Removed support for `wl_shell` (#1443)
|
||||
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
||||
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
|
||||
|
@ -57,6 +57,7 @@ if (_GLFW_WAYLAND)
|
||||
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
|
||||
pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols>=1.15)
|
||||
pkg_get_variable(WAYLAND_PROTOCOLS_BASE wayland-protocols pkgdatadir)
|
||||
pkg_get_variable(WAYLAND_CLIENT_PKGDATADIR wayland-client pkgdatadir)
|
||||
|
||||
macro(wayland_generate protocol_file output_file)
|
||||
add_custom_command(OUTPUT "${output_file}.h"
|
||||
@ -64,14 +65,17 @@ if (_GLFW_WAYLAND)
|
||||
DEPENDS "${protocol_file}"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_command(OUTPUT "${output_file}.c"
|
||||
COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" private-code "${protocol_file}" "${output_file}.c"
|
||||
add_custom_command(OUTPUT "${output_file}-code.h"
|
||||
COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" private-code "${protocol_file}" "${output_file}-code.h"
|
||||
DEPENDS "${protocol_file}"
|
||||
VERBATIM)
|
||||
|
||||
target_sources(glfw PRIVATE "${output_file}.h" "${output_file}.c")
|
||||
target_sources(glfw PRIVATE "${output_file}.h" "${output_file}-code.h")
|
||||
endmacro()
|
||||
|
||||
wayland_generate(
|
||||
"${WAYLAND_CLIENT_PKGDATADIR}/wayland.xml"
|
||||
"${GLFW_BINARY_DIR}/src/wayland-client-protocol")
|
||||
wayland_generate(
|
||||
"${WAYLAND_PROTOCOLS_BASE}/stable/xdg-shell/xdg-shell.xml"
|
||||
"${GLFW_BINARY_DIR}/src/wayland-xdg-shell-client-protocol")
|
||||
|
@ -39,7 +39,22 @@
|
||||
#include <sys/timerfd.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "wayland-client-protocol.h"
|
||||
#include "wayland-xdg-shell-client-protocol.h"
|
||||
#include "wayland-xdg-decoration-client-protocol.h"
|
||||
#include "wayland-viewporter-client-protocol.h"
|
||||
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
|
||||
|
||||
#include "wayland-client-protocol-code.h"
|
||||
#include "wayland-xdg-shell-client-protocol-code.h"
|
||||
#include "wayland-xdg-decoration-client-protocol-code.h"
|
||||
#include "wayland-viewporter-client-protocol-code.h"
|
||||
#include "wayland-relative-pointer-unstable-v1-client-protocol-code.h"
|
||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol-code.h"
|
||||
#include "wayland-idle-inhibit-unstable-v1-client-protocol-code.h"
|
||||
|
||||
|
||||
static inline int min(int n1, int n2)
|
||||
@ -1037,6 +1052,69 @@ int _glfwPlatformInit(void)
|
||||
long cursorSizeLong;
|
||||
int cursorSize;
|
||||
|
||||
_glfw.wl.client.handle = _glfw_dlopen("libwayland-client.so.0");
|
||||
if (!_glfw.wl.client.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to open libwayland-client");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.wl.client.display_flush = (PFN_wl_display_flush)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_flush");
|
||||
_glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_cancel_read");
|
||||
_glfw.wl.client.display_dispatch_pending = (PFN_wl_display_dispatch_pending)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_dispatch_pending");
|
||||
_glfw.wl.client.display_read_events = (PFN_wl_display_read_events)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_read_events");
|
||||
_glfw.wl.client.display_connect = (PFN_wl_display_connect)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_connect");
|
||||
_glfw.wl.client.display_disconnect = (PFN_wl_display_disconnect)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_disconnect");
|
||||
_glfw.wl.client.display_roundtrip = (PFN_wl_display_roundtrip)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_roundtrip");
|
||||
_glfw.wl.client.display_get_fd = (PFN_wl_display_get_fd)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_get_fd");
|
||||
_glfw.wl.client.display_prepare_read = (PFN_wl_display_prepare_read)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_prepare_read");
|
||||
_glfw.wl.client.proxy_marshal = (PFN_wl_proxy_marshal)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_proxy_marshal");
|
||||
_glfw.wl.client.proxy_add_listener = (PFN_wl_proxy_add_listener)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_proxy_add_listener");
|
||||
_glfw.wl.client.proxy_destroy = (PFN_wl_proxy_destroy)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_proxy_destroy");
|
||||
_glfw.wl.client.proxy_marshal_constructor = (PFN_wl_proxy_marshal_constructor)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_proxy_marshal_constructor");
|
||||
_glfw.wl.client.proxy_marshal_constructor_versioned = (PFN_wl_proxy_marshal_constructor_versioned)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_proxy_marshal_constructor_versioned");
|
||||
_glfw.wl.client.proxy_get_user_data = (PFN_wl_proxy_get_user_data)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_proxy_get_user_data");
|
||||
_glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data)
|
||||
_glfw_dlsym(_glfw.wl.client.handle, "wl_proxy_set_user_data");
|
||||
|
||||
if (!_glfw.wl.client.display_flush ||
|
||||
!_glfw.wl.client.display_cancel_read ||
|
||||
!_glfw.wl.client.display_dispatch_pending ||
|
||||
!_glfw.wl.client.display_read_events ||
|
||||
!_glfw.wl.client.display_connect ||
|
||||
!_glfw.wl.client.display_disconnect ||
|
||||
!_glfw.wl.client.display_roundtrip ||
|
||||
!_glfw.wl.client.display_get_fd ||
|
||||
!_glfw.wl.client.display_prepare_read ||
|
||||
!_glfw.wl.client.proxy_marshal ||
|
||||
!_glfw.wl.client.proxy_add_listener ||
|
||||
!_glfw.wl.client.proxy_destroy ||
|
||||
!_glfw.wl.client.proxy_marshal_constructor ||
|
||||
!_glfw.wl.client.proxy_marshal_constructor_versioned ||
|
||||
!_glfw.wl.client.proxy_get_user_data ||
|
||||
!_glfw.wl.client.proxy_set_user_data)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to load libwayland-client entry point");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
|
||||
if (!_glfw.wl.cursor.handle)
|
||||
{
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "wayland-client-protocol.h"
|
||||
|
||||
|
||||
static void outputHandleGeometry(void* data,
|
||||
struct wl_output* output,
|
||||
|
@ -24,7 +24,7 @@
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-client-core.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
@ -54,12 +54,80 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
#endif
|
||||
#include "xkb_unicode.h"
|
||||
|
||||
#include "wayland-xdg-shell-client-protocol.h"
|
||||
#include "wayland-xdg-decoration-client-protocol.h"
|
||||
#include "wayland-viewporter-client-protocol.h"
|
||||
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
|
||||
typedef int (* PFN_wl_display_flush)(struct wl_display *display);
|
||||
typedef void (* PFN_wl_display_cancel_read)(struct wl_display *display);
|
||||
typedef int (* PFN_wl_display_dispatch_pending)(struct wl_display *display);
|
||||
typedef int (* PFN_wl_display_read_events)(struct wl_display *display);
|
||||
typedef struct wl_display* (* PFN_wl_display_connect)(const char*);
|
||||
typedef void (* PFN_wl_display_disconnect)(struct wl_display*);
|
||||
typedef int (* PFN_wl_display_roundtrip)(struct wl_display*);
|
||||
typedef int (* PFN_wl_display_get_fd)(struct wl_display*);
|
||||
typedef int (* PFN_wl_display_prepare_read)(struct wl_display*);
|
||||
typedef void (* PFN_wl_proxy_marshal)(struct wl_proxy*,uint32_t,...);
|
||||
typedef int (* PFN_wl_proxy_add_listener)(struct wl_proxy*,void(**)(void),void*);
|
||||
typedef void (* PFN_wl_proxy_destroy)(struct wl_proxy*);
|
||||
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor)(struct wl_proxy*,uint32_t,const struct wl_interface*,...);
|
||||
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,...);
|
||||
typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*);
|
||||
typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*,void*);
|
||||
#define wl_display_flush _glfw.wl.client.display_flush
|
||||
#define wl_display_cancel_read _glfw.wl.client.display_cancel_read
|
||||
#define wl_display_dispatch_pending _glfw.wl.client.display_dispatch_pending
|
||||
#define wl_display_read_events _glfw.wl.client.display_read_events
|
||||
#define wl_display_connect _glfw.wl.client.display_connect
|
||||
#define wl_display_disconnect _glfw.wl.client.display_disconnect
|
||||
#define wl_display_roundtrip _glfw.wl.client.display_roundtrip
|
||||
#define wl_display_get_fd _glfw.wl.client.display_get_fd
|
||||
#define wl_display_prepare_read _glfw.wl.client.display_prepare_read
|
||||
#define wl_proxy_marshal _glfw.wl.client.proxy_marshal
|
||||
#define wl_proxy_add_listener _glfw.wl.client.proxy_add_listener
|
||||
#define wl_proxy_destroy _glfw.wl.client.proxy_destroy
|
||||
#define wl_proxy_marshal_constructor _glfw.wl.client.proxy_marshal_constructor
|
||||
#define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned
|
||||
#define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data
|
||||
#define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data
|
||||
|
||||
struct wl_shm;
|
||||
|
||||
#define wl_display_interface _glfw_wl_display_interface
|
||||
#define wl_subcompositor_interface _glfw_wl_subcompositor_interface
|
||||
#define wl_compositor_interface _glfw_wl_compositor_interface
|
||||
#define wl_shm_interface _glfw_wl_shm_interface
|
||||
#define wl_data_device_manager_interface _glfw_wl_data_device_manager_interface
|
||||
#define wl_shell_interface _glfw_wl_shell_interface
|
||||
#define wl_buffer_interface _glfw_wl_buffer_interface
|
||||
#define wl_callback_interface _glfw_wl_callback_interface
|
||||
#define wl_data_device_interface _glfw_wl_data_device_interface
|
||||
#define wl_data_offer_interface _glfw_wl_data_offer_interface
|
||||
#define wl_data_source_interface _glfw_wl_data_source_interface
|
||||
#define wl_keyboard_interface _glfw_wl_keyboard_interface
|
||||
#define wl_output_interface _glfw_wl_output_interface
|
||||
#define wl_pointer_interface _glfw_wl_pointer_interface
|
||||
#define wl_region_interface _glfw_wl_region_interface
|
||||
#define wl_registry_interface _glfw_wl_registry_interface
|
||||
#define wl_seat_interface _glfw_wl_seat_interface
|
||||
#define wl_shell_surface_interface _glfw_wl_shell_surface_interface
|
||||
#define wl_shm_pool_interface _glfw_wl_shm_pool_interface
|
||||
#define wl_subsurface_interface _glfw_wl_subsurface_interface
|
||||
#define wl_surface_interface _glfw_wl_surface_interface
|
||||
#define wl_touch_interface _glfw_wl_touch_interface
|
||||
#define zwp_idle_inhibitor_v1_interface _glfw_zwp_idle_inhibitor_v1_interface
|
||||
#define zwp_idle_inhibit_manager_v1_interface _glfw_zwp_idle_inhibit_manager_v1_interface
|
||||
#define zwp_confined_pointer_v1_interface _glfw_zwp_confined_pointer_v1_interface
|
||||
#define zwp_locked_pointer_v1_interface _glfw_zwp_locked_pointer_v1_interface
|
||||
#define zwp_pointer_constraints_v1_interface _glfw_zwp_pointer_constraints_v1_interface
|
||||
#define zwp_relative_pointer_v1_interface _glfw_zwp_relative_pointer_v1_interface
|
||||
#define zwp_relative_pointer_manager_v1_interface _glfw_zwp_relative_pointer_manager_v1_interface
|
||||
#define wp_viewport_interface _glfw_wp_viewport_interface
|
||||
#define wp_viewporter_interface _glfw_wp_viewporter_interface
|
||||
#define xdg_toplevel_interface _glfw_xdg_toplevel_interface
|
||||
#define zxdg_toplevel_decoration_v1_interface _glfw_zxdg_toplevel_decoration_v1_interface
|
||||
#define zxdg_decoration_manager_v1_interface _glfw_zxdg_decoration_manager_v1_interface
|
||||
#define xdg_popup_interface _glfw_xdg_popup_interface
|
||||
#define xdg_positioner_interface _glfw_xdg_positioner_interface
|
||||
#define xdg_surface_interface _glfw_xdg_surface_interface
|
||||
#define xdg_toplevel_interface _glfw_xdg_toplevel_interface
|
||||
#define xdg_wm_base_interface _glfw_xdg_wm_base_interface
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
@ -302,6 +370,26 @@ typedef struct _GLFWlibraryWayland
|
||||
_GLFWwindow* pointerFocus;
|
||||
_GLFWwindow* keyboardFocus;
|
||||
|
||||
struct {
|
||||
void* handle;
|
||||
PFN_wl_display_flush display_flush;
|
||||
PFN_wl_display_cancel_read display_cancel_read;
|
||||
PFN_wl_display_dispatch_pending display_dispatch_pending;
|
||||
PFN_wl_display_read_events display_read_events;
|
||||
PFN_wl_display_connect display_connect;
|
||||
PFN_wl_display_disconnect display_disconnect;
|
||||
PFN_wl_display_roundtrip display_roundtrip;
|
||||
PFN_wl_display_get_fd display_get_fd;
|
||||
PFN_wl_display_prepare_read display_prepare_read;
|
||||
PFN_wl_proxy_marshal proxy_marshal;
|
||||
PFN_wl_proxy_add_listener proxy_add_listener;
|
||||
PFN_wl_proxy_destroy proxy_destroy;
|
||||
PFN_wl_proxy_marshal_constructor proxy_marshal_constructor;
|
||||
PFN_wl_proxy_marshal_constructor_versioned proxy_marshal_constructor_versioned;
|
||||
PFN_wl_proxy_get_user_data proxy_get_user_data;
|
||||
PFN_wl_proxy_set_user_data proxy_set_user_data;
|
||||
} client;
|
||||
|
||||
struct {
|
||||
void* handle;
|
||||
|
||||
|
@ -40,6 +40,14 @@
|
||||
#include <sys/timerfd.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "wayland-client-protocol.h"
|
||||
#include "wayland-xdg-shell-client-protocol.h"
|
||||
#include "wayland-xdg-decoration-client-protocol.h"
|
||||
#include "wayland-viewporter-client-protocol.h"
|
||||
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
|
||||
|
||||
|
||||
static int createTmpfileCloexec(char* tmpname)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user