#pragma once #include #include #include #include #include #include /* Wayland protocols */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "cursor-shape.h" #include "fdm.h" /* Forward declarations */ struct terminal; struct buffer; /* Mime-types we support when dealing with data offers (e.g. copy-paste, or DnD) */ enum data_offer_mime_type { DATA_OFFER_MIME_UNSET, DATA_OFFER_MIME_TEXT_PLAIN, DATA_OFFER_MIME_TEXT_UTF8, DATA_OFFER_MIME_URI_LIST, DATA_OFFER_MIME_TEXT_TEXT, DATA_OFFER_MIME_TEXT_STRING, DATA_OFFER_MIME_TEXT_UTF8_STRING, }; enum touch_state { TOUCH_STATE_INHIBITED = -1, TOUCH_STATE_IDLE, TOUCH_STATE_HELD, TOUCH_STATE_DRAGGING, TOUCH_STATE_SCROLLING, }; struct wayl_surface { struct wl_surface *surf; struct wp_viewport *viewport; struct wp_color_management_surface_v1 *color_management; }; struct wayl_sub_surface { struct wayl_surface surface; struct wl_subsurface *sub; }; struct wl_window; struct wl_clipboard { struct wl_window *window; /* For DnD */ struct wl_data_source *data_source; struct wl_data_offer *data_offer; enum data_offer_mime_type mime_type; char *text; uint32_t serial; }; struct wl_primary { struct zwp_primary_selection_source_v1 *data_source; struct zwp_primary_selection_offer_v1 *data_offer; enum data_offer_mime_type mime_type; char *text; uint32_t serial; }; /* Maps a mouse button to its "owning" surface */ struct button_tracker { int button; int surf_kind; /* TODO: this is really an "enum term_surface" */ bool send_to_client; /* Only valid when surface is the main grid surface */ }; struct rect { int x; int y; int width; int height; }; struct seat { struct wayland *wayl; struct wl_seat *wl_seat; uint32_t wl_name; char *name; /* Focused terminals */ struct terminal *kbd_focus; struct terminal *mouse_focus; struct terminal *ime_focus; /* Keyboard state */ struct wl_keyboard *wl_keyboard; struct { uint32_t serial; struct xkb_context *xkb; struct xkb_keymap *xkb_keymap; struct xkb_state *xkb_state; struct xkb_compose_table *xkb_compose_table; struct xkb_compose_state *xkb_compose_state; struct { int fd; bool dont_re_repeat; int32_t delay; int32_t rate; uint32_t key; } repeat; xkb_mod_index_t mod_shift; xkb_mod_index_t mod_alt; xkb_mod_index_t mod_ctrl; xkb_mod_index_t mod_super; xkb_mod_index_t mod_caps; xkb_mod_index_t mod_num; xkb_mod_mask_t legacy_significant; /* Significant modifiers for the legacy keyboard protocol */ xkb_mod_mask_t kitty_significant; /* Significant modifiers for the kitty keyboard protocol */ xkb_mod_mask_t virtual_modifiers; /* Set of modifiers to completely ignore */ xkb_keycode_t key_arrow_up; xkb_keycode_t key_arrow_down; /* Enabled modifiers */ bool shift; bool alt; bool ctrl; bool super; } kbd; /* Pointer state */ struct wl_pointer *wl_pointer; struct { uint32_t serial; /* Client-side cursor */ struct wayl_surface surface; struct wl_cursor_theme *theme; struct wl_cursor *cursor; /* Server-side cursor */ struct wp_cursor_shape_device_v1 *shape_device; float scale; bool hidden; enum cursor_shape shape; char *last_custom_xcursor; struct wl_callback *xcursor_callback; bool xcursor_pending; } pointer; /* Touch state */ struct wl_touch *wl_touch; struct { enum touch_state state; uint32_t serial; uint32_t time; struct wl_surface *surface; int surface_kind; int32_t id; } touch; struct { int x; int y; int col; int row; /* Mouse buttons currently being pressed, and their "owning" surfaces */ tll(struct button_tracker) buttons; /* Double- and triple click state */ int count; int last_released_button; struct timespec last_time; /* We used a discrete axis event in the current pointer frame */ double aggregated[2]; double aggregated_120[2]; bool have_discrete; } mouse; /* Clipboard */ struct wl_data_device *data_device; struct zwp_primary_selection_device_v1 *primary_selection_device; struct wl_clipboard clipboard; struct wl_primary primary; #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED /* Input Method Editor */ struct zwp_text_input_v3 *wl_text_input; struct { struct { struct rect pending; struct rect sent; } cursor_rect; struct { struct { char *text; int32_t cursor_begin; int32_t cursor_end; } pending; char32_t *text; struct cell *cells; int count; struct { bool hidden; int start; /* Cell index, inclusive */ int end; /* Cell index, exclusive */ } cursor; } preedit; struct { struct { char *text; } pending; } commit; struct { struct { uint32_t before_length; uint32_t after_length; } pending; } surrounding; uint32_t serial; } ime; #endif }; enum csd_surface { CSD_SURF_TITLE, CSD_SURF_LEFT, CSD_SURF_RIGHT, CSD_SURF_TOP, CSD_SURF_BOTTOM, CSD_SURF_MINIMIZE, CSD_SURF_MAXIMIZE, CSD_SURF_CLOSE, CSD_SURF_COUNT, }; struct monitor { struct wayland *wayl; struct wl_output *output; struct zxdg_output_v1 *xdg; uint32_t wl_name; int x; int y; struct { /* Physical size, in mm */ struct { int width; int height; } mm; /* Physical size, in pixels */ struct { int width; int height; } px_real; /* Scaled size, in pixels */ struct { int width; int height; } px_scaled; } dim; struct { /* PPI, based on physical size */ struct { int x; int y; } real; /* PPI, logical, based on scaled size */ struct { int x; int y; } scaled; } ppi; struct { float scaled; float physical; } dpi; int scale; float refresh; enum wl_output_subpixel subpixel; enum wl_output_transform transform; /* From wl_output */ char *make; char *model; /* From xdg_output */ char *name; char *description; float inch; /* e.g. 24" */ bool use_output_release; }; struct wl_url { const struct url *url; struct wayl_sub_surface surf; }; enum csd_mode {CSD_UNKNOWN, CSD_NO, CSD_YES}; typedef void (*activation_token_cb_t)(const char *token, void *data); /* * This context holds data used both in the token::done callback, and * when cleaning up created, by not-yet-done tokens in * wayl_win_destroy(). */ struct xdg_activation_token_context { struct wl_window *win; /* Need for win->xdg_tokens */ struct xdg_activation_token_v1 *xdg_token; /* Used to match token in done() */ activation_token_cb_t cb; /* User provided callback */ void *cb_data; /* Callback user pointer */ }; struct wayland; struct wl_window { struct terminal *term; struct wayl_surface surface; struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; struct wp_fractional_scale_v1 *fractional_scale; tll(struct xdg_activation_token_context *) xdg_tokens; bool urgency_token_is_pending; bool unmapped; float scale; int preferred_buffer_scale; struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration; enum csd_mode csd_mode; struct { struct wayl_sub_surface surface[CSD_SURF_COUNT]; struct fcft_font *font; int move_timeout_fd; uint32_t serial; } csd; struct { bool maximize:1; bool minimize:1; } wm_capabilities; struct wayl_sub_surface search; struct wayl_sub_surface scrollback_indicator; struct wayl_sub_surface render_timer; struct wayl_sub_surface overlay; struct wl_callback *frame_callback; tll(const struct monitor *) on_outputs; /* Outputs we're mapped on */ tll(struct wl_url) urls; bool is_configured; bool is_fullscreen; bool is_maximized; bool is_resizing; bool is_tiled_top; bool is_tiled_bottom; bool is_tiled_left; bool is_tiled_right; bool is_tiled; /* At least one of is_tiled_{top,bottom,left,right} is true */ bool is_constrained_top; bool is_constrained_bottom; bool is_constrained_left; bool is_constrained_right; struct { int width; int height; bool is_activated:1; bool is_fullscreen:1; bool is_maximized:1; bool is_resizing:1; bool is_tiled_top:1; bool is_tiled_bottom:1; bool is_tiled_left:1; bool is_tiled_right:1; bool is_constrained_top:1; bool is_constrained_bottom:1; bool is_constrained_left:1; bool is_constrained_right:1; enum csd_mode csd_mode; } configure; int resize_timeout_fd; }; struct terminal; struct wayland { struct fdm *fdm; struct key_binding_manager *key_binding_manager; int fd; struct wl_display *display; struct wl_registry *registry; struct wl_compositor *compositor; struct wl_subcompositor *sub_compositor; struct wl_shm *shm; struct zxdg_output_manager_v1 *xdg_output_manager; struct xdg_wm_base *shell; struct zxdg_decoration_manager_v1 *xdg_decoration_manager; struct wl_data_device_manager *data_device_manager; struct zwp_primary_selection_device_manager_v1 *primary_selection_device_manager; struct xdg_activation_v1 *xdg_activation; struct wp_viewporter *viewporter; struct wp_fractional_scale_manager_v1 *fractional_scale_manager; struct wp_cursor_shape_manager_v1 *cursor_shape_manager; int shape_manager_version; struct wp_single_pixel_buffer_manager_v1 *single_pixel_manager; struct xdg_toplevel_icon_manager_v1 *toplevel_icon_manager; struct xdg_system_bell_v1 *system_bell; struct { struct wp_color_manager_v1 *manager; struct wp_image_description_v1 *img_description; bool have_intent_perceptual; bool have_feat_parametric; bool have_tf_ext_linear; bool have_primaries_srgb; } color_management; bool presentation_timings; struct wp_presentation *presentation; uint32_t presentation_clock_id; #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED struct zwp_text_input_manager_v3 *text_input_manager; #endif tll(struct monitor) monitors; /* All available outputs */ tll(struct seat) seats; tll(struct terminal *) terms; /* WL_SHM >= 2 */ bool use_shm_release; bool shm_have_argb2101010:1; bool shm_have_xrgb2101010:1; bool shm_have_abgr2101010:1; bool shm_have_xbgr2101010:1; bool shm_have_abgr161616:1; bool shm_have_xbgr161616:1; }; struct wayland *wayl_init( struct fdm *fdm, struct key_binding_manager *key_binding_manager, bool presentation_timings); void wayl_destroy(struct wayland *wayl); bool wayl_reload_xcursor_theme(struct seat *seat, float new_scale); void wayl_flush(struct wayland *wayl); void wayl_roundtrip(struct wayland *wayl); bool wayl_fractional_scaling(const struct wayland *wayl); void wayl_surface_scale( const struct wl_window *win, const struct wayl_surface *surf, const struct buffer *buf, float scale); void wayl_surface_scale_explicit_width_height( const struct wl_window *win, const struct wayl_surface *surf, int width, int height, float scale); struct wl_window *wayl_win_init(struct terminal *term, const char *token); void wayl_win_destroy(struct wl_window *win); void wayl_win_scale(struct wl_window *win, const struct buffer *buf); void wayl_win_alpha_changed(struct wl_window *win); bool wayl_win_set_urgent(struct wl_window *win); bool wayl_win_ring_bell(const struct wl_window *win); bool wayl_win_csd_titlebar_visible(const struct wl_window *win); bool wayl_win_csd_borders_visible(const struct wl_window *win); bool wayl_win_subsurface_new( struct wl_window *win, struct wayl_sub_surface *surf, bool allow_pointer_input); bool wayl_win_subsurface_new_with_custom_parent( struct wl_window *win, struct wl_surface *parent, struct wayl_sub_surface *surf, bool allow_pointer_input); void wayl_win_subsurface_destroy(struct wayl_sub_surface *surf); bool wayl_get_activation_token( struct wayland *wayl, struct seat *seat, uint32_t serial, struct wl_window *win, activation_token_cb_t cb, void *cb_data); void wayl_activate(struct wayland *wayl, struct wl_window *win, const char *token); bool wayl_do_linear_blending(const struct wayland *wayl, const struct config *conf);