2025-12-09 20:11:01 -06:00
/*!
* @ file Mw / LowLevel / Wayland . h
2026-03-31 16:54:01 -07:00
* @ brief Wayland Backend
2025-12-09 20:11:01 -06:00
* @ warning This is used internally .
*/
# ifndef __MW_LOWLEVEL_WAYLAND_H__
# define __MW_LOWLEVEL_WAYLAND_H__
# include <Mw/MachDep.h>
# include <Mw/TypeDefs.h>
# include <Mw/LowLevel.h>
2026-03-24 17:38:21 -07:00
# include <Mw/Abstract/Dynamic.h>
2025-12-09 20:11:01 -06:00
# include <xkbcommon/xkbcommon.h>
2025-12-17 19:14:54 -07:00
# include <cairo/cairo.h>
2026-01-03 18:27:34 -07:00
# include <pthread.h>
2025-12-09 20:11:01 -06:00
2026-04-28 16:30:01 +00:00
# ifdef __cplusplus
extern " C " {
# endif
2025-12-09 20:11:01 -06:00
MWDECL int MwLLWaylandCallInit ( void ) ;
2026-04-28 16:30:01 +00:00
# ifdef __cplusplus
}
# endif
2026-03-24 17:38:21 -07:00
# define CSD_BORDER_FRAME_LEFT 5
# define CSD_BORDER_FRAME_RIGHT 5
2026-05-20 16:29:09 -07:00
# define CSD_BORDER_FRAME_TOP 23
# define CSD_BORDER_FRAME_BOTTOM 4
2026-03-24 17:38:21 -07:00
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 ;
2026-04-15 16:12:38 -07:00
# ifdef USE_DBUS
MwLLDBusFuncTable dbus ;
MwBool has_dbus ;
# endif
2026-03-24 17:38:21 -07:00
2026-04-16 18:36:42 -07:00
int ( * wl_display_dispatch ) ( struct wl_display * display ) ;
2026-03-24 17:38:21 -07:00
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 ) ;
2026-04-16 18:36:42 -07:00
struct wl_display * ( * wl_display_connect_to_fd ) ( int fd ) ;
2026-04-23 14:02:33 -07:00
int ( * wl_display_get_error ) ( struct wl_display * display ) ;
2026-03-24 17:38:21 -07:00
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 ) ;
2026-04-20 12:36:01 +09:00
void ( * cairo_save ) ( cairo_t * cr ) ;
void ( * cairo_restore ) ( cairo_t * cr ) ;
2026-03-24 17:38:21 -07:00
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 ) ;
2026-03-26 14:40:21 -07:00
void ( * cairo_set_antialias ) ( cairo_t * , cairo_antialias_t ) ;
2026-04-14 23:49:04 -07:00
void ( * cairo_set_operator ) ( cairo_t * cr , cairo_operator_t op ) ;
2026-03-24 17:38:21 -07:00
} wayland_call_table_t ;
extern wayland_call_table_t wl_call_tbl ;
2026-05-20 02:43:22 -07:00
# ifdef MW_VULKAN
extern MwBool MwWaylandVulkan ;
# else
# define MwWaylandVulkan 0
# endif
2026-03-24 17:38:21 -07:00
/* defined inline right here so that it doesn't conflict with the other macros */
MwInline int wayland_load_funcs ( ) {
2026-04-26 21:57:46 -07:00
# ifdef __APPLE__
wl_call_tbl . lib = MwDynamicOpen ( " libwayland-client.dylib " ) ;
# else
2026-03-24 17:38:21 -07:00
wl_call_tbl . lib = MwDynamicOpen ( " libwayland-client.so " ) ;
2026-04-26 21:57:46 -07:00
# endif
2026-03-24 17:38:21 -07:00
if ( ! wl_call_tbl . lib ) {
2026-04-26 21:57:46 -07:00
printf ( " (libwayland-client not found, falling back to X11) \n " ) ;
2026-03-24 17:38:21 -07:00
return 1 ;
}
2026-04-26 21:57:46 -07:00
# ifdef __APPLE__
wl_call_tbl . xkb_lib = MwDynamicOpen ( " libxkbcommon.dylib " ) ;
# else
2026-03-24 17:38:21 -07:00
wl_call_tbl . xkb_lib = MwDynamicOpen ( " libxkbcommon.so " ) ;
2026-04-26 21:57:46 -07:00
# endif
2026-03-24 17:38:21 -07:00
if ( ! wl_call_tbl . xkb_lib ) {
2026-04-26 21:57:46 -07:00
printf ( " (libxkbcommon not found, cannot use Wayland backend.) \n " ) ;
2026-03-24 17:38:21 -07:00
return 1 ;
}
2026-04-26 21:57:46 -07:00
# ifdef __APPLE__
wl_call_tbl . cairo_lib = MwDynamicOpen ( " libcairo.dylib " ) ;
# else
2026-03-24 17:38:21 -07:00
wl_call_tbl . cairo_lib = MwDynamicOpen ( " libcairo.so " ) ;
2026-04-26 21:57:46 -07:00
# endif
2026-03-24 17:38:21 -07:00
if ( ! wl_call_tbl . cairo_lib ) {
2026-04-26 21:57:46 -07:00
printf ( " (libcairo not found, cannot use Wayland backend.) \n " ) ;
2026-03-24 17:38:21 -07:00
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 ; \
} ;
2026-04-16 18:36:42 -07:00
WAYLAND_FUNC ( wl_display_dispatch )
2026-03-24 17:38:21 -07:00
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 )
2026-04-16 18:36:42 -07:00
WAYLAND_FUNC ( wl_display_connect_to_fd )
2026-04-23 14:02:33 -07:00
WAYLAND_FUNC ( wl_display_get_error )
2026-03-24 17:38:21 -07:00
# 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 ) ;
2026-03-26 14:40:21 -07:00
CAIRO_FUNC ( cairo_set_antialias ) ;
2026-03-24 17:38:21 -07:00
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 ) ;
2026-04-20 12:36:01 +09:00
CAIRO_FUNC ( cairo_save ) ;
CAIRO_FUNC ( cairo_restore ) ;
2026-03-24 17:38:21 -07:00
CAIRO_FUNC ( cairo_surface_mark_dirty ) ;
CAIRO_FUNC ( cairo_stroke ) ;
CAIRO_FUNC ( cairo_set_source_surface ) ;
CAIRO_FUNC ( cairo_fill ) ;
2026-04-14 23:49:04 -07:00
CAIRO_FUNC ( cairo_set_operator ) ;
2026-03-24 17:38:21 -07:00
CAIRO_FUNC ( cairo_pattern_set_filter ) ;
# undef CAIRO_FUNC
2026-04-15 16:12:38 -07:00
# ifdef USE_DBUS
wl_call_tbl . has_dbus = MwLLDBusFuncSetup ( & wl_call_tbl . dbus ) ;
# endif
2026-04-15 12:25:51 -07:00
2026-03-24 17:38:21 -07:00
return 0 ;
}
2026-04-16 18:36:42 -07:00
# define wl_display_dispatch wl_call_tbl.wl_display_dispatch
2026-03-24 17:38:21 -07:00
# 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
2026-04-16 18:36:42 -07:00
# define wl_display_connect_to_fd wl_call_tbl.wl_display_connect_to_fd
2026-04-23 14:02:33 -07:00
# define wl_display_get_error wl_call_tbl.wl_display_get_error
2026-03-24 17:38:21 -07:00
# 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
2026-03-26 14:40:21 -07:00
# define cairo_set_antialias wl_call_tbl.cairo_set_antialias
2026-03-24 17:38:21 -07:00
# 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
2026-04-20 12:36:01 +09:00
# define cairo_save wl_call_tbl.cairo_save
# define cairo_restore wl_call_tbl.cairo_restore
2026-03-24 17:38:21 -07:00
# 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
2026-04-14 23:49:04 -07:00
# define cairo_set_operator wl_call_tbl.cairo_set_operator
2026-03-24 17:38:21 -07:00
# define cairo_pattern_set_filter wl_call_tbl.cairo_pattern_set_filter
2025-12-09 20:11:01 -06:00
# ifndef WL_PROTOCOLS_DEFINED
# define WL_PROTOCOLS_DEFINED
2026-03-24 17:38:21 -07:00
# include "Wayland/wayland-core-protocol.h"
2025-12-09 20:11:01 -06:00
# include "Wayland/xdg-shell-client-protocol.h"
2026-03-19 19:43:57 -07:00
# include "Wayland/viewporter-client-protocol.h"
2025-12-09 20:11:01 -06:00
# include "Wayland/xdg-decoration-client-protocol.h"
# include "Wayland/cursor-shape-client-protocol.h"
2025-12-18 17:46:23 -07:00
# include "Wayland/primary-selection-client-protocol.h"
2026-03-24 23:44:30 -07:00
# include "Wayland/pointer-constraints-client-protocol.h"
2026-03-27 17:15:59 -07:00
# include "Wayland/relative-pointer-client-protocol.h"
2025-12-18 18:21:57 -07:00
# include "Wayland/xdg-toplevel-icon-client-protocol.h"
2026-07-07 23:04:58 -07:00
# include "Wayland/wlr-layer-shell-client-protocol.h"
2025-12-09 20:11:01 -06:00
# endif
typedef struct wayland_protocol {
void * listener ;
void * context ;
} wayland_protocol_t ;
2026-05-24 22:51:10 -07:00
typedef wayland_protocol_t * ( wl_setup_func ) ( MwU32 , struct _MwLLWayland * , MwU32 version ) ;
2025-12-18 23:32:51 -07:00
typedef void ( wl_destroy_func ) ( struct _MwLLWayland * wayland , wayland_protocol_t * data ) ;
typedef struct wayland_protocol_callback_table {
wl_setup_func * setup ;
wl_destroy_func * destroy ;
} wayland_protocol_callback_table_t ;
2025-12-09 20:11:01 -06:00
struct _MwLLWaylandTopLevel {
struct xdg_surface * xdg_surface ;
struct xdg_toplevel * xdg_top_level ;
struct xdg_toplevel_listener xdg_toplevel_listener ;
struct xdg_surface_listener xdg_surface_listener ;
2026-05-20 16:29:09 -07:00
MwBool maxim_state ;
2025-12-09 20:11:01 -06:00
MwBool compositor_created ;
MwBool xdg_wm_base_created ;
MwBool xdg_surface_created ;
2026-03-19 19:43:57 -07:00
struct wl_subsurface * ssurface ;
struct wl_subcompositor * scompositor ;
2025-12-09 20:11:01 -06:00
} ;
2025-12-17 19:14:54 -07:00
struct _MwLLWaylandSublevel {
struct wl_subsurface * subsurface ;
struct wl_subcompositor * subcompositor ;
MwLL parent ;
2025-12-18 23:32:51 -07:00
2026-03-26 23:32:24 -07:00
struct xdg_surface * xdg_surface ;
2025-12-18 23:32:51 -07:00
} ;
struct _MwLLWaylandPopup {
struct xdg_surface * xdg_surface ;
struct xdg_popup * xdg_popup ;
struct xdg_positioner * xdg_positioner ;
struct xdg_surface_listener xdg_surface_listener ;
struct xdg_wm_base * xdg_wm_base ;
2026-01-04 13:01:44 -07:00
MwLL topmost_parent ;
2025-12-17 19:14:54 -07:00
} ;
2026-07-07 23:04:58 -07:00
struct _MwLLWaylandLayerSurface {
struct zwlr_layer_surface_v1 * surface ;
} ;
2025-12-18 18:27:44 -07:00
/* Shared set of anything needed for a shm buffer. */
2025-12-18 13:15:03 -07:00
struct _MwLLWaylandShmBuffer {
struct wl_shm * shm ;
struct wl_shm_pool * shm_pool ;
struct wl_buffer * shm_buffer ;
2026-03-26 16:54:40 -07:00
struct wl_shm_pool * shm_pool_back ;
struct wl_buffer * shm_buffer_back ;
2025-12-18 13:15:03 -07:00
struct wl_surface * surface ;
2025-12-18 13:43:45 -07:00
struct wl_output * output ;
MwU8 * buf ;
2026-03-26 16:54:40 -07:00
MwU8 * buf_back ;
2025-12-18 13:43:45 -07:00
MwU64 buf_size ;
int fd ;
2026-03-26 16:54:40 -07:00
int fd_back ;
2025-12-18 13:43:45 -07:00
MwBool setup ;
2025-12-18 13:15:03 -07:00
} ;
2025-12-18 23:32:51 -07:00
enum _MwLLWaylandType {
2026-04-20 14:49:20 +09:00
MwLL_WAYLAND_UNKNOWN = 0 ,
MwLL_WAYLAND_TOPLEVEL ,
MwLL_WAYLAND_SUBLEVEL ,
MwLL_WAYLAND_POPUP ,
2026-07-07 23:04:58 -07:00
MwLL_WAYLAND_LAYER_SURFACE ,
2025-12-18 23:32:51 -07:00
} ;
2025-12-30 17:12:12 -07:00
typedef struct wl_clipboard_device_context {
2026-04-16 18:36:42 -07:00
struct {
2025-12-30 17:12:12 -07:00
struct wl_data_device * wl ;
struct zwp_primary_selection_device_v1 * zwp ;
} device ;
2026-04-16 18:36:42 -07:00
struct {
2025-12-30 17:12:12 -07:00
struct wl_data_offer * wl ;
struct zwp_primary_selection_offer_v1 * zwp ;
} offer ;
2026-04-26 13:44:11 -07:00
MwLL ll ;
// struct wl_seat* seat;
2025-12-30 17:12:12 -07:00
} wl_clipboard_device_context_t ;
2025-12-09 20:11:01 -06:00
struct _MwLLWayland {
struct _MwLLCommon common ;
2025-12-17 19:14:54 -07:00
union {
/* Pointer for data that's only loaded if the widget is a toplevel */
struct _MwLLWaylandTopLevel * toplevel ;
/* Pointer for data that's only loaded if the widget is a sublevel */
struct _MwLLWaylandSublevel * sublevel ;
2025-12-18 23:32:51 -07:00
/* Pointer for data that's only loaded if the widget is a popup */
struct _MwLLWaylandPopup * popup ;
2026-07-07 23:04:58 -07:00
/* Pointer for data that's only loaded if the widget is a layer surface */
struct _MwLLWaylandLayerSurface * layer_surface ;
2025-12-17 19:14:54 -07:00
} ;
2025-12-09 20:11:01 -06:00
2025-12-18 23:32:51 -07:00
enum _MwLLWaylandType type ;
enum _MwLLWaylandType type_to_be ;
2025-12-09 20:11:01 -06:00
2026-04-19 18:50:33 -07:00
MwRect clipping_rect ;
2026-05-05 18:10:48 -07:00
MwBool no ;
2026-04-19 18:50:33 -07:00
2026-03-23 12:05:32 -07:00
MwBool detatching ;
MwPoint detach_point ;
2026-03-23 14:28:49 -07:00
MwBool did_initial_resize ;
2026-04-24 12:53:27 +09:00
MwBool is_toplevel ;
2026-05-07 18:51:42 +09:00
MwBool is_clipping ;
MwRect clip ;
2025-12-09 20:11:01 -06:00
/* Map of Wayland interfaces to their relevant setup functions. */
struct {
2026-04-23 14:02:33 -07:00
char * key ;
2025-12-18 23:32:51 -07:00
wayland_protocol_callback_table_t * value ;
2025-12-09 20:11:01 -06:00
} * wl_protocol_setup_map ;
/* Map of Wayland interfaces to any information we keep about them once we've registered them. */
struct {
2026-04-23 14:02:33 -07:00
char * key ;
2025-12-09 20:11:01 -06:00
wayland_protocol_t * value ;
} * wl_protocol_map ;
2026-07-05 00:44:54 -07:00
MwBool do_csd ;
2026-03-19 19:43:57 -07:00
MwBool has_decorations ;
2026-04-20 15:51:51 +09:00
char title [ 256 ] ;
2026-03-19 19:43:57 -07:00
2026-03-27 15:14:04 -07:00
struct xkb_context * xkb_context ;
struct xkb_keymap * xkb_keymap ;
struct xkb_state * xkb_state ;
2025-12-09 20:11:01 -06:00
struct wl_display * display ;
struct wl_registry * registry ;
struct wl_compositor * compositor ;
struct wl_registry_listener registry_listener ;
2026-03-19 15:57:20 -07:00
struct wl_region * o_region ;
2025-12-18 11:26:51 -07:00
struct wl_region * region ;
2025-12-18 13:43:45 -07:00
struct wl_output * output ;
2025-12-18 11:26:51 -07:00
2026-03-19 19:43:57 -07:00
struct wp_viewport * vp ;
2026-03-27 17:15:59 -07:00
MwBool do_lock_pointer ;
struct zwp_pointer_constraints_v1 * pointer_constraints ;
struct zwp_relative_pointer_manager_v1 * relative_pointer_manager ;
struct zwp_relative_pointer_v1 * relative_pointer ;
struct zwp_locked_pointer_v1 * locked_pointer ;
MwBool pointer_constrained ;
2026-04-23 10:45:29 -07:00
MwBool valid ;
2026-03-24 23:44:30 -07:00
2026-04-15 16:12:38 -07:00
# ifdef USE_DBUS
MwLLDBusContext dbus ;
# endif
MwBool dark_theme_detection ;
2026-04-17 21:26:41 +09:00
MwU32 dark_theme ;
2026-04-15 12:25:51 -07:00
2025-12-30 17:12:12 -07:00
/* clipboard related stuff.
* Note that unlike most interfaces , we don ' t keep zwp_primary_selection stuff in a wayland_protocol_t because we use wl_data_device as a fallback and want to have it share memory space . */
2026-04-15 10:58:46 -07:00
struct {
2025-12-30 17:12:12 -07:00
struct wl_data_device_manager * wl ;
struct zwp_primary_selection_device_manager_v1 * zwp ;
} clipboard_manager ;
union {
struct wl_data_source * wl ;
struct zwp_primary_selection_source_v1 * zwp ;
} clipboard_source ;
char * clipboard_buffer ;
MwBool supports_zwp ;
2026-04-26 13:44:11 -07:00
MwBool zwp_setup ;
2025-12-30 17:12:12 -07:00
uint32_t clipboard_serial ;
2026-04-15 10:58:46 -07:00
wl_clipboard_device_context_t * * clipboard_devices_wl ;
wl_clipboard_device_context_t * * clipboard_devices_zwp ;
2025-12-30 17:12:12 -07:00
2026-03-20 19:28:18 -07:00
struct wl_pointer * pointer ;
MwU32 pointer_serial ;
struct wl_seat * pointer_seat ;
2025-12-30 17:12:12 -07:00
struct wl_keyboard * keyboard ;
MwU32 keyboard_serial ;
2025-12-18 13:15:03 -07:00
2025-12-30 22:26:19 -07:00
MwU64 events_pending ;
2025-12-18 19:59:40 -07:00
2025-12-18 11:36:04 -07:00
MwU32 mod_state ;
2025-12-09 20:11:01 -06:00
MwBool configured ; /* Whether or not xdg_toplevel_configure has run once */
2026-03-20 19:28:18 -07:00
MwBool held_down ;
2026-03-17 20:28:58 -07:00
MwI32 x , y ;
MwI32 ox , oy ;
MwU32 ww , wh ; /* Window position */
2025-12-17 19:14:54 -07:00
MwPoint cur_mouse_pos ; /* Currently known mouse position */
2026-05-04 20:46:34 -07:00
MwLL currentlyHeldWidget ;
2026-05-24 22:18:29 -07:00
MwLL focusedWidget ;
2025-12-09 20:11:01 -06:00
2026-04-19 21:12:39 -07:00
int resizing ;
2026-04-23 14:39:38 -07:00
int setting_wh ;
2026-04-19 21:12:39 -07:00
2025-12-18 13:43:45 -07:00
MwU32 mw , mh ; /* Monitor width and height as advertised by wl_output.mode */
2026-04-23 11:04:47 -07:00
MwLL parent ;
2025-12-18 23:32:51 -07:00
2025-12-30 17:12:12 -07:00
MwBool force_render ;
2026-03-17 17:43:22 -07:00
MwBool did_event_loop_early ;
2025-12-30 17:12:12 -07:00
2026-03-27 15:14:04 -07:00
MwBool dispatching_resize ;
2025-12-18 18:21:57 -07:00
struct _MwLLWaylandShmBuffer framebuffer ;
2026-03-19 19:43:57 -07:00
struct _MwLLWaylandShmBuffer backbuffer ;
2025-12-18 18:21:57 -07:00
struct _MwLLWaylandShmBuffer cursor ;
struct _MwLLWaylandShmBuffer * icon ;
2025-12-09 20:11:01 -06:00
2026-05-20 16:29:09 -07:00
MwLLPixmap icon_pixmap ;
2026-01-03 18:27:34 -07:00
pthread_mutex_t eventsMutex ;
2026-04-23 10:45:29 -07:00
int cancelEvent ;
int numCallbacksRunning ;
2026-01-12 18:18:05 -07:00
uint32_t last_time ;
2026-03-19 19:43:57 -07:00
MwBool moving ;
2026-05-24 23:01:48 -07:00
MwI64 keyboard_rate ;
MwI32 keyboard_delay ;
int last_pressed_key ;
MwBool holding_key ;
MwU64 next_elapsed ;
long start_time ;
long end_time ;
2026-05-24 22:51:10 -07:00
2026-03-19 19:43:57 -07:00
cairo_surface_t * front_cs ;
cairo_surface_t * back_cs ;
cairo_t * front_cairo ;
cairo_t * back_cairo ;
2026-03-22 16:15:50 -07:00
/* The cairo to actually use for draw operations. Typically is front_cairo, but MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
2026-03-23 12:05:32 -07:00
cairo_t * selected_cairo ;
2025-12-09 20:11:01 -06:00
} ;
struct _MwLLWaylandColor {
struct _MwLLCommonColor common ;
} ;
struct _MwLLWaylandPixmap {
struct _MwLLCommonPixmap common ;
2025-12-17 19:14:54 -07:00
cairo_surface_t * cs ;
2025-12-09 20:11:01 -06:00
} ;
2026-05-04 21:07:39 -07:00
/* Setup the framebuffer with the saved width/height */
void MwLLWaylandFramebufferSetup ( struct _MwLLWayland * wayland ) ;
/* Destroy the framebuffer */
void MwLLWaylandFramebufferDestroy ( struct _MwLLWayland * handle ) ;
/* Setup the framebuffer with the saved width/height */
void MwLLWaylandBackbufferSetup ( struct _MwLLWayland * wayland ) ;
/* Destroy the backbuffer */
void MwLLWaylandBackbufferDestroy ( struct _MwLLWayland * handle ) ;
void MwLLWaylandBufferSetup ( struct _MwLLWaylandShmBuffer * buffer , MwU32 width , MwU32 height ) ;
void MwLLWaylandBufferUpdate ( MwLL self , struct _MwLLWaylandShmBuffer * buffer ) ;
void MwLLWaylandBufferDestroy ( struct _MwLLWaylandShmBuffer * buffer ) ;
void MwLLWaylandRegionSetup ( MwLL handle ) ;
void MwLLWaylandRegionInvalidate ( MwLL handle ) ;
void MwLLWaylandHangUntilConfigured ( MwLL handle ) ;
MwBool MwLLWaylandWidgetIsDestroyed ( MwLL self ) ;
void MwLLWaylandWidgetUndestroy ( MwLL self ) ;
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
void MwLLWaylandSetupCallbacks ( struct _MwLLWayland * wayland ) ;
void MwLLWaylandClipboardRead ( wl_clipboard_device_context_t * ctx , int clipboard_type ) ;
/* Flush Wayland events */
void MwLLWaylandFlush ( MwLL handle ) ;
/* Standard procedure before event callbacks in Wayland */
# define WAYLAND_EVENT_OP_START(self) \
if ( MwLLWaylandWidgetIsDestroyed ( self ) ) { \
return ; \
}
/* Footer for WAYLAND_EVENT_OP_START */
# define WAYLAND_EVENT_OP_END(self)
# define WIDGET_CHECK(handle) \
if ( ! handle - > wayland . valid ) { \
return ; \
}
/* the two decoration manager constructs */
typedef struct zxdg_decoration_manager_v1_context {
struct zxdg_decoration_manager_v1 * manager ;
struct zxdg_toplevel_decoration_v1 * decoration ;
} zxdg_decoration_manager_v1_context_t ;
extern struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener ;
2025-12-09 20:11:01 -06:00
# endif