2025-12-09 20:11:01 -06:00
/*!
* @ file Mw / LowLevel / Wayland . h
* @ brief Work in progress Wayland Backend
* @ warning This is used internally .
* @ warning This is disabled by default .
*/
# ifndef __MW_LOWLEVEL_WAYLAND_H__
# define __MW_LOWLEVEL_WAYLAND_H__
2026-01-12 19:21:21 -07:00
# include "Mw/BaseTypes.h"
2025-12-09 20:11:01 -06:00
# include <Mw/MachDep.h>
# include <Mw/TypeDefs.h>
# include <Mw/LowLevel.h>
# include <wayland-client-protocol.h>
# include <wayland-client.h>
# 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
MWDECL int MwLLWaylandCallInit ( void ) ;
# ifndef WL_PROTOCOLS_DEFINED
# define WL_PROTOCOLS_DEFINED
# 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"
2025-12-18 18:21:57 -07:00
# include "Wayland/xdg-toplevel-icon-client-protocol.h"
2025-12-09 20:11:01 -06:00
# endif
2026-03-20 19:28:18 -07:00
# define CSD_BORDER_FRAME_LEFT 5
# define CSD_BORDER_FRAME_RIGHT 5
# define CSD_BORDER_FRAME_TOP 24
# define CSD_BORDER_FRAME_BOTTOM 5
2026-03-19 19:43:57 -07:00
2026-03-20 19:28:18 -07:00
# 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
2026-03-19 19:43:57 -07:00
2025-12-09 20:11:01 -06:00
struct _MwLLWayland ;
typedef struct wayland_protocol {
void * listener ;
void * context ;
} wayland_protocol_t ;
typedef wayland_protocol_t * ( wl_setup_func ) ( MwU32 , struct _MwLLWayland * ) ;
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 ;
struct xkb_context * xkb_context ;
struct xkb_keymap * xkb_keymap ;
struct xkb_state * xkb_state ;
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
struct xdg_surface * parent_xdg_surface ;
} ;
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
} ;
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 ;
struct wl_surface * surface ;
2025-12-18 13:43:45 -07:00
struct wl_output * output ;
MwU8 * buf ;
MwU64 buf_size ;
int fd ;
MwBool setup ;
2025-12-18 13:15:03 -07:00
} ;
2025-12-18 23:32:51 -07:00
enum _MwLLWaylandType {
MWLL_WAYLAND_UNKNOWN = 0 ,
MWLL_WAYLAND_TOPLEVEL ,
MWLL_WAYLAND_SUBLEVEL ,
MWLL_WAYLAND_POPUP ,
} ;
2025-12-30 17:12:12 -07:00
typedef struct wl_clipboard_device_context {
union {
struct wl_data_device * wl ;
struct zwp_primary_selection_device_v1 * zwp ;
} device ;
union {
struct wl_data_offer * wl ;
struct zwp_primary_selection_offer_v1 * zwp ;
} offer ;
MwLL ll ;
struct wl_seat * seat ;
MwU32 capabilities ;
} 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 ;
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-03-23 12:05:32 -07:00
MwBool detatching ;
MwPoint detach_point ;
2025-12-09 20:11:01 -06:00
/* Map of Wayland interfaces to their relevant setup functions. */
struct {
2025-12-18 23:32:51 -07:00
const char * key ;
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 {
const char * key ;
wayland_protocol_t * value ;
} * wl_protocol_map ;
2025-12-30 19:16:01 -07:00
MwBool always_render ;
2026-03-19 19:43:57 -07:00
MwBool has_decorations ;
char title [ 255 ] ;
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 ;
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 . */
union {
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 ;
uint32_t clipboard_serial ;
wl_clipboard_device_context_t * * clipboard_devices ;
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 */
2025-12-09 20:11:01 -06:00
2025-12-18 13:43:45 -07:00
MwU32 mw , mh ; /* Monitor width and height as advertised by wl_output.mode */
2025-12-18 23:32:51 -07:00
MwLL parent ;
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
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-01-03 18:27:34 -07:00
/*
Events mutex . Any time a keyboard / mouse event happens , we try to lock this for 100 milliseconds , then give up if we can ' t do it . This is used in conjunction with some code in the MwLLDestroyImpl to make sure that destroy is NEVER interferes with an ongoing event .
IOI_XD : This sounds like a hilariously rare edge case , so it ' s almost funnier that this happened with 100 % certainty for me and I spent day ( s ) trying to figure out what was happening . */
pthread_mutex_t eventsMutex ;
2026-01-12 18:18:05 -07:00
uint32_t last_time ;
2026-03-19 19:43:57 -07:00
MwBool moving ;
2026-03-18 23:01:39 -07:00
struct wl_surface * curSurface ;
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
} ;
# endif