From d95bc2dd54599be2ec6e42b9a84ee56823b92c8f Mon Sep 17 00:00:00 2001 From: Colin Kinloch Date: Mon, 21 Mar 2022 19:34:52 +0000 Subject: [PATCH] (Wayland) Dynamically load libdecor at runtime --- Makefile.common | 3 +- gfx/common/wayland/libdecor_sym.h | 76 +++++++++++ gfx/common/wayland_common.c | 184 +++++++++++++++------------ gfx/common/wayland_common.h | 19 ++- gfx/drivers_context/wayland_ctx.c | 26 ++-- gfx/drivers_context/wayland_vk_ctx.c | 23 ++-- input/common/wayland_common.c | 13 +- input/common/wayland_common.h | 16 ++- 8 files changed, 240 insertions(+), 120 deletions(-) create mode 100644 gfx/common/wayland/libdecor_sym.h diff --git a/Makefile.common b/Makefile.common index d421cccbb1..8dabcaa3bb 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1275,8 +1275,7 @@ ifeq ($(HAVE_WAYLAND), 1) LIBS += $(WAYLAND_LIBS) $(WAYLAND_CURSOR_LIBS) ifeq ($(HAVE_LIBDECOR), 1) - DEFINES += -DHAVE_LIBDECOR - LIBS += $(LIBDECOR_LIBS) + DEFINES += -DHAVE_LIBDECOR_H DEF_FLAGS += $(LIBDECOR_CFLAGS) endif diff --git a/gfx/common/wayland/libdecor_sym.h b/gfx/common/wayland/libdecor_sym.h new file mode 100644 index 0000000000..9339cb81ba --- /dev/null +++ b/gfx/common/wayland/libdecor_sym.h @@ -0,0 +1,76 @@ + +#ifndef RA_WAYLAND_MODULE +#define RA_WAYLAND_MODULE(modname) +#endif + +#ifndef RA_WAYLAND_SYM +#define RA_WAYLAND_SYM(rc,fn,params) +#endif + +#ifndef RA_WAYLAND_INTERFACE +#define RA_WAYLAND_INTERFACE(iface) +#endif + +#include + +#ifdef HAVE_LIBDECOR_H +RA_WAYLAND_MODULE(WAYLAND_LIBDECOR) +RA_WAYLAND_SYM(void, libdecor_unref, (struct libdecor *)) +RA_WAYLAND_SYM(struct libdecor *, libdecor_new, (struct wl_display *, struct libdecor_interface *)) +RA_WAYLAND_SYM(int, libdecor_dispatch, (struct libdecor *, int timeout)) +RA_WAYLAND_SYM(struct libdecor_frame *, libdecor_decorate, (struct libdecor *,\ + struct wl_surface *,\ + struct libdecor_frame_interface *,\ + void *)) +RA_WAYLAND_SYM(void, libdecor_frame_unref, (struct libdecor_frame *)) +RA_WAYLAND_SYM(void, libdecor_frame_set_title, (struct libdecor_frame *, const char *)) +RA_WAYLAND_SYM(void, libdecor_frame_set_app_id, (struct libdecor_frame *, const char *)) +RA_WAYLAND_SYM(void, libdecor_frame_set_max_content_size, (struct libdecor_frame *frame,\ + int content_width,\ + int content_height)) +RA_WAYLAND_SYM(void, libdecor_frame_set_min_content_size, (struct libdecor_frame *frame,\ + int content_width,\ + int content_height)) +RA_WAYLAND_SYM(void, libdecor_frame_resize, (struct libdecor_frame *,\ + struct wl_seat *,\ + uint32_t,\ + enum libdecor_resize_edge)) +RA_WAYLAND_SYM(void, libdecor_frame_move, (struct libdecor_frame *,\ + struct wl_seat *,\ + uint32_t)) +RA_WAYLAND_SYM(void, libdecor_frame_commit, (struct libdecor_frame *,\ + struct libdecor_state *,\ + struct libdecor_configuration *)) +RA_WAYLAND_SYM(void, libdecor_frame_set_minimized, (struct libdecor_frame *)) +RA_WAYLAND_SYM(void, libdecor_frame_set_maximized, (struct libdecor_frame *)) +RA_WAYLAND_SYM(void, libdecor_frame_unset_maximized, (struct libdecor_frame *)) +RA_WAYLAND_SYM(void, libdecor_frame_set_fullscreen, (struct libdecor_frame *, struct wl_output *)) +RA_WAYLAND_SYM(void, libdecor_frame_unset_fullscreen, (struct libdecor_frame *)) +RA_WAYLAND_SYM(void, libdecor_frame_set_capabilities, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +RA_WAYLAND_SYM(void, libdecor_frame_unset_capabilities, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +RA_WAYLAND_SYM(bool, libdecor_frame_has_capability, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +RA_WAYLAND_SYM(void, libdecor_frame_set_visibility, (struct libdecor_frame *, bool)) +RA_WAYLAND_SYM(bool, libdecor_frame_is_visible, (struct libdecor_frame *)) +RA_WAYLAND_SYM(bool, libdecor_frame_is_floating, (struct libdecor_frame *)) +RA_WAYLAND_SYM(void, libdecor_frame_set_parent, (struct libdecor_frame *,\ + struct libdecor_frame *)) +RA_WAYLAND_SYM(struct xdg_surface *, libdecor_frame_get_xdg_surface, (struct libdecor_frame *)) +RA_WAYLAND_SYM(struct xdg_toplevel *, libdecor_frame_get_xdg_toplevel, (struct libdecor_frame *)) +RA_WAYLAND_SYM(void, libdecor_frame_map, (struct libdecor_frame *)) +RA_WAYLAND_SYM(struct libdecor_state *, libdecor_state_new, (int, int)) +RA_WAYLAND_SYM(void, libdecor_state_free, (struct libdecor_state *)) +RA_WAYLAND_SYM(bool, libdecor_configuration_get_content_size, (struct libdecor_configuration *,\ + struct libdecor_frame *,\ + int *,\ + int *)) +RA_WAYLAND_SYM(bool, libdecor_configuration_get_window_state, (struct libdecor_configuration *,\ + enum libdecor_window_state *)) +#endif + +#undef RA_WAYLAND_MODULE +#undef RA_WAYLAND_SYM +#undef RA_WAYLAND_INTERFACE + diff --git a/gfx/common/wayland_common.c b/gfx/common/wayland_common.c index db7e52c703..795b5de29f 100644 --- a/gfx/common/wayland_common.c +++ b/gfx/common/wayland_common.c @@ -25,7 +25,7 @@ #define SPLASH_SHM_NAME "retroarch-wayland-vk-splash" -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H #include #endif @@ -71,7 +71,7 @@ void xdg_toplevel_handle_close(void *data, command_event(CMD_EVENT_QUIT, NULL); } -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H void libdecor_frame_handle_configure_common(struct libdecor_frame *frame, struct libdecor_configuration *configuration, gfx_ctx_wayland_data_t *wl) @@ -92,7 +92,7 @@ void libdecor_frame_handle_configure_common(struct libdecor_frame *frame, wl->fullscreen = false; wl->maximized = false; - if (libdecor_configuration_get_window_state( + if (wl->libdecor_configuration_get_window_state( configuration, &window_state)) { wl->fullscreen = (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0; @@ -101,7 +101,7 @@ void libdecor_frame_handle_configure_common(struct libdecor_frame *frame, tiled = (window_state & tiled_states) != 0; } - if (!libdecor_configuration_get_content_size(configuration, frame, + if (!wl->libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { width = wl->floating_width; @@ -115,11 +115,11 @@ void libdecor_frame_handle_configure_common(struct libdecor_frame *frame, wl->height = height; } - state = libdecor_state_new(wl->width, wl->height); - libdecor_frame_commit(frame, state, configuration); - libdecor_state_free(state); + state = wl->libdecor_state_new(wl->width, wl->height); + wl->libdecor_frame_commit(frame, state, configuration); + wl->libdecor_state_free(state); - if (libdecor_frame_is_floating(frame)) { + if (wl->libdecor_frame_is_floating(frame)) { wl->floating_width = width; wl->floating_height = height; } @@ -231,18 +231,23 @@ void gfx_ctx_wl_update_title_common(gfx_ctx_wayland_data_t *wl) video_driver_get_window_title(title, sizeof(title)); -#ifdef HAVE_LIBDECOR - if (wl && title[0]) - libdecor_frame_set_title(wl->libdecor_frame, title); -#else - if (wl && title[0]) +#ifdef HAVE_LIBDECOR_H + if (wl->libdecor) { - if (wl->deco) - zxdg_toplevel_decoration_v1_set_mode(wl->deco, - ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - xdg_toplevel_set_title(wl->xdg_toplevel, title); + if (wl && title[0]) + wl->libdecor_frame_set_title(wl->libdecor_frame, title); } + else #endif + { + if (wl && title[0]) + { + if (wl->deco) + zxdg_toplevel_decoration_v1_set_mode(wl->deco, + ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + xdg_toplevel_set_title(wl->xdg_toplevel, title); + } + } } bool gfx_ctx_wl_get_metrics_common(gfx_ctx_wayland_data_t *wl, @@ -279,7 +284,7 @@ bool gfx_ctx_wl_get_metrics_common(gfx_ctx_wayland_data_t *wl, } bool gfx_ctx_wl_init_common(void *video_driver, - toplevel_listener_t **toplevel_listener, gfx_ctx_wayland_data_t **wwl) + const toplevel_listener_t *toplevel_listener, gfx_ctx_wayland_data_t **wwl) { int i; *wwl = calloc(1, sizeof(gfx_ctx_wayland_data_t)); @@ -288,6 +293,18 @@ bool gfx_ctx_wl_init_common(void *video_driver, if (!wl) return false; + +#ifdef HAVE_LIBDECOR_H +#ifdef HAVE_DYNAMIC + wl->libdecor = dylib_load("libdecor-0.so"); + if (wl->libdecor) + { +#define RA_WAYLAND_SYM(rc,fn,params) wl->fn = (rc (*) params)dylib_proc(wl->libdecor, #fn); +#include "wayland/libdecor_sym.h" + } +#endif +#endif + wl_list_init(&wl->all_outputs); frontend_driver_destroy_signal_handler_state(); @@ -343,55 +360,60 @@ bool gfx_ctx_wl_init_common(void *video_driver, wl_surface_set_buffer_scale(wl->surface, wl->buffer_scale); wl_surface_add_listener(wl->surface, &wl_surface_listener, wl); -#ifdef HAVE_LIBDECOR - wl->libdecor_context = libdecor_new(wl->input.dpy, &libdecor_interface); - if (wl->libdecor_context) +#ifdef HAVE_LIBDECOR_H + if (wl->libdecor) { - wl->libdecor_frame = libdecor_decorate(wl->libdecor_context, wl->surface, toplevel_listener, wl); - if (!wl->libdecor_frame) + wl->libdecor_context = wl->libdecor_new(wl->input.dpy, &libdecor_interface); + if (wl->libdecor_context) { - RARCH_ERR("[Wayland]: Failed to crate libdecor frame\n"); - goto error; + wl->libdecor_frame = wl->libdecor_decorate(wl->libdecor_context, wl->surface, &toplevel_listener->libdecor_frame_interface, wl); + if (!wl->libdecor_frame) + { + RARCH_ERR("[Wayland]: Failed to crate libdecor frame\n"); + goto error; + } + + wl->libdecor_frame_set_app_id(wl->libdecor_frame, "retroarch"); + wl->libdecor_frame_set_title(wl->libdecor_frame, "RetroArch"); + wl->libdecor_frame_map(wl->libdecor_frame); } - libdecor_frame_set_app_id(wl->libdecor_frame, "retroarch"); - libdecor_frame_set_title(wl->libdecor_frame, "RetroArch"); - libdecor_frame_map(wl->libdecor_frame); - } + /* Waiting for libdecor to be configured before starting to draw */ + wl_surface_commit(wl->surface); + wl->configured = true; - /* Waiting for libdecor to be configured before starting to draw */ - wl_surface_commit(wl->surface); - wl->configured = true; - - while (wl->configured) - { - if (libdecor_dispatch(wl->libdecor_context, 0) < 0) + while (wl->configured) { - RARCH_ERR("[Wayland]: libdecor failed to dispatch\n"); - goto error; + if (wl->libdecor_dispatch(wl->libdecor_context, 0) < 0) + { + RARCH_ERR("[Wayland]: libdecor failed to dispatch\n"); + goto error; + } } } -#else - wl->xdg_surface = xdg_wm_base_get_xdg_surface(wl->xdg_shell, wl->surface); - xdg_surface_add_listener(wl->xdg_surface, &xdg_surface_listener, wl); - - wl->xdg_toplevel = xdg_surface_get_toplevel(wl->xdg_surface); - xdg_toplevel_add_listener(wl->xdg_toplevel, toplevel_listener, wl); - - xdg_toplevel_set_app_id(wl->xdg_toplevel, "retroarch"); - xdg_toplevel_set_title(wl->xdg_toplevel, "RetroArch"); - - if (wl->deco_manager) - wl->deco = zxdg_decoration_manager_v1_get_toplevel_decoration( - wl->deco_manager, wl->xdg_toplevel); - - /* Waiting for xdg_toplevel to be configured before starting to draw */ - wl_surface_commit(wl->surface); - wl->configured = true; - - while (wl->configured) - wl_display_dispatch(wl->input.dpy); + else #endif + { + wl->xdg_surface = xdg_wm_base_get_xdg_surface(wl->xdg_shell, wl->surface); + xdg_surface_add_listener(wl->xdg_surface, &xdg_surface_listener, wl); + + wl->xdg_toplevel = xdg_surface_get_toplevel(wl->xdg_surface); + xdg_toplevel_add_listener(wl->xdg_toplevel, &toplevel_listener->xdg_toplevel_listener, wl); + + xdg_toplevel_set_app_id(wl->xdg_toplevel, "retroarch"); + xdg_toplevel_set_title(wl->xdg_toplevel, "RetroArch"); + + if (wl->deco_manager) + wl->deco = zxdg_decoration_manager_v1_get_toplevel_decoration( + wl->deco_manager, wl->xdg_toplevel); + + /* Waiting for xdg_toplevel to be configured before starting to draw */ + wl_surface_commit(wl->surface); + wl->configured = true; + + while (wl->configured) + wl_display_dispatch(wl->input.dpy); + } wl_display_roundtrip(wl->input.dpy); xdg_wm_base_add_listener(wl->xdg_shell, &xdg_shell_listener, NULL); @@ -443,10 +465,13 @@ bool gfx_ctx_wl_set_video_mode_common_size(gfx_ctx_wayland_data_t *wl, wl_surface_set_buffer_scale(wl->surface, wl->buffer_scale); -#ifdef HAVE_LIBDECOR - struct libdecor_state *state = libdecor_state_new(width, height); - libdecor_frame_commit(wl->libdecor_frame, state, NULL); - libdecor_state_free(state); +#ifdef HAVE_LIBDECOR_H + if (wl->libdecor) + { + struct libdecor_state *state = wl->libdecor_state_new(width, height); + wl->libdecor_frame_commit(wl->libdecor_frame, state, NULL); + wl->libdecor_state_free(state); + } #endif return true; @@ -486,11 +511,14 @@ bool gfx_ctx_wl_set_video_mode_common_fullscreen(gfx_ctx_wayland_data_t *wl, if (output == NULL) RARCH_LOG("[Wayland] Failed to specify monitor for fullscreen, letting compositor decide\n"); -#ifdef HAVE_LIBDECOR - libdecor_frame_set_fullscreen(wl->libdecor_frame, output); -#else - xdg_toplevel_set_fullscreen(wl->xdg_toplevel, output); +#ifdef HAVE_LIBDECOR_H + if (wl->libdecor) + wl->libdecor_frame_set_fullscreen(wl->libdecor_frame, output); + else #endif + { + xdg_toplevel_set_fullscreen(wl->xdg_toplevel, output); + } } flush_wayland_fd(&wl->input); @@ -589,10 +617,10 @@ static void shm_buffer_handle_release(void *data, static void xdg_surface_handle_configure(void *data, struct xdg_surface *surface, uint32_t serial) { - xdg_surface_ack_configure(surface, serial); + xdg_surface_ack_configure(surface, serial); } -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H static void libdecor_handle_error(struct libdecor *context, enum libdecor_error error, const char *message) { @@ -610,16 +638,16 @@ int create_shm_file(off_t size) fd = memfd_create(SPLASH_SHM_NAME, MFD_CLOEXEC | MFD_ALLOW_SEALING); if (fd >= 0) { - fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK); + fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK); - do { - ret = posix_fallocate(fd, 0, size); - } while (ret == EINTR); - if (ret != 0) { - close(fd); - errno = ret; - fd = -1; - } + do { + ret = posix_fallocate(fd, 0, size); + } while (ret == EINTR); + if (ret != 0) { + close(fd); + errno = ret; + fd = -1; + } } if (fd < 0) #endif @@ -747,7 +775,7 @@ const struct wl_buffer_listener shm_buffer_listener = { shm_buffer_handle_release, }; -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H const struct libdecor_interface libdecor_interface = { .error = libdecor_handle_error, }; diff --git a/gfx/common/wayland_common.h b/gfx/common/wayland_common.h index e7e44f95bc..5a97d227ac 100644 --- a/gfx/common/wayland_common.h +++ b/gfx/common/wayland_common.h @@ -15,19 +15,18 @@ #pragma once -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H #include #endif #include "../../input/common/wayland_common.h" - - -#ifdef HAVE_LIBDECOR -typedef struct libdecor_frame_interface toplevel_listener_t; -#else -typedef struct xdg_toplevel_listener toplevel_listener_t; +typedef struct toplevel_listener { +#ifdef HAVE_LIBDECOR_H + struct libdecor_frame_interface libdecor_frame_interface; #endif + struct xdg_toplevel_listener xdg_toplevel_listener; +} toplevel_listener_t; typedef struct shm_buffer { struct wl_buffer *wl_buffer; @@ -41,7 +40,7 @@ void xdg_toplevel_handle_configure_common(gfx_ctx_wayland_data_t *wl, void *topl void xdg_toplevel_handle_close(void *data, struct xdg_toplevel *xdg_toplevel); -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H void libdecor_frame_handle_configure_common(struct libdecor_frame *frame, struct libdecor_configuration *configuration, gfx_ctx_wayland_data_t *wl); @@ -63,7 +62,7 @@ bool gfx_ctx_wl_get_metrics_common(gfx_ctx_wayland_data_t *wl, enum display_metric_types type, float *value); bool gfx_ctx_wl_init_common(void *video_driver, - toplevel_listener_t **toplevel_listener, + const toplevel_listener_t *toplevel_listener, gfx_ctx_wayland_data_t **wl); bool gfx_ctx_wl_set_video_mode_common_size(gfx_ctx_wayland_data_t *wl, @@ -97,7 +96,7 @@ void shm_buffer_paint_checkerboard(shm_buffer_t *buffer, bool draw_splash_screen(gfx_ctx_wayland_data_t *wl); -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H extern const struct libdecor_interface libdecor_interface; #endif diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 8dab9e7776..8af43658f8 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -134,7 +134,7 @@ static bool gfx_ctx_wl_get_metrics(void *data, return gfx_ctx_wl_get_metrics_common(wl, type, value); } -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H static void libdecor_frame_handle_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *data) @@ -154,18 +154,24 @@ libdecor_frame_handle_configure(struct libdecor_frame *frame, wl->configured = false; } +#endif static const toplevel_listener_t toplevel_listener = { - libdecor_frame_handle_configure, - libdecor_frame_handle_close, - libdecor_frame_handle_commit, -}; -#else -static const toplevel_listener_t toplevel_listener = { - xdg_toplevel_handle_configure, - xdg_toplevel_handle_close, -}; +#ifdef HAVE_LIBDECOR_H + .libdecor_frame_interface = { + libdecor_frame_handle_configure, + libdecor_frame_handle_close, + libdecor_frame_handle_commit, + }, #endif + .xdg_toplevel_listener = { + xdg_toplevel_handle_configure, + xdg_toplevel_handle_close, + }, +}; + +static const toplevel_listener_t xdg_toplevel_listener = { +}; #ifdef HAVE_EGL #define WL_EGL_ATTRIBS_BASE \ diff --git a/gfx/drivers_context/wayland_vk_ctx.c b/gfx/drivers_context/wayland_vk_ctx.c index 14e870aa96..15c737f03f 100644 --- a/gfx/drivers_context/wayland_vk_ctx.c +++ b/gfx/drivers_context/wayland_vk_ctx.c @@ -125,7 +125,7 @@ static bool gfx_ctx_wl_get_metrics(void *data, return gfx_ctx_wl_get_metrics_common(wl, type, value); } -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H static void libdecor_frame_handle_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *data) @@ -135,18 +135,21 @@ libdecor_frame_handle_configure(struct libdecor_frame *frame, wl->configured = false; } +#endif static const toplevel_listener_t toplevel_listener = { - libdecor_frame_handle_configure, - libdecor_frame_handle_close, - libdecor_frame_handle_commit, -}; -#else -static const toplevel_listener_t toplevel_listener = { - xdg_toplevel_handle_configure, - xdg_toplevel_handle_close, -}; +#ifdef HAVE_LIBDECOR_H + .libdecor_frame_interface = { + libdecor_frame_handle_configure, + libdecor_frame_handle_close, + libdecor_frame_handle_commit, + }, #endif + .xdg_toplevel_listener = { + xdg_toplevel_handle_configure, + xdg_toplevel_handle_close, + }, +}; static void *gfx_ctx_wl_init(void *video_driver) { diff --git a/input/common/wayland_common.c b/input/common/wayland_common.c index 55cfe59a1e..762d925e84 100644 --- a/input/common/wayland_common.c +++ b/input/common/wayland_common.c @@ -29,7 +29,7 @@ #include -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H #include #endif @@ -244,11 +244,14 @@ static void pointer_handle_button(void *data, if (BIT_GET(wl->input.key_state, KEY_LEFTALT)) { -#ifdef HAVE_LIBDECOR - libdecor_frame_move(wl->libdecor_frame, wl->seat, serial); -#else - xdg_toplevel_move(wl->xdg_toplevel, wl->seat, serial); +#ifdef HAVE_LIBDECOR_H + if (wl->libdecor) + wl->libdecor_frame_move(wl->libdecor_frame, wl->seat, serial); + else #endif + { + xdg_toplevel_move(wl->xdg_toplevel, wl->seat, serial); + } } break; case BTN_RIGHT: diff --git a/input/common/wayland_common.h b/input/common/wayland_common.h index 54c4f558d3..45c5b322bf 100644 --- a/input/common/wayland_common.h +++ b/input/common/wayland_common.h @@ -13,8 +13,7 @@ * If not, see . */ -#ifndef WAYLAND_INPUT_COMMON_H__ -#define WAYLAND_INPUT_COMMON_H__ +#pragma once #include #include @@ -52,6 +51,10 @@ (const char *) pos < ((const char *) (array)->data + (array)->size); \ (pos)++) +#ifdef HAVE_LIBDECOR_H +#include +#endif + typedef struct { int16_t x; @@ -141,9 +144,14 @@ typedef struct gfx_ctx_wayland_data struct wl_data_device_manager *data_device_manager; struct wl_data_device *data_device; data_offer_ctx *current_drag_offer; -#ifdef HAVE_LIBDECOR +#ifdef HAVE_LIBDECOR_H struct libdecor *libdecor_context; struct libdecor_frame *libdecor_frame; +#ifdef HAVE_DYNAMIC + struct dylib_t *libdecor; +#define RA_WAYLAND_SYM(rc,fn,params) rc (*fn) params; +#include "../../gfx/common/wayland/libdecor_sym.h" +#endif #endif struct zxdg_decoration_manager_v1 *deco_manager; struct zxdg_toplevel_decoration_v1 *deco; @@ -220,5 +228,3 @@ extern const struct wl_buffer_listener shm_buffer_listener; extern const struct wl_data_device_listener data_device_listener; extern const struct wl_data_offer_listener data_offer_listener; - -#endif