From 47746ff30e6fa5ef41cd6dbe1bb7caa0731b048d Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Tue, 24 Mar 2026 17:38:21 -0700 Subject: [PATCH] dynamically load wayland and its dependencies, fix warnings --- include/Mw/LowLevel/Wayland.h | 275 ++++++++++++++++++++++++++++++++-- pl/rules.pl | 5 +- pl/utils.pl | 29 ++++ src/backend/wayland.c | 192 +++++++++++++++++------- src/widget/opengl.c | 95 +++++++++++- 5 files changed, 522 insertions(+), 74 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 2a16f50..a6f2254 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -7,22 +7,279 @@ #ifndef __MW_LOWLEVEL_WAYLAND_H__ #define __MW_LOWLEVEL_WAYLAND_H__ -#include "Mw/BaseTypes.h" #include #include #include +#include -#include - -#include #include #include #include MWDECL int MwLLWaylandCallInit(void); +#define CSD_BORDER_FRAME_LEFT 5 +#define CSD_BORDER_FRAME_RIGHT 5 +#define CSD_BORDER_FRAME_TOP 24 +#define CSD_BORDER_FRAME_BOTTOM 5 + +struct _MwLLWayland; + +#include + +#if WAYLAND_LOAD_OPENGL +#include +#include +#endif + +typedef struct wayland_call_table { + void* lib; + void* xkb_lib; + void* cairo_lib; +#if WAYLAND_LOAD_OPENGL +#endif + + int (*wl_display_dispatch_pending)(struct wl_display* display); + void (*wl_display_disconnect)(struct wl_display* display); + void (*wl_display_cancel_read)(struct wl_display* display); + int (*wl_display_prepare_read)(struct wl_display* display); + int (*wl_display_read_events)(struct wl_display* display); + int (*wl_display_flush)(struct wl_display* display); + int (*wl_display_get_fd)(struct wl_display* display); + int (*wl_display_roundtrip)(struct wl_display* display); + int (*wl_proxy_add_listener)(struct wl_proxy* proxy, void (**implementation)(void), void* data); + void (*wl_proxy_destroy)(struct wl_proxy* proxy); + void (*wl_log_set_handler_client)(wl_log_func_t handler); + struct wl_proxy* (*wl_proxy_marshal_flags)(struct wl_proxy* proxy, uint32_t opcode, + const struct wl_interface* interface, + uint32_t version, + uint32_t flags, ...); + struct wl_display* (*wl_display_connect)(const char* name); + uint32_t (*wl_proxy_get_version)(struct wl_proxy* proxy); + + struct xkb_context* (*xkb_context_new)(enum xkb_context_flags flags); + void (*xkb_context_unref)(struct xkb_context* context); + struct xkb_state* (*xkb_state_new)(struct xkb_keymap* keymap); + void (*xkb_state_unref)(struct xkb_state* state); + struct xkb_keymap* (*xkb_keymap_new_from_string)(struct xkb_context* context, const char* string, enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags); + xkb_level_index_t (*xkb_keymap_num_levels_for_key)(struct xkb_keymap* keymap, xkb_keycode_t key, xkb_layout_index_t layout); + int (*xkb_keymap_key_get_syms_by_level)(struct xkb_keymap* keymap, xkb_keycode_t key, xkb_layout_index_t layout, xkb_level_index_t level, const xkb_keysym_t** syms_out); + xkb_layout_index_t (*xkb_state_key_get_layout)(struct xkb_state* state, xkb_keycode_t key); + void (*xkb_keymap_unref)(struct xkb_keymap* keymap); + + void (*cairo_set_line_width)(cairo_t* cr, + double width); + void (*cairo_scale)(cairo_t* cr, + double sx, + double sy); + cairo_t* (*cairo_create)(cairo_surface_t* target); + void (*cairo_move_to)(cairo_t* cr, + double x, + double y); + + void (*cairo_rectangle)(cairo_t* cr, + double x, + double y, + double width, + double height); + void (*cairo_new_path)(cairo_t* cr); + void (*cairo_set_line_cap)(cairo_t* cr, + cairo_line_cap_t line_cap); + void (*cairo_set_source_rgba)(cairo_t* cr, + double red, + double green, + double blue, + double alpha); + void (*cairo_set_source_rgb)(cairo_t* cr, + double red, + double green, + double blue); + void (*cairo_reset_clip)(cairo_t* cr); + unsigned char* (*cairo_image_surface_get_data)(cairo_surface_t* surface); + void (*cairo_line_to)(cairo_t* cr, + double x, + double y); + void (*cairo_surface_destroy)(cairo_surface_t* surface); + cairo_surface_t* (*cairo_image_surface_create_for_data)(unsigned char* data, + cairo_format_t format, + int width, + int height, + int stride); + cairo_surface_t* (*cairo_image_surface_create)(cairo_format_t format, + int width, + int height); + void (*cairo_destroy)(cairo_t* cr); + cairo_pattern_t* (*cairo_get_source)(cairo_t* cr); + void (*cairo_close_path)(cairo_t* cr); + void (*cairo_paint)(cairo_t* cr); + void (*cairo_surface_flush)(cairo_surface_t* surface); + void (*cairo_clip)(cairo_t* cr); + void (*cairo_surface_mark_dirty)(cairo_surface_t* surface); + void (*cairo_stroke)(cairo_t* cr); + void (*cairo_set_source_surface)(cairo_t* cr, + cairo_surface_t* surface, + double x, + double y); + void (*cairo_fill)(cairo_t* cr); + void (*cairo_pattern_set_filter)(cairo_pattern_t* pattern, + cairo_filter_t filter); + +} wayland_call_table_t; + +extern wayland_call_table_t wl_call_tbl; + +/* defined inline right here so that it doesn't conflict with the other macros */ +MwInline int wayland_load_funcs() { + wl_call_tbl.lib = MwDynamicOpen("libwayland-client.so"); + if(!wl_call_tbl.lib) { + printf("(libwayland-client.so not found, falling back to X11)\n"); + return 1; + } + wl_call_tbl.xkb_lib = MwDynamicOpen("libxkbcommon.so"); + if(!wl_call_tbl.xkb_lib) { + printf("(libxkbcommon.so not found, cannot use Wayland backend.)\n"); + return 1; + } + wl_call_tbl.cairo_lib = MwDynamicOpen("libcairo.so"); + if(!wl_call_tbl.cairo_lib) { + printf("(libcairo.so not found, cannot use Wayland backend.)\n"); + return 1; + } +#define WAYLAND_FUNC(x) \ + wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.lib, #x); \ + if(!wl_call_tbl.x) { \ + printf("WARNING: Could use Wayland backend if " #x " was found.\n"); \ + return 1; \ + }; + + WAYLAND_FUNC(wl_display_dispatch_pending) + WAYLAND_FUNC(wl_display_disconnect) + WAYLAND_FUNC(wl_display_cancel_read) + WAYLAND_FUNC(wl_display_prepare_read) + WAYLAND_FUNC(wl_display_read_events) + WAYLAND_FUNC(wl_display_flush) + WAYLAND_FUNC(wl_display_get_fd) + WAYLAND_FUNC(wl_display_roundtrip) + WAYLAND_FUNC(wl_proxy_add_listener) + WAYLAND_FUNC(wl_proxy_destroy) + WAYLAND_FUNC(wl_log_set_handler_client) + WAYLAND_FUNC(wl_proxy_marshal_flags) + WAYLAND_FUNC(wl_display_connect) + WAYLAND_FUNC(wl_proxy_get_version) + +#undef WAYLAND_FUNC + +#define XKB_FUNC(x) \ + wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.xkb_lib, #x); \ + if(!wl_call_tbl.x) { \ + printf("WARNING: Could use Wayland backend if " #x " was found. Do you have libxkbcommon?\n"); \ + return 1; \ + }; + + XKB_FUNC(xkb_state_unref) + XKB_FUNC(xkb_context_new) + XKB_FUNC(xkb_context_unref) + XKB_FUNC(xkb_state_new) + XKB_FUNC(xkb_keymap_new_from_string) + XKB_FUNC(xkb_keymap_unref) + XKB_FUNC(xkb_keymap_num_levels_for_key) + XKB_FUNC(xkb_keymap_key_get_syms_by_level) + XKB_FUNC(xkb_state_key_get_layout) +#undef XKB_FUNC + +#define CAIRO_FUNC(x) \ + wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.cairo_lib, #x); \ + if(!wl_call_tbl.x) { \ + printf("WARNING: Could use Wayland backend if " #x " was found. Do you have libcairo?\n"); \ + return 1; \ + }; + + CAIRO_FUNC(cairo_set_line_width); + CAIRO_FUNC(cairo_scale); + CAIRO_FUNC(cairo_create); + CAIRO_FUNC(cairo_move_to); + CAIRO_FUNC(cairo_rectangle); + CAIRO_FUNC(cairo_new_path); + CAIRO_FUNC(cairo_set_line_cap); + CAIRO_FUNC(cairo_set_source_rgba); + CAIRO_FUNC(cairo_set_source_rgb); + CAIRO_FUNC(cairo_reset_clip); + CAIRO_FUNC(cairo_image_surface_get_data); + CAIRO_FUNC(cairo_line_to); + CAIRO_FUNC(cairo_surface_destroy); + CAIRO_FUNC(cairo_image_surface_create_for_data); + CAIRO_FUNC(cairo_image_surface_create); + CAIRO_FUNC(cairo_destroy); + CAIRO_FUNC(cairo_get_source); + CAIRO_FUNC(cairo_close_path); + CAIRO_FUNC(cairo_paint); + CAIRO_FUNC(cairo_surface_flush); + CAIRO_FUNC(cairo_clip); + CAIRO_FUNC(cairo_surface_mark_dirty); + CAIRO_FUNC(cairo_stroke); + CAIRO_FUNC(cairo_set_source_surface); + CAIRO_FUNC(cairo_fill); + CAIRO_FUNC(cairo_pattern_set_filter); +#undef CAIRO_FUNC + + return 0; +} + +#define wl_display_dispatch_pending wl_call_tbl.wl_display_dispatch_pending +#define wl_display_disconnect wl_call_tbl.wl_display_disconnect +#define wl_display_cancel_read wl_call_tbl.wl_display_cancel_read +#define wl_display_prepare_read wl_call_tbl.wl_display_prepare_read +#define wl_display_read_events wl_call_tbl.wl_display_read_events +#define wl_display_flush wl_call_tbl.wl_display_flush +#define wl_display_get_fd wl_call_tbl.wl_display_get_fd +#define wl_display_roundtrip wl_call_tbl.wl_display_roundtrip +#define wl_proxy_add_listener wl_call_tbl.wl_proxy_add_listener +#define wl_proxy_destroy wl_call_tbl.wl_proxy_destroy +#define wl_log_set_handler_client wl_call_tbl.wl_log_set_handler_client +#define wl_proxy_marshal_flags wl_call_tbl.wl_proxy_marshal_flags +#define wl_display_connect wl_call_tbl.wl_display_connect +#define wl_proxy_get_version wl_call_tbl.wl_proxy_get_version + +#define xkb_state_unref wl_call_tbl.xkb_state_unref +#define xkb_context_new wl_call_tbl.xkb_context_new +#define xkb_context_unref wl_call_tbl.xkb_context_unref +#define xkb_state_new wl_call_tbl.xkb_state_new +#define xkb_keymap_new_from_string wl_call_tbl.xkb_keymap_new_from_string +#define xkb_keymap_unref wl_call_tbl.xkb_keymap_unref +#define xkb_keymap_num_levels_for_key wl_call_tbl.xkb_keymap_num_levels_for_key +#define xkb_keymap_key_get_syms_by_level wl_call_tbl.xkb_keymap_key_get_syms_by_level +#define xkb_state_key_get_layout wl_call_tbl.xkb_state_key_get_layout + +#define cairo_set_line_width wl_call_tbl.cairo_set_line_width +#define cairo_scale wl_call_tbl.cairo_scale +#define cairo_create wl_call_tbl.cairo_create +#define cairo_move_to wl_call_tbl.cairo_move_to +#define cairo_rectangle wl_call_tbl.cairo_rectangle +#define cairo_new_path wl_call_tbl.cairo_new_path +#define cairo_set_line_cap wl_call_tbl.cairo_set_line_cap +#define cairo_set_source_rgba wl_call_tbl.cairo_set_source_rgba +#define cairo_set_source_rgb wl_call_tbl.cairo_set_source_rgb +#define cairo_reset_clip wl_call_tbl.cairo_reset_clip +#define cairo_image_surface_get_data wl_call_tbl.cairo_image_surface_get_data +#define cairo_line_to wl_call_tbl.cairo_line_to +#define cairo_surface_destroy wl_call_tbl.cairo_surface_destroy +#define cairo_image_surface_create_for_data wl_call_tbl.cairo_image_surface_create_for_data +#define cairo_image_surface_create wl_call_tbl.cairo_image_surface_create +#define cairo_destroy wl_call_tbl.cairo_destroy +#define cairo_get_source wl_call_tbl.cairo_get_source +#define cairo_close_path wl_call_tbl.cairo_close_path +#define cairo_paint wl_call_tbl.cairo_paint +#define cairo_surface_flush wl_call_tbl.cairo_surface_flush +#define cairo_clip wl_call_tbl.cairo_clip +#define cairo_surface_mark_dirty wl_call_tbl.cairo_surface_mark_dirty +#define cairo_stroke wl_call_tbl.cairo_stroke +#define cairo_set_source_surface wl_call_tbl.cairo_set_source_surface +#define cairo_fill wl_call_tbl.cairo_fill +#define cairo_pattern_set_filter wl_call_tbl.cairo_pattern_set_filter + #ifndef WL_PROTOCOLS_DEFINED #define WL_PROTOCOLS_DEFINED +#include "Wayland/wayland-core-protocol.h" #include "Wayland/xdg-shell-client-protocol.h" #include "Wayland/viewporter-client-protocol.h" #include "Wayland/xdg-decoration-client-protocol.h" @@ -31,16 +288,6 @@ MWDECL int MwLLWaylandCallInit(void); #include "Wayland/xdg-toplevel-icon-client-protocol.h" #endif -#define CSD_BORDER_FRAME_LEFT 5 -#define CSD_BORDER_FRAME_RIGHT 5 -#define CSD_BORDER_FRAME_TOP 24 -#define CSD_BORDER_FRAME_BOTTOM 5 - -#define CSD_LEFT_OFFSET(handle) handle->wayland.has_decorations ? 0 : CSD_BORDER_FRAME_LEFT -#define CSD_TOP_OFFSET(handle) handle->wayland.has_decorations ? 0 : CSD_BORDER_FRAME_TOP - -struct _MwLLWayland; - typedef struct wayland_protocol { void* listener; void* context; diff --git a/pl/rules.pl b/pl/rules.pl index a4ba7bf..81a1ece 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -29,13 +29,12 @@ if (grep(/^gdi$/, @backends)) { if (grep(/^wayland$/, @backends)) { add_cflags("-DUSE_WAYLAND"); new_object("src/backend/wayland.c"); - add_cflags(`pkg-config --cflags cairo wayland-client xkbcommon`); - add_libs(`pkg-config --libs cairo wayland-client xkbcommon`); if (param_get("opengl")) { - add_libs(`pkg-config --libs egl wayland-egl`); + add_cflags("-DWAYLAND_LOAD_OPENGL"); } + scan_wayland_protocol_core(); scan_wayland_protocol("stable", "xdg-shell", ""); scan_wayland_protocol("stable", "viewporter", ""); scan_wayland_protocol("stable", "tablet", "-v2"); diff --git a/pl/utils.pl b/pl/utils.pl index f2f722b..77131a0 100644 --- a/pl/utils.pl +++ b/pl/utils.pl @@ -58,6 +58,35 @@ sub use_backend { } } + +sub scan_wayland_protocol_core { + my $proto_c = "src/backend/wayland-core-protocol.c"; + + if ( + system( +"wayland-scanner private-code /usr/share/wayland/wayland.xml ${proto_c}" + ) != 0 + ) + { + print( +"^ Error on getting private code for /usr/share/wayland/wayland.xml\n" + ); + } + else { + new_object($proto_c); + } + if ( + system( +"wayland-scanner client-header /usr/share/wayland/wayland.xml include/Mw/LowLevel/Wayland/wayland-core-protocol.h" + ) + ) + { + print( +"^ Error on getting client header for /usr/share/wayland/wayland.xml\n" + ); + } +} + sub scan_wayland_protocol { my $tier = $_[0]; my $proto = $_[1]; diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 2b581c6..34c87cf 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -19,6 +19,8 @@ #include #endif +wayland_call_table_t wl_call_tbl; + /* Standard procedure before most event callbacks in Wayland ("most" because the setup ones don't need this). Wait for the Mutex to be freed, if we're deadlocking for longer then a quarter of a second then do nothing with the event. */ #define WAYLAND_EVENT_OP_START(self) \ do { \ @@ -57,6 +59,8 @@ static void new_protocol(void* data, struct wl_registry* registry, MwU32 name, const char* interface, MwU32 version) { MwLL self = data; + (void)version; + (void)registry; WAYLAND_EVENT_OP_START(self); @@ -76,6 +80,9 @@ static void new_protocol(void* data, struct wl_registry* registry, static void protocol_removed(void* data, struct wl_registry* registry, MwU32 name) { + (void)data; + (void)registry; + (void)name; printf("%d destroyed\n", name); }; @@ -155,6 +162,7 @@ static void wl_data_device_data_offer(void* data, struct wl_data_device* wl_data_device, struct wl_data_offer* offer) { wl_clipboard_device_context_t* self = data; + (void)wl_data_device; wl_data_offer_add_listener(offer, &offer_listener, data); @@ -169,6 +177,11 @@ static void wl_data_device_enter(void* data, wl_fixed_t y, struct wl_data_offer* id) { MwLL self = data; + (void)wl_data_device; + (void)surface; + (void)x; + (void)y; + (void)id; WAYLAND_EVENT_OP_START(self); @@ -189,14 +202,24 @@ static void wl_data_device_motion(void* data, uint32_t time, wl_fixed_t x, wl_fixed_t y) { + (void)data; + (void)wl_data_device; + (void)time; + (void)x; + (void)y; }; static void wl_data_device_drop(void* data, struct wl_data_device* wl_data_device) { + (void)data; + (void)wl_data_device; }; static void wl_data_device_selection(void* data, struct wl_data_device* wl_data_device, struct wl_data_offer* id) { + (void)data; + (void)wl_data_device; + (void)id; }; struct wl_data_device_listener wl_data_device_listener = { @@ -212,6 +235,7 @@ static void zwp_primary_selection_device_v1_data_offer(void* data, struct zwp_primary_selection_device_v1* zwp_primary_selection_device_v1, struct zwp_primary_selection_offer_v1* offer) { wl_clipboard_device_context_t* self = data; + (void)zwp_primary_selection_device_v1; self->offer.zwp = offer; }; @@ -219,6 +243,9 @@ static void zwp_primary_selection_device_v1_data_offer(void* data, static void zwp_primary_selection_device_v1_selection(void* data, struct zwp_primary_selection_device_v1* zwp_primary_selection_device_v1, struct zwp_primary_selection_offer_v1* id) { + (void)data; + (void)zwp_primary_selection_device_v1; + (void)id; }; struct zwp_primary_selection_device_v1_listener zwp_primary_selection_device_v1_listener = { @@ -232,7 +259,6 @@ static void wl_clipboard_read(wl_clipboard_device_context_t* ctx) { char* buf = NULL; struct timeval timeout; int rc = 0; - int n; if(pipe(fds) != 0) { return; @@ -254,7 +280,6 @@ static void wl_clipboard_read(wl_clipboard_device_context_t* ctx) { wl_display_roundtrip(ctx->ll->wayland.display); while(MwTRUE) { - char ch; rc = select(fds[0] + 1, &set, NULL, NULL, &timeout); if(rc <= 0) { break; @@ -279,12 +304,17 @@ static void wl_clipboard_read(wl_clipboard_device_context_t* ctx) { static void wl_data_source_listener_target(void* data, struct wl_data_source* wl_data_source, const char* mime_type) { + (void)data; + (void)wl_data_source; + (void)mime_type; }; static void wl_data_source_listener_send(void* data, struct wl_data_source* wl_data_source, const char* mime_type, int32_t fd) { MwLL self = data; + (void)wl_data_source; + (void)mime_type; WAYLAND_EVENT_OP_START(self); if(self->wayland.clipboard_buffer != NULL) { @@ -328,6 +358,8 @@ static void zwp_primary_selection_source_v1_send(void* data, const char* mime_type, int32_t fd) { MwLL self = data; + (void)wl_data_source; + (void)mime_type; WAYLAND_EVENT_OP_START(self); @@ -341,6 +373,7 @@ static void zwp_primary_selection_source_v1_send(void* data, static void zwp_primary_selection_source_v1_cancelled(void* data, struct zwp_primary_selection_source_v1* wl_data_source) { MwLL self = data; + (void)wl_data_source; WAYLAND_EVENT_OP_START(self); @@ -380,6 +413,7 @@ static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLL } static void wl_data_device_manager_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)data; if(wayland->clipboard_manager.wl != NULL && !wayland->supports_zwp) { wl_data_device_manager_destroy(wayland->clipboard_manager.wl); wl_data_source_destroy(wayland->clipboard_source.wl); @@ -411,7 +445,8 @@ static wayland_protocol_t* zwp_primary_selection_device_manager_v1_setup(MwU32 n } static void zwp_primary_selection_device_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - // zwp_primary_selection_device_manager_v1_destroy(wayland->clipboard_manager.zwp); + (void)wayland; + (void)data; } /* `wl_pointer.enter` callback */ @@ -419,6 +454,8 @@ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 seria struct wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { MwLL self = data; + (void)surface_x; + (void)surface_y; WAYLAND_EVENT_OP_START(self); self->wayland.curSurface = surface; @@ -433,6 +470,10 @@ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 seria /* `wl_pointer.leave` callback */ static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial, struct wl_surface* surface) { + (void)data; + (void)wl_pointer; + (void)serial; + (void)surface; }; static void xdg_borderless_step(MwLL self, MwLLMouse p, MwU32 serial) { @@ -466,8 +507,8 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time wl_fixed_t surface_x, wl_fixed_t surface_y) { MwLL self = data; MwLLMouse p; - int i = 0; - MwWidget h = (MwWidget)self->common.user; + (void)time; + (void)wl_pointer; WAYLAND_EVENT_OP_START(self); @@ -488,8 +529,9 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri MwLL self = data; MwLLMouse p; - int x = self->wayland.x; - int y = self->wayland.y; + (void)wl_pointer; + (void)serial; + (void)time; WAYLAND_EVENT_OP_START(self); @@ -544,7 +586,13 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri /* `wl_pointer.axis` callback */ static void pointer_axis(void* data, struct wl_pointer* wl_pointer, MwU32 time, - MwU32 axis, wl_fixed_t value) {}; + MwU32 axis, wl_fixed_t value) { + (void)data; + (void)wl_pointer; + (void)time; + (void)axis; + (void)value; +}; struct wl_pointer_listener pointer_listener = { .enter = pointer_enter, @@ -561,6 +609,7 @@ static void keyboard_keymap(void* data, int32_t fd, MwU32 size) { MwLL self = data; + (void)wl_keyboard; if(self->wayland.type == MWLL_WAYLAND_TOPLEVEL) { struct _MwLLWaylandTopLevel* wayland = self->wayland.toplevel; @@ -589,6 +638,9 @@ static void keyboard_enter(void* data, struct wl_surface* surface, struct wl_array* keys) { MwLL self = data; + (void)wl_keyboard; + (void)surface; + (void)keys; WAYLAND_EVENT_OP_START(self); @@ -605,6 +657,9 @@ static void keyboard_leave(void* data, MwU32 serial, struct wl_surface* surface) { MwLL self = data; + (void)wl_keyboard; + (void)serial; + (void)surface; WAYLAND_EVENT_OP_START(self); @@ -621,6 +676,9 @@ static void keyboard_key(void* data, MwU32 key, MwU32 state) { MwLL self = data; + (void)wl_keyboard; + (void)serial; + (void)time; WAYLAND_EVENT_OP_START(self); @@ -726,6 +784,10 @@ static void keyboard_modifiers(void* data, MwU32 mods_locked, MwU32 group) { MwLL self = data; + (void)wl_keyboard; + (void)serial; + (void)group; + (void)mods_latched; WAYLAND_EVENT_OP_START(self); @@ -746,7 +808,11 @@ struct wl_keyboard_listener keyboard_listener = { /* `wl_seat.name` callback */ static void -wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {}; +wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) { + (void)data; + (void)wl_seat; + (void)name; +}; /* `wl_seat.capabilities` callback */ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat, @@ -797,14 +863,28 @@ static void output_geometry(void* data, int32_t subpixel, const char* make, const char* model, - int32_t transform) {}; + int32_t transform) { + (void)data; + (void)wl_output; + (void)x; + (void)y; + (void)physical_width; + (void)physical_height; + (void)subpixel; + (void)make; + (void)model; + (void)transform; +}; static void output_mode(void* data, struct wl_output* wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { - MwLL self = data; + MwLL self = data; + (void)wl_output; + (void)flags; + (void)refresh; self->wayland.mw = width; self->wayland.mh = height; }; @@ -818,6 +898,7 @@ struct wl_output_listener output_listener = { void xdg_wm_base_ping(void* data, struct xdg_wm_base* xdg_wm_base, MwU32 serial) { + (void)data; xdg_wm_base_pong(xdg_wm_base, serial); }; @@ -835,6 +916,7 @@ static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll) { } static void wl_seat_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; free(data->listener); } @@ -847,6 +929,8 @@ static wayland_protocol_t* wl_output_setup(MwU32 name, MwLL ll) { } static void wl_output_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; } /* wl_compositor setup function */ @@ -857,6 +941,8 @@ static wayland_protocol_t* wl_compositor_setup(MwU32 name, struct _MwLLWayland* } static void wl_compositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; } /* wl_subcompositor setup function */ @@ -871,6 +957,7 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan } static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)data; wl_subcompositor_destroy(wayland->sublevel->subcompositor); } @@ -888,6 +975,7 @@ static wayland_protocol_t* xdg_wm_base_setup(MwU32 name, struct _MwLLWayland* wa } static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; free(data->listener); } @@ -900,7 +988,8 @@ static wayland_protocol_t* wp_viewporter_setup(MwU32 name, struct _MwLLWayland* } static void wp_viewporter_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - // free(data->listener); + (void)wayland; + (void)data; } /* the two decoration manager constructs */ @@ -924,6 +1013,8 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _ } static void zxdg_decoration_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; } /* Standard Wayland event loop. */ @@ -931,7 +1022,6 @@ static int event_loop(MwLL handle) { struct pollfd fd; struct timespec timeout; struct _MwLLWayland* wayland = &handle->wayland; - int res; timeout.tv_nsec = 1; timeout.tv_sec = 0; @@ -977,7 +1067,6 @@ static int event_loop(MwLL handle) { /* make the fuck sure that we're configurd */ static void hang_until_configured(MwLL handle) { - int i = 0; while(!handle->wayland.configured) { if(wl_display_roundtrip(handle->wayland.display) == -1) { printf("roundtrip failed\n"); @@ -993,9 +1082,9 @@ static void xdg_toplevel_configure(void* data, struct xdg_toplevel* xdg_toplevel, MwI32 width, MwI32 height, struct wl_array* states) { - MwLL self = data; - int i; - MwWidget h = ((MwWidget)self->common.user); + MwLL self = data; + (void)states; + (void)xdg_toplevel; /* Yes, somehow this can get called before */ if(!self->wayland.configured) { @@ -1029,16 +1118,11 @@ static void xdg_toplevel_configure(void* data, recursive_dispatch_resize(self); }; -/* Empty function for satisfying zxdg_toplevel's requirements */ -static void decoration_configure( - void* data, struct zxdg_toplevel_decoration_v1* zxdg_toplevel_decoration_v1, - MwU32 mode) { -} - /* `xdg_surface.close` callback */ static void xdg_toplevel_close( void* data, struct xdg_toplevel* xdg_toplevel) { MwLL self = data; + (void)xdg_toplevel; WAYLAND_EVENT_OP_START(self); MwLLDispatch(self, close, NULL); WAYLAND_EVENT_OP_END(self); @@ -1069,6 +1153,8 @@ static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland } static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; } static void update_buffer(struct _MwLLWaylandShmBuffer* buffer) { @@ -1077,7 +1163,6 @@ static void update_buffer(struct _MwLLWaylandShmBuffer* buffer) { } static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) { - int x, y; int stride = width * 4; char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX"; @@ -1215,6 +1300,7 @@ static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct } static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; free(data->listener); } @@ -1256,8 +1342,6 @@ static void setup_callbacks(struct _MwLLWayland* wayland) { /* Toplevel setup function */ static void setup_toplevel(MwLL r, int x, int y) { - int i; - r->wayland.type = MWLL_WAYLAND_TOPLEVEL; r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel)); r->wayland.x = x; @@ -1335,8 +1419,6 @@ static void setup_toplevel(MwLL r, int x, int y) { /* Toplevel destroy function */ static void destroy_toplevel(MwLL r) { - int i; - if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context; zxdg_decoration_manager_v1_destroy(dec->manager); @@ -1428,6 +1510,7 @@ static void popup_configure(void* data, int32_t width, int32_t height) { MwLL self = data; + (void)xdg_popup; self->wayland.x = x; self->wayland.y = y; @@ -1437,6 +1520,8 @@ static void popup_configure(void* data, static void popup_done(void* data, struct xdg_popup* xdg_popup) { + (void)data; + (void)xdg_popup; }; struct xdg_popup_listener popup_listener = { @@ -1446,7 +1531,6 @@ struct xdg_popup_listener popup_listener = { /* Popup setup function */ static void setup_popup(MwLL r, int x, int y) { - int i; struct xdg_surface* xdg_surface; MwLL topmost_parent = r->wayland.parent; @@ -1529,24 +1613,12 @@ static void destroy_popup(MwLL r) { } static void clip(MwLL handle) { - MwLL parent = handle->wayland.parent; - MwLL topmost = parent; - int left_offset = 0; - int top_offset = 0; - + MwLL parent = handle->wayland.parent; if(parent && handle->wayland.type == MWLL_WAYLAND_SUBLEVEL) { cairo_reset_clip(handle->wayland.front_cairo); cairo_rectangle(handle->wayland.front_cairo, 0, 0, (parent->wayland.ww + handle->wayland.x), (parent->wayland.wh + handle->wayland.y)); cairo_clip(handle->wayland.front_cairo); } - // if(topmost && handle->wayland.type == MWLL_WAYLAND_SUBLEVEL) { - // cairo_reset_clip(handle->wayland.front_cairo); - // while(topmost->wayland.parent) topmost = topmost->wayland.parent; - // left_offset = topmost->wayland.has_decorations ? 0 : (CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT); - // top_offset = topmost->wayland.has_decorations ? 0 : (CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM); - // cairo_rectangle(handle->wayland.front_cairo, 0, 0, (topmost->wayland.ww + handle->wayland.x) - left_offset, (topmost->wayland.wh + handle->wayland.y) - top_offset); - // cairo_clip(handle->wayland.front_cairo); - // } } static void wl_logger(const char* fmt, va_list args) { @@ -1560,8 +1632,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { memset(r, 0, sizeof(*r)); MwLLCreateCommon(r); - wl_log_set_handler_client(wl_logger); - /* Wayland does not report global coordinates ever. Compositors are not even expected to have knowledge of this. */ r->common.coordinate_type = MwCoordinatesLocal; @@ -1677,9 +1747,6 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign } static void MwLLSetXYImpl(MwLL handle, int x, int y) { - int i = 0; - MwWidget h = (MwWidget)handle->common.user; - region_invalidate(handle); handle->wayland.x = x; handle->wayland.y = y; @@ -1692,8 +1759,6 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) { } static void MwLLSetWHImpl(MwLL handle, int w, int h) { - int i = 0; - MwWidget widget = (MwWidget)handle->common.user; region_invalidate(handle); /* Prevent an integer underflow when the w/h is too low */ @@ -1734,7 +1799,7 @@ static void MwLLBeginDrawImpl(MwLL handle) { } if(!handle->wayland.has_decorations) { - int x, y; + int x; MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT; MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM; cairo_set_line_width(handle->wayland.back_cairo, 4.0); @@ -1870,6 +1935,7 @@ static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { MwLLColor c = malloc(sizeof(*c)); + (void)handle; c->common.red = r; c->common.blue = b; @@ -1879,6 +1945,7 @@ static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { } static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { + (void)handle; c->common.red = r; c->common.blue = b; c->common.green = g; @@ -1929,7 +1996,6 @@ static int MwLLPendingImpl(MwLL handle) { } static void MwLLNextEventImpl(MwLL handle) { - int i = 0; if(!handle->wayland.always_render) { if(handle->wayland.did_event_loop_early) { handle->wayland.did_event_loop_early = MwFALSE; @@ -1961,6 +2027,7 @@ static void MwLLSetTitleImpl(MwLL handle, const char* title) { static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { MwLLPixmap r = malloc(sizeof(*r)); + (void)handle; r->common.width = width; r->common.height = height; @@ -2030,7 +2097,6 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { if(WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1) != NULL) { - void* map; struct xdg_toplevel_icon_manager_v1* icon_manager = WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1)->context; struct xdg_toplevel_icon_v1* icon = xdg_toplevel_icon_manager_v1_create_icon(icon_manager); MwU64 size = pixmap->common.width * pixmap->common.height * 4; @@ -2092,7 +2158,6 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { for(y = 0; y < mask->height; y++) { unsigned int d = mask->data[y]; for(x = mask->width - 1; x >= 0; x--) { - int px = 0; int idx = ((y * image->width) + x) * 4; if(d & 1) { @@ -2135,6 +2200,7 @@ static void MwLLDetachImpl(MwLL handle, MwPoint* point) { } static void MwLLShowImpl(MwLL handle, int show) { + (void)show; switch(handle->wayland.type) { case MWLL_WAYLAND_UNKNOWN: case MWLL_WAYLAND_TOPLEVEL: @@ -2147,6 +2213,9 @@ static void MwLLShowImpl(MwLL handle, int show) { } static void MwLLMakePopupImpl(MwLL handle, MwLL parent) { + (void)handle; + (void)parent; + /* Wayland doesn't have "popups" in the Milsko sense persay. xdg_popup is closer to ToolWindow and as such is what we use there. So just like the Mac backend, this is just left alone. */ } static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) { @@ -2157,6 +2226,7 @@ static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int } static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { + (void)toggle; if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { if(WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1) != NULL) { zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1)->context; @@ -2171,10 +2241,14 @@ static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { } static void MwLLFocusImpl(MwLL handle) { + (void)handle; printf("[WARNING] MwLLFocus not supported on Wayland\n"); } static void MwLLGrabPointerImpl(MwLL handle, int toggle) { + (void)handle; + (void)toggle; + printf("[WARNING] MwLLGrabPointer not supported on Wayland\n"); } static void MwLLSetClipboardImpl(MwLL handle, const char* text) { @@ -2200,6 +2274,7 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text) { } static void MwLLGetClipboardImpl(MwLL handle) { + (void)handle; /* no-op */ return; } @@ -2255,11 +2330,16 @@ static void MwLLEndStateChangeImpl(MwLL handle) { static int MwLLWaylandCallInitImpl(void) { #ifdef __linux__ - if(strcmp(getenv("XDG_SESSION_TYPE"), "wayland")) { - return 1; + if(strcmp(getenv("XDG_SESSION_TYPE"), "wayland") == 0) { + if(wayland_load_funcs()) { + return 1; + } + wl_log_set_handler_client(wl_logger); + + return 0; } #endif - return 0; + return 1; } #include "call.c" diff --git a/src/widget/opengl.c b/src/widget/opengl.c index 7d685ad..59e3a40 100644 --- a/src/widget/opengl.c +++ b/src/widget/opengl.c @@ -57,6 +57,47 @@ typedef struct waylandopengl { EGLContext egl_context; EGLSurface egl_surface; EGLConfig egl_config; + + void* gllib; + void* wlgllib; + EGLBoolean (*eglGetConfigs)(EGLDisplay display, + EGLConfig* configs, + EGLint config_size, + EGLint* num_config); + EGLBoolean (*eglInitialize)(EGLDisplay display, + EGLint* major, + EGLint* minor); + EGLContext (*eglCreateContext)(EGLDisplay display, + EGLConfig config, + EGLContext share_context, + EGLint const* attrib_list); + EGLBoolean (*eglMakeCurrent)(EGLDisplay display, + EGLSurface draw, + EGLSurface read, + EGLContext context); + void* (*eglGetProcAddress)(char const* procname); + EGLBoolean (*eglSwapBuffers)(EGLDisplay display, + EGLSurface surface); + EGLBoolean (*eglSwapInterval)(EGLDisplay display, + EGLint interval); + EGLint (*eglGetError)(void); + EGLBoolean (*eglBindAPI)(EGLenum api); + EGLDisplay (*eglGetDisplay)(NativeDisplayType native_display); + EGLSurface (*eglCreateWindowSurface)(EGLDisplay display, + EGLConfig config, + NativeWindowType native_window, + EGLint const* attrib_list); + EGLBoolean (*eglChooseConfig)(EGLDisplay display, + EGLint const* attrib_list, + EGLConfig* configs, + EGLint config_size, + EGLint* num_config); + + struct wl_egl_window* (*wl_egl_window_create)(struct wl_surface* surface, + int width, int height); + void (*wl_egl_window_resize)(struct wl_egl_window* egl_window, + int width, int height, + int dx, int dy); } waylandopengl_t; #endif @@ -136,7 +177,6 @@ static int create(MwWidget handle) { #endif #ifdef USE_WAYLAND if(handle->lowlevel->common.type == MwLLBackendWayland) { - int err; EGLint numConfigs; EGLint majorVersion; EGLint minorVersion; @@ -174,6 +214,58 @@ static int create(MwWidget handle) { topmost_parent = topmost_parent->wayland.parent; } + o->gllib = MwDynamicOpen("libEGL.so"); + if(!o->gllib) { + printf("Could not load OpenGL widget under Wayland! libEGL.so missing.\n"); + return 1; + } + o->wlgllib = MwDynamicOpen("libwayland-egl.so"); + if(!o->gllib) { + printf("Could not load OpenGL widget under Wayland! libwayland-egl.so missing.\n"); + return 1; + } +#define EGL_FUNC(x) \ + o->x = MwDynamicSymbol(o->gllib, #x); \ + if(!o->x) { \ + printf("Could not load OpenGL widget under Wayland! " #x " missing.\n"); \ + return 1; \ + }; +#define WAYLAND_EGL_FUNC(x) \ + o->x = MwDynamicSymbol(o->wlgllib, #x); \ + if(!o->x) { \ + printf("Could not load OpenGL widget under Wayland! " #x " missing.\n"); \ + return 1; \ + }; + EGL_FUNC(eglGetConfigs) + EGL_FUNC(eglInitialize) + EGL_FUNC(eglCreateContext) + EGL_FUNC(eglMakeCurrent) + EGL_FUNC(eglGetProcAddress) + EGL_FUNC(eglSwapBuffers) + EGL_FUNC(eglSwapInterval) + EGL_FUNC(eglGetError) + EGL_FUNC(eglBindAPI) + EGL_FUNC(eglGetDisplay) + EGL_FUNC(eglCreateWindowSurface) + EGL_FUNC(eglChooseConfig) + WAYLAND_EGL_FUNC(wl_egl_window_create) + WAYLAND_EGL_FUNC(wl_egl_window_resize) + +#define eglGetConfigs o->eglGetConfigs +#define eglInitialize o->eglInitialize +#define eglCreateContext o->eglCreateContext +#define eglMakeCurrent o->eglMakeCurrent +#define eglGetProcAddress o->eglGetProcAddress +#define eglSwapBuffers o->eglSwapBuffers +#define eglSwapInterval o->eglSwapInterval +#define eglGetError o->eglGetError +#define wl_egl_window_create o->wl_egl_window_create +#define eglBindAPI o->eglBindAPI +#define eglGetDisplay o->eglGetDisplay +#define wl_egl_window_resize o->wl_egl_window_resize +#define eglCreateWindowSurface o->eglCreateWindowSurface +#define eglChooseConfig o->eglChooseConfig + display = eglGetDisplay((EGLNativeDisplayType)handle->lowlevel->wayland.display); if(display == EGL_NO_DISPLAY) { @@ -391,6 +483,7 @@ static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) { #endif #ifdef USE_WAYLAND if(handle->lowlevel->common.type == MwLLBackendWayland) { + waylandopengl_t* o = handle->internal; return eglGetProcAddress(name); } #endif