dynamically load wayland and its dependencies, fix warnings
This commit is contained in:
parent
e86d6acdf3
commit
47746ff30e
5 changed files with 522 additions and 74 deletions
|
|
@ -7,22 +7,279 @@
|
|||
#ifndef __MW_LOWLEVEL_WAYLAND_H__
|
||||
#define __MW_LOWLEVEL_WAYLAND_H__
|
||||
|
||||
#include "Mw/BaseTypes.h"
|
||||
#include <Mw/MachDep.h>
|
||||
#include <Mw/TypeDefs.h>
|
||||
#include <Mw/LowLevel.h>
|
||||
#include <Mw/Abstract/Dynamic.h>
|
||||
|
||||
#include <wayland-client-protocol.h>
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <cairo/cairo.h>
|
||||
#include <pthread.h>
|
||||
|
||||
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 <wayland-client-core.h>
|
||||
|
||||
#if WAYLAND_LOAD_OPENGL
|
||||
#include <EGL/egl.h>
|
||||
#include <wayland-egl-core.h>
|
||||
#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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
29
pl/utils.pl
29
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];
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include <linux/input-event-codes.h>
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue