1 #pragma once 2 3 #include <stdint.h> 4 #include <stdbool.h> 5 6 #include <sys/time.h> 7 8 #include <wayland-client.h> 9 #include <xkbcommon/xkbcommon.h> 10 11 /* Wayland protocols */ 12 #include <presentation-time.h> 13 #include <primary-selection-unstable-v1.h> 14 #include <text-input-unstable-v3.h> 15 #include <xdg-decoration-unstable-v1.h> 16 #include <xdg-output-unstable-v1.h> 17 #include <xdg-shell.h> 18 19 #if defined(HAVE_XDG_ACTIVATION) 20 #include <xdg-activation-v1.h> 21 #endif 22 23 #include <fcft/fcft.h> 24 #include <tllist.h> 25 26 #include "fdm.h" 27 28 /* Forward declarations */ 29 struct terminal; 30 31 enum bind_action_normal { 32 BIND_ACTION_NONE, 33 BIND_ACTION_NOOP, 34 BIND_ACTION_SCROLLBACK_UP_PAGE, 35 BIND_ACTION_SCROLLBACK_UP_HALF_PAGE, 36 BIND_ACTION_SCROLLBACK_UP_LINE, 37 BIND_ACTION_SCROLLBACK_DOWN_PAGE, 38 BIND_ACTION_SCROLLBACK_DOWN_HALF_PAGE, 39 BIND_ACTION_SCROLLBACK_DOWN_LINE, 40 BIND_ACTION_CLIPBOARD_COPY, 41 BIND_ACTION_CLIPBOARD_PASTE, 42 BIND_ACTION_PRIMARY_PASTE, 43 BIND_ACTION_SEARCH_START, 44 BIND_ACTION_FONT_SIZE_UP, 45 BIND_ACTION_FONT_SIZE_DOWN, 46 BIND_ACTION_FONT_SIZE_RESET, 47 BIND_ACTION_SPAWN_TERMINAL, 48 BIND_ACTION_MINIMIZE, 49 BIND_ACTION_MAXIMIZE, 50 BIND_ACTION_FULLSCREEN, 51 BIND_ACTION_PIPE_SCROLLBACK, 52 BIND_ACTION_PIPE_VIEW, 53 BIND_ACTION_PIPE_SELECTED, 54 BIND_ACTION_SHOW_URLS_COPY, 55 BIND_ACTION_SHOW_URLS_LAUNCH, 56 57 /* Mouse specific actions - i.e. they require a mouse coordinate */ 58 BIND_ACTION_SELECT_BEGIN, 59 BIND_ACTION_SELECT_BEGIN_BLOCK, 60 BIND_ACTION_SELECT_EXTEND, 61 BIND_ACTION_SELECT_EXTEND_CHAR_WISE, 62 BIND_ACTION_SELECT_WORD, 63 BIND_ACTION_SELECT_WORD_WS, 64 BIND_ACTION_SELECT_ROW, 65 66 BIND_ACTION_KEY_COUNT = BIND_ACTION_SHOW_URLS_LAUNCH + 1, 67 BIND_ACTION_COUNT = BIND_ACTION_SELECT_ROW + 1, 68 }; 69 70 enum bind_action_search { 71 BIND_ACTION_SEARCH_NONE, 72 BIND_ACTION_SEARCH_CANCEL, 73 BIND_ACTION_SEARCH_COMMIT, 74 BIND_ACTION_SEARCH_FIND_PREV, 75 BIND_ACTION_SEARCH_FIND_NEXT, 76 BIND_ACTION_SEARCH_EDIT_LEFT, 77 BIND_ACTION_SEARCH_EDIT_LEFT_WORD, 78 BIND_ACTION_SEARCH_EDIT_RIGHT, 79 BIND_ACTION_SEARCH_EDIT_RIGHT_WORD, 80 BIND_ACTION_SEARCH_EDIT_HOME, 81 BIND_ACTION_SEARCH_EDIT_END, 82 BIND_ACTION_SEARCH_DELETE_PREV, 83 BIND_ACTION_SEARCH_DELETE_PREV_WORD, 84 BIND_ACTION_SEARCH_DELETE_NEXT, 85 BIND_ACTION_SEARCH_DELETE_NEXT_WORD, 86 BIND_ACTION_SEARCH_EXTEND_WORD, 87 BIND_ACTION_SEARCH_EXTEND_WORD_WS, 88 BIND_ACTION_SEARCH_CLIPBOARD_PASTE, 89 BIND_ACTION_SEARCH_PRIMARY_PASTE, 90 BIND_ACTION_SEARCH_COUNT, 91 }; 92 93 enum bind_action_url { 94 BIND_ACTION_URL_NONE, 95 BIND_ACTION_URL_CANCEL, 96 BIND_ACTION_URL_TOGGLE_URL_ON_JUMP_LABEL, 97 BIND_ACTION_URL_COUNT, 98 }; 99 100 typedef tll(xkb_keycode_t) xkb_keycode_list_t; 101 102 struct key_binding { 103 xkb_mod_mask_t mods; 104 xkb_keysym_t sym; 105 xkb_keycode_list_t key_codes; 106 107 int action; /* enum bind_action_* */ 108 char **pipe_argv; 109 }; 110 typedef tll(struct key_binding) key_binding_list_t; 111 112 struct mouse_binding { 113 enum bind_action_normal action; 114 xkb_mod_mask_t mods; 115 uint32_t button; 116 int count; 117 char **pipe_argv; 118 }; 119 typedef tll(struct mouse_binding) mouse_binding_list_t; 120 121 /* Mime-types we support when dealing with data offers (e.g. copy-paste, or DnD) */ 122 enum data_offer_mime_type { 123 DATA_OFFER_MIME_UNSET, 124 DATA_OFFER_MIME_TEXT_PLAIN, 125 DATA_OFFER_MIME_TEXT_UTF8, 126 DATA_OFFER_MIME_URI_LIST, 127 128 DATA_OFFER_MIME_TEXT_TEXT, 129 DATA_OFFER_MIME_TEXT_STRING, 130 DATA_OFFER_MIME_TEXT_UTF8_STRING, 131 }; 132 133 struct wl_window; 134 struct wl_clipboard { 135 struct wl_window *window; /* For DnD */ 136 struct wl_data_source *data_source; 137 struct wl_data_offer *data_offer; 138 enum data_offer_mime_type mime_type; 139 char *text; 140 uint32_t serial; 141 }; 142 143 struct wl_primary { 144 struct zwp_primary_selection_source_v1 *data_source; 145 struct zwp_primary_selection_offer_v1 *data_offer; 146 enum data_offer_mime_type mime_type; 147 char *text; 148 uint32_t serial; 149 }; 150 151 /* Maps a mouse button to its "owning" surface */ 152 struct button_tracker { 153 int button; 154 int surf_kind; /* TODO: this is really an "enum term_surface" */ 155 bool send_to_client; /* Only valid when surface is the main grid surface */ 156 }; 157 158 struct rect { 159 int x; 160 int y; 161 int width; 162 int height; 163 }; 164 165 struct seat { 166 struct wayland *wayl; 167 struct wl_seat *wl_seat; 168 uint32_t wl_name; 169 char *name; 170 171 /* Focused terminals */ 172 struct terminal *kbd_focus; 173 struct terminal *mouse_focus; 174 175 /* Keyboard state */ 176 struct wl_keyboard *wl_keyboard; 177 struct { 178 uint32_t serial; 179 180 struct xkb_context *xkb; 181 struct xkb_keymap *xkb_keymap; 182 struct xkb_state *xkb_state; 183 struct xkb_compose_table *xkb_compose_table; 184 struct xkb_compose_state *xkb_compose_state; 185 struct { 186 int fd; 187 188 bool dont_re_repeat; 189 int32_t delay; 190 int32_t rate; 191 uint32_t key; 192 } repeat; 193 194 xkb_mod_index_t mod_shift; 195 xkb_mod_index_t mod_alt; 196 xkb_mod_index_t mod_ctrl; 197 xkb_mod_index_t mod_super; 198 xkb_mod_index_t mod_caps; 199 xkb_mod_index_t mod_num; 200 201 xkb_mod_mask_t bind_significant; 202 xkb_mod_mask_t kitty_significant; 203 204 xkb_keycode_t key_arrow_up; 205 xkb_keycode_t key_arrow_down; 206 207 /* Enabled modifiers */ 208 bool shift; 209 bool alt; 210 bool ctrl; 211 bool super; 212 213 struct { 214 key_binding_list_t key; 215 key_binding_list_t search; 216 key_binding_list_t url; 217 } bindings; 218 } kbd; 219 220 /* Pointer state */ 221 struct wl_pointer *wl_pointer; 222 struct { 223 uint32_t serial; 224 225 struct wl_surface *surface; 226 struct wl_cursor_theme *theme; 227 struct wl_cursor *cursor; 228 int scale; 229 bool hidden; 230 231 const char *xcursor; 232 struct wl_callback *xcursor_callback; 233 bool xcursor_pending; 234 } pointer; 235 236 struct { 237 int x; 238 int y; 239 int col; 240 int row; 241 242 /* Mouse buttons currently being pressed, and their "owning" surfaces */ 243 tll(struct button_tracker) buttons; 244 245 /* Double- and triple click state */ 246 int count; 247 int last_released_button; 248 struct timeval last_time; 249 250 /* We used a discrete axis event in the current pointer frame */ 251 double aggregated[2]; 252 bool have_discrete; 253 254 mouse_binding_list_t bindings; 255 } mouse; 256 257 /* Clipboard */ 258 struct wl_data_device *data_device; 259 struct zwp_primary_selection_device_v1 *primary_selection_device; 260 261 struct wl_clipboard clipboard; 262 struct wl_primary primary; 263 264 #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED 265 /* Input Method Editor */ 266 struct zwp_text_input_v3 *wl_text_input; 267 struct { 268 struct { 269 struct rect pending; 270 struct rect sent; 271 } cursor_rect; 272 273 struct { 274 struct { 275 char *text; 276 int32_t cursor_begin; 277 int32_t cursor_end; 278 } pending; 279 280 wchar_t *text; 281 struct cell *cells; 282 int count; 283 struct { 284 bool hidden; 285 int start; /* Cell index, inclusive */ 286 int end; /* Cell index, exclusive */ 287 } cursor; 288 } preedit; 289 290 struct { 291 struct { 292 char *text; 293 } pending; 294 } commit; 295 296 struct { 297 struct { 298 uint32_t before_length; 299 uint32_t after_length; 300 } pending; 301 } surrounding; 302 303 bool focused; 304 uint32_t serial; 305 } ime; 306 #endif 307 }; 308 309 enum csd_surface { 310 CSD_SURF_TITLE, 311 CSD_SURF_LEFT, 312 CSD_SURF_RIGHT, 313 CSD_SURF_TOP, 314 CSD_SURF_BOTTOM, 315 CSD_SURF_MINIMIZE, 316 CSD_SURF_MAXIMIZE, 317 CSD_SURF_CLOSE, 318 CSD_SURF_COUNT, 319 }; 320 321 struct monitor { 322 struct wayland *wayl; 323 struct wl_output *output; 324 struct zxdg_output_v1 *xdg; 325 uint32_t wl_name; 326 327 int x; 328 int y; 329 330 struct { 331 /* Physical size, in mm */ 332 struct { 333 int width; 334 int height; 335 } mm; 336 337 /* Physical size, in pixels */ 338 struct { 339 int width; 340 int height; 341 } px_real; 342 343 /* Scaled size, in pixels */ 344 struct { 345 int width; 346 int height; 347 } px_scaled; 348 } dim; 349 350 struct { 351 /* PPI, based on physical size */ 352 struct { 353 int x; 354 int y; 355 } real; 356 357 /* PPI, logical, based on scaled size */ 358 struct { 359 int x; 360 int y; 361 } scaled; 362 } ppi; 363 364 float dpi; 365 366 int scale; 367 float refresh; 368 enum wl_output_subpixel subpixel; 369 enum wl_output_transform transform; 370 371 /* From wl_output */ 372 char *make; 373 char *model; 374 375 /* From xdg_output */ 376 char *name; 377 char *description; 378 379 float inch; /* e.g. 24" */ 380 381 bool use_output_release; 382 }; 383 384 struct wl_surf_subsurf { 385 struct wl_surface *surf; 386 struct wl_subsurface *sub; 387 }; 388 389 struct wl_url { 390 const struct url *url; 391 struct wl_surf_subsurf surf; 392 }; 393 394 enum csd_mode {CSD_UNKNOWN, CSD_NO, CSD_YES}; 395 396 struct wayland; 397 struct wl_window { 398 struct terminal *term; 399 struct wl_surface *surface; 400 struct xdg_surface *xdg_surface; 401 struct xdg_toplevel *xdg_toplevel; 402 #if defined(HAVE_XDG_ACTIVATION) 403 struct xdg_activation_token_v1 *xdg_activation_token; 404 #endif 405 406 struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration; 407 408 enum csd_mode csd_mode; 409 410 struct { 411 struct wl_surf_subsurf surface[CSD_SURF_COUNT]; 412 struct fcft_font *font; 413 int move_timeout_fd; 414 uint32_t serial; 415 } csd; 416 417 struct wl_surf_subsurf search; 418 struct wl_surf_subsurf scrollback_indicator; 419 struct wl_surf_subsurf render_timer; 420 421 struct wl_callback *frame_callback; 422 423 tll(const struct monitor *) on_outputs; /* Outputs we're mapped on */ 424 tll(struct wl_url) urls; 425 426 bool is_configured; 427 bool is_fullscreen; 428 bool is_maximized; 429 bool is_resizing; 430 bool is_tiled_top; 431 bool is_tiled_bottom; 432 bool is_tiled_left; 433 bool is_tiled_right; 434 bool is_tiled; /* At least one of is_tiled_{top,bottom,left,right} is true */ 435 struct { 436 int width; 437 int height; 438 bool is_activated:1; 439 bool is_fullscreen:1; 440 bool is_maximized:1; 441 bool is_resizing:1; 442 bool is_tiled_top:1; 443 bool is_tiled_bottom:1; 444 bool is_tiled_left:1; 445 bool is_tiled_right:1; 446 enum csd_mode csd_mode; 447 } configure; 448 449 int resize_timeout_fd; 450 }; 451 452 struct config; 453 struct terminal; 454 struct wayland { 455 const struct config *conf; 456 struct fdm *fdm; 457 458 int fd; 459 460 struct wl_display *display; 461 struct wl_registry *registry; 462 struct wl_compositor *compositor; 463 struct wl_subcompositor *sub_compositor; 464 struct wl_shm *shm; 465 466 struct zxdg_output_manager_v1 *xdg_output_manager; 467 468 struct xdg_wm_base *shell; 469 struct zxdg_decoration_manager_v1 *xdg_decoration_manager; 470 471 struct wl_data_device_manager *data_device_manager; 472 struct zwp_primary_selection_device_manager_v1 *primary_selection_device_manager; 473 474 #if defined(HAVE_XDG_ACTIVATION) 475 struct xdg_activation_v1 *xdg_activation; 476 #endif 477 478 struct wp_presentation *presentation; 479 uint32_t presentation_clock_id; 480 481 #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED 482 struct zwp_text_input_manager_v3 *text_input_manager; 483 #endif 484 485 bool have_argb8888; 486 tll(struct monitor) monitors; /* All available outputs */ 487 tll(struct seat) seats; 488 489 tll(struct terminal *) terms; 490 }; 491 492 struct wayland *wayl_init(const struct config *conf, struct fdm *fdm); 493 void wayl_destroy(struct wayland *wayl); 494 495 bool wayl_reload_xcursor_theme(struct seat *seat, int new_scale); 496 497 void wayl_flush(struct wayland *wayl); 498 void wayl_roundtrip(struct wayland *wayl); 499 500 struct wl_window *wayl_win_init(struct terminal *term, const char *token); 501 void wayl_win_destroy(struct wl_window *win); 502 503 bool wayl_win_set_urgent(struct wl_window *win); 504 505 bool wayl_win_subsurface_new( 506 struct wl_window *win, struct wl_surf_subsurf *surf); 507 bool wayl_win_subsurface_new_with_custom_parent( 508 struct wl_window *win, struct wl_surface *parent, 509 struct wl_surf_subsurf *surf); 510 void wayl_win_subsurface_destroy(struct wl_surf_subsurf *surf); 511