WIP: Load libwayland-client at runtime

Fixes #1174.
This commit is contained in:
Emmanuel Gil Peyrot 2018-01-05 22:11:03 +01:00
parent 4d3f0fb5df
commit 88e98243ca
4 changed files with 108 additions and 2 deletions

View File

@ -2,6 +2,13 @@ find_package(PkgConfig)
pkg_check_modules(WaylandProtocols QUIET wayland-protocols>=${WaylandProtocols_FIND_VERSION})
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-client
OUTPUT_VARIABLE Wayland_PKGDATADIR
RESULT_VARIABLE _pkgconfig_failed)
if (_pkgconfig_failed)
message(FATAL_ERROR "Missing wayland-client pkgdatadir")
endif()
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols
OUTPUT_VARIABLE WaylandProtocols_PKGDATADIR
RESULT_VARIABLE _pkgconfig_failed)
@ -10,6 +17,7 @@ if (_pkgconfig_failed)
endif()
string(REGEX REPLACE "[\r\n]" "" WaylandProtocols_PKGDATADIR "${WaylandProtocols_PKGDATADIR}")
string(REGEX REPLACE "[\r\n]" "" Wayland_PKGDATADIR "${Wayland_PKGDATADIR}")
find_package_handle_standard_args(WaylandProtocols
FOUND_VAR
@ -22,5 +30,6 @@ find_package_handle_standard_args(WaylandProtocols
)
set(WAYLAND_PROTOCOLS_FOUND ${WaylandProtocols_FOUND})
set(WAYLAND_PKGDATADIR ${Wayland_PKGDATADIR})
set(WAYLAND_PROTOCOLS_PKGDATADIR ${WaylandProtocols_PKGDATADIR})
set(WAYLAND_PROTOCOLS_VERSION ${WaylandProtocols_VERSION})

View File

@ -31,6 +31,10 @@ elseif (_GLFW_WAYLAND)
posix_time.c posix_thread.c xkb_unicode.c
egl_context.c osmesa_context.c)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PKGDATADIR}/wayland.xml"
BASENAME base)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml"

View File

@ -34,7 +34,6 @@
#include <sys/mman.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <wayland-client.h>
static inline int min(int n1, int n2)
@ -951,6 +950,37 @@ static void createKeyTables(void)
int _glfwPlatformInit(void)
{
_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.cancel_read = (PFN_wl_display_cancel_read)
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_cancel_read");
_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.dispatch_pending = (PFN_wl_display_dispatch_pending)
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_dispatch_pending");
_glfw.wl.client.display.flush = (PFN_wl_display_flush)
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_flush");
_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.display.read_events = (PFN_wl_display_read_events)
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_read_events");
_glfw.wl.client.display.roundtrip = (PFN_wl_display_roundtrip)
_glfw_dlsym(_glfw.wl.client.handle, "wl_display_roundtrip");
// TODO:
//_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.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
if (!_glfw.wl.cursor.handle)
{

View File

@ -24,7 +24,6 @@
//
//========================================================================
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
#ifdef HAVE_XKBCOMMON_COMPOSE_H
#include <xkbcommon/xkbcommon-compose.h>
@ -56,6 +55,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
#include "egl_context.h"
#include "osmesa_context.h"
#include "wayland-base-client-protocol.h"
#include "wayland-xdg-shell-client-protocol.h"
#include "wayland-viewporter-client-protocol.h"
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
@ -77,6 +77,42 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
#define _GLFW_PLATFORM_CONTEXT_STATE
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
typedef void (* PFN_wl_display_cancel_read)(struct wl_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_dispatch_pending)(struct wl_display*);
typedef int (* PFN_wl_display_flush)(struct wl_display*);
typedef int (* PFN_wl_display_get_fd)(struct wl_display*);
typedef int (* PFN_wl_display_prepare_read)(struct wl_display*);
typedef int (* PFN_wl_display_read_events)(struct wl_display*);
typedef int (* PFN_wl_display_roundtrip)(struct wl_display*);
#define wl_display_cancel_read _glfw.wl.client.display.cancel_read
#define wl_display_connect _glfw.wl.client.display.connect
#define wl_display_disconnect _glfw.wl.client.display.disconnect
#define wl_display_dispatch_pending _glfw.wl.client.display.dispatch_pending
#define wl_display_flush _glfw.wl.client.display.flush
#define wl_display_get_fd _glfw.wl.client.display.get_fd
#define wl_display_prepare_read _glfw.wl.client.display.prepare_read
#define wl_display_read_events _glfw.wl.client.display.read_events
#define wl_display_roundtrip _glfw.wl.client.display.roundtrip
typedef void (* PFN_wl_proxy_marshal)(struct wl_proxy*, uint32_t, ...);
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_destroy)(struct wl_proxy*);
typedef int (* PFN_wl_proxy_add_listener)(struct wl_proxy*, void(**)(void), void*);
typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*, void*);
typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*);
typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*);
#define wl_proxy_marshal _glfw.wl.client.proxy.marshal
#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_destroy _glfw.wl.client.proxy.destroy
#define wl_proxy_add_listener _glfw.wl.client.proxy.add_listener
#define wl_proxy_set_user_data _glfw.wl.client.proxy.set_user_data
#define wl_proxy_get_user_data _glfw.wl.client.proxy.get_user_data
#define wl_proxy_get_version _glfw.wl.client.proxy.get_version
struct wl_cursor_image {
uint32_t width;
uint32_t height;
@ -297,6 +333,33 @@ typedef struct _GLFWlibraryWayland
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus;
struct {
void* handle;
struct {
PFN_wl_display_cancel_read cancel_read;
PFN_wl_display_connect connect;
PFN_wl_display_disconnect disconnect;
PFN_wl_display_dispatch_pending dispatch_pending;
PFN_wl_display_flush flush;
PFN_wl_display_get_fd get_fd;
PFN_wl_display_prepare_read prepare_read;
PFN_wl_display_read_events read_events;
PFN_wl_display_roundtrip roundtrip;
} display;
struct {
PFN_wl_proxy_marshal marshal;
PFN_wl_proxy_marshal_constructor marshal_constructor;
PFN_wl_proxy_marshal_constructor_versioned marshal_constructor_versioned;
PFN_wl_proxy_destroy destroy;
PFN_wl_proxy_add_listener add_listener;
PFN_wl_proxy_set_user_data set_user_data;
PFN_wl_proxy_get_user_data get_user_data;
PFN_wl_proxy_get_version get_version;
} proxy;
} client;
struct {
void* handle;