aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Versace <chad.versace@intel.com>2015-03-27 11:31:09 -0700
committerChad Versace <chad.versace@intel.com>2015-03-27 11:31:13 -0700
commit8b5766929bfc717acc4ef6feb22126e694ea5474 (patch)
tree72da74d232a5d9de1dd9d7a482f43fa9ed521d7d
parent3b9b8f5f6d1b99af43e95ec0868404e552a85b73 (diff)
parentbd32a55d927766205de97c857e317425a9124281 (diff)
downloadwaffle-8b5766929bfc717acc4ef6feb22126e694ea5474.tar.gz
Merge branch 'evelikov/no-libwayland'
* evelikov/no-libwayland: wayland: resolve wayland-client symbols at runtime (via libdl) wayland: do not link against wayland-egl wayland: fetch wl_egl_* function pointers at wayland_platform_create wayland: fix indentation
-rw-r--r--cmake/Modules/WafflePrintConfigurationSummary.cmake2
-rw-r--r--src/waffle/CMakeLists.txt7
-rw-r--r--src/waffle/wayland/wayland_display.c2
-rw-r--r--src/waffle/wayland/wayland_platform.c43
-rw-r--r--src/waffle/wayland/wayland_platform.h18
-rw-r--r--src/waffle/wayland/wayland_window.c47
-rw-r--r--src/waffle/wayland/wayland_wrapper.c115
-rw-r--r--src/waffle/wayland/wayland_wrapper.h94
8 files changed, 301 insertions, 27 deletions
diff --git a/cmake/Modules/WafflePrintConfigurationSummary.cmake b/cmake/Modules/WafflePrintConfigurationSummary.cmake
index 1f38db5..1199ea3 100644
--- a/cmake/Modules/WafflePrintConfigurationSummary.cmake
+++ b/cmake/Modules/WafflePrintConfigurationSummary.cmake
@@ -60,9 +60,7 @@ if(waffle_has_glx)
endif()
if(waffle_has_wayland)
message(" wayland-client_INCLUDE_DIRS: ${wayland-client_INCLUDE_DIRS}")
- message(" wayland-client_LDFLAGS: ${wayland-client_LDFLAGS}")
message(" wayland-egl_INCLUDE_DIRS: ${wayland-egl_INCLUDE_DIRS}")
- message(" wayland-egl_LDFLAGS: ${wayland-egl_LDFLAGS}")
endif()
if(waffle_has_x11)
message(" x11-xcb_INCLUDE_DIRS: ${x11-xcb_INCLUDE_DIRS}")
diff --git a/src/waffle/CMakeLists.txt b/src/waffle/CMakeLists.txt
index ac9b415..4f1d5c7 100644
--- a/src/waffle/CMakeLists.txt
+++ b/src/waffle/CMakeLists.txt
@@ -41,12 +41,6 @@ list(APPEND waffle_libdeps
)
if(waffle_on_linux)
- if(waffle_has_wayland)
- list(APPEND waffle_libdeps
- ${wayland-client_LDFLAGS}
- ${wayland-egl_LDFLAGS}
- )
- endif()
if(waffle_has_x11)
list(APPEND waffle_libdeps
${x11-xcb_LDFLAGS}
@@ -138,6 +132,7 @@ if(waffle_has_wayland)
wayland/wayland_display.c
wayland/wayland_platform.c
wayland/wayland_window.c
+ wayland/wayland_wrapper.c
)
endif()
diff --git a/src/waffle/wayland/wayland_display.c b/src/waffle/wayland/wayland_display.c
index e7c6e94..e2d59a8 100644
--- a/src/waffle/wayland/wayland_display.c
+++ b/src/waffle/wayland/wayland_display.c
@@ -28,6 +28,8 @@
#include <stdlib.h>
#include <string.h>
+// The wrapper must be included before wayland-client.h
+#include "wayland_wrapper.h"
#include <wayland-client.h>
#undef container_of
diff --git a/src/waffle/wayland/wayland_platform.c b/src/waffle/wayland/wayland_platform.c
index 63cfdc2..2746ca1 100644
--- a/src/waffle/wayland/wayland_platform.c
+++ b/src/waffle/wayland/wayland_platform.c
@@ -27,6 +27,7 @@
#define _POSIX_C_SOURCE 200112 // glib feature macro for unsetenv()
#include <stdlib.h>
+#include <dlfcn.h>
#include "waffle_wayland.h"
@@ -42,6 +43,9 @@
#include "wayland_display.h"
#include "wayland_platform.h"
#include "wayland_window.h"
+#include "wayland_wrapper.h"
+
+static const char *libwl_egl_filename = "libwayland-egl.so.1";
static const struct wcore_platform_vtbl wayland_platform_vtbl;
@@ -50,6 +54,7 @@ wayland_platform_destroy(struct wcore_platform *wc_self)
{
struct wayland_platform *self = wayland_platform(wegl_platform(wc_self));
bool ok = true;
+ int error;
if (!self)
return true;
@@ -59,6 +64,17 @@ wayland_platform_destroy(struct wcore_platform *wc_self)
if (self->linux)
ok &= linux_platform_destroy(self->linux);
+ if (self->dl_wl_egl) {
+ error = dlclose(self->dl_wl_egl);
+ if (error) {
+ ok &= false;
+ wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+ "dlclose(\"%s\") failed: %s",
+ libwl_egl_filename, dlerror());
+ }
+ }
+
+ ok &= wayland_wrapper_teardown();
ok &= wegl_platform_teardown(&self->wegl);
free(self);
return ok;
@@ -78,6 +94,33 @@ wayland_platform_create(void)
if (!ok)
goto error;
+ ok = wayland_wrapper_init();
+ if (!ok)
+ goto error;
+
+ self->dl_wl_egl = dlopen(libwl_egl_filename, RTLD_LAZY | RTLD_LOCAL);
+ if (!self->dl_wl_egl) {
+ wcore_errorf(WAFFLE_ERROR_FATAL,
+ "dlopen(\"%s\") failed: %s",
+ libwl_egl_filename, dlerror());
+ goto error;
+ }
+
+#define RETRIEVE_WL_EGL_SYMBOL(function) \
+ self->function = dlsym(self->dl_wl_egl, #function); \
+ if (!self->function) { \
+ wcore_errorf(WAFFLE_ERROR_FATAL, \
+ "dlsym(\"%s\", \"" #function "\") failed: %s", \
+ libwl_egl_filename, dlerror()); \
+ goto error; \
+ }
+
+ RETRIEVE_WL_EGL_SYMBOL(wl_egl_window_create);
+ RETRIEVE_WL_EGL_SYMBOL(wl_egl_window_destroy);
+ RETRIEVE_WL_EGL_SYMBOL(wl_egl_window_resize);
+
+#undef RETRIEVE_WL_EGL_SYMBOL
+
self->linux = linux_platform_create();
if (!self->linux)
goto error;
diff --git a/src/waffle/wayland/wayland_platform.h b/src/waffle/wayland/wayland_platform.h
index c4e870f..574a306 100644
--- a/src/waffle/wayland/wayland_platform.h
+++ b/src/waffle/wayland/wayland_platform.h
@@ -36,10 +36,28 @@
#include "wcore_util.h"
struct linux_platform;
+struct wl_egl_window;
+struct wl_surface;
struct wayland_platform {
struct wegl_platform wegl;
struct linux_platform *linux;
+
+
+ void *dl_wl_egl;
+
+ struct wl_egl_window *
+ (*wl_egl_window_create)(struct wl_surface *surface,
+ int width, int height);
+
+ void
+ (*wl_egl_window_destroy)(struct wl_egl_window *egl_window);
+
+ void
+ (*wl_egl_window_resize)(struct wl_egl_window *egl_window,
+ int width, int height,
+ int dx, int dy);
+
};
DEFINE_CONTAINER_CAST_FUNC(wayland_platform,
diff --git a/src/waffle/wayland/wayland_window.c b/src/waffle/wayland/wayland_window.c
index 4ac9c16..b5eeaa3 100644
--- a/src/waffle/wayland/wayland_window.c
+++ b/src/waffle/wayland/wayland_window.c
@@ -28,6 +28,8 @@
#include <stdlib.h>
#include <string.h>
+// The wrapper must be included before wayland-(client|egl).h
+#include "wayland_wrapper.h"
#include <wayland-egl.h>
#undef container_of
@@ -39,11 +41,14 @@
#include "wegl_config.h"
#include "wayland_display.h"
+#include "wayland_platform.h"
#include "wayland_window.h"
bool
wayland_window_destroy(struct wcore_window *wc_self)
{
+ struct wcore_platform *wc_plat = wc_self->display->platform;
+ struct wayland_platform *plat = wayland_platform(wegl_platform(wc_plat));
struct wayland_window *self = wayland_window(wc_self);
bool ok = true;
@@ -53,7 +58,7 @@ wayland_window_destroy(struct wcore_window *wc_self)
ok &= wegl_window_teardown(&self->wegl);
if (self->wl_window)
- wl_egl_window_destroy(self->wl_window);
+ plat->wl_egl_window_destroy(self->wl_window);
if (self->wl_shell_surface)
wl_shell_surface_destroy(self->wl_shell_surface);
@@ -102,6 +107,7 @@ wayland_window_create(struct wcore_platform *wc_plat,
const intptr_t attrib_list[])
{
struct wayland_window *self;
+ struct wayland_platform *plat = wayland_platform(wegl_platform(wc_plat));
struct wayland_display *dpy = wayland_display(wc_config->display);
bool ok = true;
@@ -142,7 +148,8 @@ wayland_window_create(struct wcore_platform *wc_plat,
&shell_surface_listener,
NULL);
- self->wl_window = wl_egl_window_create(self->wl_surface, width, height);
+ self->wl_window = plat->wl_egl_window_create(self->wl_surface,
+ width, height);
if (!self->wl_window) {
wcore_errorf(WAFFLE_ERROR_UNKNOWN, "wl_egl_window_create failed");
goto error;
@@ -184,35 +191,37 @@ wayland_window_show(struct wcore_window *wc_self)
bool
wayland_window_swap_buffers(struct wcore_window *wc_self)
{
- struct wayland_display *dpy = wayland_display(wc_self->display);
- bool ok;
+ struct wayland_display *dpy = wayland_display(wc_self->display);
+ bool ok;
- ok = wegl_window_swap_buffers(wc_self);
- if (!ok)
- return false;
+ ok = wegl_window_swap_buffers(wc_self);
+ if (!ok)
+ return false;
- ok = wayland_display_sync(dpy);
- if (!ok)
- return false;
+ ok = wayland_display_sync(dpy);
+ if (!ok)
+ return false;
- return true;
+ return true;
}
bool
wayland_window_resize(struct wcore_window *wc_self,
int32_t width, int32_t height)
{
- struct wayland_window *self = wayland_window(wc_self);
- struct wayland_display *dpy = wayland_display(self->wegl.wcore.display);
+ struct wayland_window *self = wayland_window(wc_self);
+ struct wcore_platform *wc_plat = wc_self->display->platform;
+ struct wayland_platform *plat = wayland_platform(wegl_platform(wc_plat));
+ struct wayland_display *dpy = wayland_display(self->wegl.wcore.display);
- wl_egl_window_resize(wayland_window(wc_self)->wl_window,
- width, height, 0, 0);
+ plat->wl_egl_window_resize(wayland_window(wc_self)->wl_window,
+ width, height, 0, 0);
- if (!wayland_display_sync(dpy))
- return false;
+ if (!wayland_display_sync(dpy))
+ return false;
- // FIXME: How to detect if the resize failed?
- return true;
+ // FIXME: How to detect if the resize failed?
+ return true;
}
union waffle_native_window*
diff --git a/src/waffle/wayland/wayland_wrapper.c b/src/waffle/wayland/wayland_wrapper.c
new file mode 100644
index 0000000..6ffd5a9
--- /dev/null
+++ b/src/waffle/wayland/wayland_wrapper.c
@@ -0,0 +1,115 @@
+// Copyright 2015 Emil Velikov
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/// @file
+/// @brief Wrappers for Wayland-client functions
+///
+/// Many of the wayland functions are defined as static inline within the
+/// public headers. In order to avoid the static(link-time) dependency, we
+/// provide the required symbols with this file.
+///
+/// This is achieved by declaring wrapper functions, around which we define the
+/// needed (base) wayland ones. After that we include the public header, at
+/// which point the pre-processor/compiler will use our defines.
+///
+/// Each wrapper is initialised via dlsym to retrieve the relevant symbol from
+/// the library libwayland-client.so.0
+
+
+#include <stdbool.h>
+#include <dlfcn.h>
+
+#include "wcore_error.h"
+
+#include "wayland_wrapper.h"
+
+// dlopen handle for libwayland-client.so.0
+static void *dl_wl_client;
+
+static const char *libwl_client_filename = "libwayland-client.so.0";
+
+bool
+wayland_wrapper_teardown(void)
+{
+ bool ok = true;
+ int error;
+
+ if (dl_wl_client) {
+ error = dlclose(dl_wl_client);
+ if (error) {
+ ok &= false;
+ wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+ "dlclose(\"%s\") failed: %s",
+ libwl_client_filename, dlerror());
+ }
+ }
+
+ return ok;
+}
+
+bool
+wayland_wrapper_init(void)
+{
+ bool ok = true;
+
+ dl_wl_client = dlopen(libwl_client_filename, RTLD_LAZY | RTLD_LOCAL);
+ if (!dl_wl_client) {
+ wcore_errorf(WAFFLE_ERROR_FATAL,
+ "dlopen(\"%s\") failed: %s",
+ libwl_client_filename, dlerror());
+ ok = false;
+ goto error;
+ }
+
+#define RETRIEVE_WL_CLIENT_SYMBOL(S) \
+ wfl_##S = (__typeof__(wfl_##S))dlsym(dl_wl_client, #S); \
+ if (!wfl_##S) { \
+ wcore_errorf(WAFFLE_ERROR_FATAL, \
+ "dlsym(\"%s\", \"" #S "\") failed: %s", \
+ libwl_client_filename, dlerror()); \
+ ok = false; \
+ goto error; \
+ }
+
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_compositor_interface);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_registry_interface);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_shell_interface);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_shell_surface_interface);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_surface_interface);
+
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_display_connect);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_display_disconnect);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_display_roundtrip);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_proxy_destroy);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_proxy_add_listener);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_proxy_marshal);
+ RETRIEVE_WL_CLIENT_SYMBOL(wl_proxy_marshal_constructor);
+#undef RETRIEVE_WL_CLIENT_SYMBOL
+
+error:
+ // On failure the caller of wayland_wrapper_init will trigger it's own
+ // destruction which will execute wayland_wrapper_teardown.
+ return ok;
+}
diff --git a/src/waffle/wayland/wayland_wrapper.h b/src/waffle/wayland/wayland_wrapper.h
new file mode 100644
index 0000000..40a581a
--- /dev/null
+++ b/src/waffle/wayland/wayland_wrapper.h
@@ -0,0 +1,94 @@
+// Copyright 2015 Emil Velikov
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <stdbool.h>
+#include "wayland-util.h"
+
+bool
+wayland_wrapper_init(void);
+
+bool
+wayland_wrapper_teardown(void);
+
+
+// Data symbols
+const struct wl_interface *wfl_wl_compositor_interface;
+const struct wl_interface *wfl_wl_registry_interface;
+const struct wl_interface *wfl_wl_shell_interface;
+const struct wl_interface *wfl_wl_shell_surface_interface;
+const struct wl_interface *wfl_wl_surface_interface;
+
+
+// Forward declaration of the structs required by the functions
+struct wl_proxy;
+struct wl_display;
+
+
+// Functions
+struct wl_display *
+(*wfl_wl_display_connect)(const char *name);
+
+void
+(*wfl_wl_display_disconnect)(struct wl_display *display);
+
+int
+(*wfl_wl_display_roundtrip)(struct wl_display *display);
+
+
+void
+(*wfl_wl_proxy_destroy)(struct wl_proxy *proxy);
+
+int
+(*wfl_wl_proxy_add_listener)(struct wl_proxy *proxy,
+ void (**implementation)(void), void *data);
+
+void
+(*wfl_wl_proxy_marshal)(struct wl_proxy *p, uint32_t opcode, ...);
+
+struct wl_proxy *
+(*wfl_wl_proxy_marshal_constructor)(struct wl_proxy *proxy,
+ uint32_t opcode,
+ const struct wl_interface *interface,
+ ...);
+
+#ifdef _WAYLAND_CLIENT_H
+#error Do not include wayland-client.h ahead of wayland_wrapper.h
+#endif
+
+#define wl_compositor_interface (*wfl_wl_compositor_interface)
+#define wl_registry_interface (*wfl_wl_registry_interface)
+#define wl_shell_interface (*wfl_wl_shell_interface)
+#define wl_shell_surface_interface (*wfl_wl_shell_surface_interface)
+#define wl_surface_interface (*wfl_wl_surface_interface)
+
+#define wl_display_connect (*wfl_wl_display_connect)
+#define wl_display_disconnect (*wfl_wl_display_disconnect)
+#define wl_display_roundtrip (*wfl_wl_display_roundtrip)
+#define wl_proxy_destroy (*wfl_wl_proxy_destroy)
+#define wl_proxy_add_listener (*wfl_wl_proxy_add_listener)
+#define wl_proxy_marshal (*wfl_wl_proxy_marshal)
+#define wl_proxy_marshal_constructor (*wfl_wl_proxy_marshal_constructor)