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