1 #pragma once
2 
3 #include <stdint.h>
4 #include <stdbool.h>
5 #include <stddef.h>
6 #include <wchar.h>
7 
8 #include <threads.h>
9 #include <semaphore.h>
10 
11 #if defined(FOOT_GRAPHEME_CLUSTERING)
12  #include <utf8proc.h>
13 #endif
14 
15 #include <tllist.h>
16 #include <fcft/fcft.h>
17 
18 //#include "config.h"
19 #include "composed.h"
20 #include "debug.h"
21 #include "fdm.h"
22 #include "macros.h"
23 #include "reaper.h"
24 #include "shm.h"
25 #include "wayland.h"
26 
27 enum color_source {
28     COLOR_DEFAULT,
29     COLOR_BASE16,
30     COLOR_BASE256,
31     COLOR_RGB,
32 };
33 
34 /*
35  *  Note: we want the cells to be as small as possible. Larger cells
36  *  means fewer scrollback lines (or performance drops due to cache
37  *  misses)
38  *
39  * Note that the members are laid out optimized for x86
40  */
41 struct attributes {
42     bool bold:1;
43     bool dim:1;
44     bool italic:1;
45     bool underline:1;
46     bool strikethrough:1;
47     bool blink:1;
48     bool conceal:1;
49     bool reverse:1;
50     uint32_t fg:24;
51 
52     bool clean:1;
53     enum color_source fg_src:2;
54     enum color_source bg_src:2;
55     bool confined:1;
56     bool selected:1;
57     bool url:1;
58     uint32_t bg:24;
59 };
60 static_assert(sizeof(struct attributes) == 8, "VT attribute struct too large");
61 
62 /* Last valid Unicode code point is 0x0010FFFFul */
63 #define CELL_COMB_CHARS_LO          0x00200000ul
64 #define CELL_COMB_CHARS_HI          (CELL_COMB_CHARS_LO + 0x3fffffff)
65 #define CELL_SPACER                 (CELL_COMB_CHARS_HI + 1)
66 
67 struct cell {
68     wchar_t wc;
69     struct attributes attrs;
70 };
71 static_assert(sizeof(struct cell) == 12, "bad size");
72 
73 struct scroll_region {
74     int start;
75     int end;
76 };
77 
78 struct coord {
79     int col;
80     int row;
81 };
82 
83 struct cursor {
84     struct coord point;
85     bool lcf;
86 };
87 
88 enum damage_type {DAMAGE_SCROLL, DAMAGE_SCROLL_REVERSE,
89                   DAMAGE_SCROLL_IN_VIEW, DAMAGE_SCROLL_REVERSE_IN_VIEW};
90 
91 struct damage {
92     enum damage_type type;
93     struct scroll_region region;
94     int lines;
95 };
96 
97 struct row_uri_range {
98     int start;
99     int end;
100     uint64_t id;
101     char *uri;
102 };
103 
104 struct row_data {
105     struct {
106         struct row_uri_range *v;
107         uint32_t size;
108         uint32_t count;
109     } uri_ranges;
110 };
111 
112 struct row {
113     struct cell *cells;
114     bool dirty;
115     bool linebreak;
116     struct row_data *extra;
117 };
118 
119 struct sixel {
120     void *data;
121     pixman_image_t *pix;
122     int width;
123     int height;
124     int rows;
125     int cols;
126     struct coord pos;
127     bool opaque;
128 };
129 
130 enum kitty_kbd_flags {
131     KITTY_KBD_DISAMBIGUATE = 0x01,
132     KITTY_KBD_REPORT_EVENT = 0x02,
133     KITTY_KBD_REPORT_ALTERNATE = 0x04,
134     KITTY_KBD_REPORT_ALL = 0x08,
135     KITTY_KBD_REPORT_ASSOCIATED = 0x10,
136     KITTY_KBD_SUPPORTED = (KITTY_KBD_DISAMBIGUATE |
137                            KITTY_KBD_REPORT_EVENT |
138                            KITTY_KBD_REPORT_ALTERNATE |
139                            KITTY_KBD_REPORT_ALL |
140                            KITTY_KBD_REPORT_ASSOCIATED),
141 };
142 
143 struct grid {
144     int num_rows;
145     int num_cols;
146     int offset;
147     int view;
148 
149     /*
150      * Note: the cursor (not the *saved* cursor) could most likely be
151      * global state in the term struct.
152      *
153      * However, we have grid specific functions that does not have
154      * access to the owning term struct, but does need access to the
155      * cursor.
156      */
157     struct cursor cursor;
158     struct cursor saved_cursor;
159 
160     struct row **rows;
161     struct row *cur_row;
162 
163     tll(struct damage) scroll_damage;
164     tll(struct sixel) sixel_images;
165 
166     struct {
167         enum kitty_kbd_flags flags[8];
168         uint8_t idx;
169     } kitty_kbd;
170 
171 };
172 
173 struct vt_subparams {
174     unsigned value[16];
175     uint8_t idx;
176 };
177 
178 struct vt_param {
179     unsigned value;
180     struct vt_subparams sub;
181 };
182 
183 struct vt {
184     int state;  /* enum state */
185     wchar_t last_printed;
186 #if defined(FOOT_GRAPHEME_CLUSTERING)
187     utf8proc_int32_t grapheme_state;
188 #endif
189     wchar_t utf8;
190     struct {
191         struct vt_param v[16];
192         uint8_t idx;
193     } params;
194 
195     uint32_t private; /* LSB=priv0, MSB=priv3 */
196 
197     struct attributes attrs;
198     struct attributes saved_attrs;
199 
200     struct {
201         uint8_t *data;
202         size_t size;
203         size_t idx;
204         bool bel; /* true if OSC string was terminated by BEL */
205     } osc;
206 
207     /* Start coordinate for current OSC-8 URI */
208     struct {
209         uint64_t id;
210         char *uri;
211     } osc8;
212 
213     struct {
214         uint8_t *data;
215         size_t size;
216         size_t idx;
217         void (*put_handler)(struct terminal *term, uint8_t c);
218         void (*unhook_handler)(struct terminal *term);
219     } dcs;
220 };
221 
222 enum cursor_origin { ORIGIN_ABSOLUTE, ORIGIN_RELATIVE };
223 enum cursor_keys { CURSOR_KEYS_DONTCARE, CURSOR_KEYS_NORMAL, CURSOR_KEYS_APPLICATION };
224 enum keypad_keys { KEYPAD_DONTCARE, KEYPAD_NUMERICAL, KEYPAD_APPLICATION };
225 enum charset { CHARSET_ASCII, CHARSET_GRAPHIC };
226 enum charset_designator { G0, G1, G2, G3 };
227 
228 struct charsets {
229     enum charset_designator selected;
230     enum charset_designator saved;
231     enum charset set[4]; /* G0-G3 */
232 };
233 
234 /* *What* to report */
235 enum mouse_tracking {
236     MOUSE_NONE,
237     MOUSE_X10,           /* ?9h */
238     MOUSE_CLICK,         /* ?1000h - report mouse clicks */
239     MOUSE_DRAG,          /* ?1002h - report clicks and drag motions */
240     MOUSE_MOTION,        /* ?1003h - report clicks and motion */
241 };
242 
243 /* *How* to report */
244 enum mouse_reporting {
245     MOUSE_NORMAL,
246     MOUSE_UTF8,          /* ?1005h */
247     MOUSE_SGR,           /* ?1006h */
248     MOUSE_URXVT,         /* ?1015h */
249 };
250 
251 enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM };
252 
253 enum selection_kind {
254     SELECTION_NONE,
255     SELECTION_CHAR_WISE,
256     SELECTION_WORD_WISE,
257     SELECTION_LINE_WISE,
258     SELECTION_BLOCK
259 };
260 enum selection_direction {SELECTION_UNDIR, SELECTION_LEFT, SELECTION_RIGHT};
261 enum selection_scroll_direction {SELECTION_SCROLL_NOT, SELECTION_SCROLL_UP, SELECTION_SCROLL_DOWN};
262 
263 struct ptmx_buffer {
264     void *data;
265     size_t len;
266     size_t idx;
267 };
268 
269 enum term_surface {
270     TERM_SURF_NONE,
271     TERM_SURF_GRID,
272     TERM_SURF_SEARCH,
273     TERM_SURF_SCROLLBACK_INDICATOR,
274     TERM_SURF_RENDER_TIMER,
275     TERM_SURF_JUMP_LABEL,
276     TERM_SURF_TITLE,
277     TERM_SURF_BORDER_LEFT,
278     TERM_SURF_BORDER_RIGHT,
279     TERM_SURF_BORDER_TOP,
280     TERM_SURF_BORDER_BOTTOM,
281     TERM_SURF_BUTTON_MINIMIZE,
282     TERM_SURF_BUTTON_MAXIMIZE,
283     TERM_SURF_BUTTON_CLOSE,
284 };
285 
286 typedef tll(struct ptmx_buffer) ptmx_buffer_list_t;
287 
288 enum url_action { URL_ACTION_COPY, URL_ACTION_LAUNCH };
289 struct url {
290     uint64_t id;
291     char *url;
292     wchar_t *key;
293     struct coord start;
294     struct coord end;
295     enum url_action action;
296     bool url_mode_dont_change_url_attr; /* Entering/exiting URL mode doesn’t touch the cells’ attr.url */
297     bool osc8;
298     bool duplicate;
299 };
300 typedef tll(struct url) url_list_t;
301 
302 /* If px != 0 then px is valid, otherwise pt is valid */
303 struct pt_or_px {
304     int16_t px;
305     float pt;
306 };
307 
308 struct terminal {
309     struct fdm *fdm;
310     struct reaper *reaper;
311     const struct config *conf;
312 
313     void (*ascii_printer)(struct terminal *term, wchar_t c);
314 
315     pid_t slave;
316     int ptmx;
317 
318     struct vt vt;
319     struct grid *grid;
320     struct grid normal;
321     struct grid alt;
322 
323     int cols;   /* number of columns */
324     int rows;   /* number of rows */
325     struct scroll_region scroll_region;
326 
327     struct charsets charsets;
328     struct charsets saved_charsets; /* For save/restore cursor + attributes */
329 
330     bool auto_margin;
331     bool insert_mode;
332     bool reverse;
333     bool hide_cursor;
334     bool reverse_wrap;
335     bool bracketed_paste;
336     bool focus_events;
337     bool alt_scrolling;
338     bool modify_escape_key;
339     bool modify_other_keys_2;  /* True when modifyOtherKeys=2 (i.e. “CSI >4;2m”) */
340     enum cursor_origin origin;
341     enum cursor_keys cursor_keys_mode;
342     enum keypad_keys keypad_keys_mode;
343     enum mouse_tracking mouse_tracking;
344     enum mouse_reporting mouse_reporting;
345 
346     tll(int) tab_stops;
347 
348     size_t composed_count;
349     struct composed *composed;
350 
351     /* Temporary: for FDM */
352     struct {
353         bool is_armed;
354         int lower_fd;
355         int upper_fd;
356     } delayed_render_timer;
357 
358     struct fcft_font *fonts[4];
359     struct config_font *font_sizes[4];
360     struct pt_or_px font_line_height;
361     float font_dpi;
362     bool font_is_sized_by_dpi;
363     int16_t font_x_ofs;
364     int16_t font_y_ofs;
365     enum fcft_subpixel font_subpixel;
366 
367     struct {
368         struct fcft_glyph **box_drawing;
369         struct fcft_glyph **braille;
370         struct fcft_glyph **legacy;
371 
372         #define GLYPH_BOX_DRAWING_FIRST 0x2500
373         #define GLYPH_BOX_DRAWING_LAST  0x259F
374         #define GLYPH_BOX_DRAWING_COUNT \
375             (GLYPH_BOX_DRAWING_LAST - GLYPH_BOX_DRAWING_FIRST + 1)
376 
377         #define GLYPH_BRAILLE_FIRST 0x2800
378         #define GLYPH_BRAILLE_LAST  0x28FF
379         #define GLYPH_BRAILLE_COUNT \
380             (GLYPH_BRAILLE_LAST - GLYPH_BRAILLE_FIRST + 1)
381 
382         #define GLYPH_LEGACY_FIRST 0x1FB00
383         #define GLYPH_LEGACY_LAST  0x1FB9B
384         #define GLYPH_LEGACY_COUNT \
385             (GLYPH_LEGACY_LAST - GLYPH_LEGACY_FIRST + 1)
386     } custom_glyphs;
387 
388     bool is_sending_paste_data;
389     ptmx_buffer_list_t ptmx_buffers;
390     ptmx_buffer_list_t ptmx_paste_buffers;
391 
392     struct {
393         bool esc_prefix;
394         bool eight_bit;
395     } meta;
396 
397     bool num_lock_modifier;
398     bool bell_action_enabled;
399 
400     /* Saved DECSET modes - we save the SET state */
401     struct {
402         bool origin:1;
403         bool application_cursor_keys:1;
404         bool reverse:1;
405         bool show_cursor:1;
406         bool reverse_wrap:1;
407         bool auto_margin:1;
408         bool cursor_blink:1;
409         bool bracketed_paste:1;
410         bool focus_events:1;
411         bool alt_scrolling:1;
412         //bool mouse_x10:1;
413         bool mouse_click:1;
414         bool mouse_drag:1;
415         bool mouse_motion:1;
416         //bool mouse_utf8:1;
417         bool mouse_sgr:1;
418         bool mouse_urxvt:1;
419         bool meta_eight_bit:1;
420         bool meta_esc_prefix:1;
421         bool num_lock_modifier:1;
422         bool bell_action_enabled:1;
423         bool alt_screen:1;
424         bool modify_escape_key:1;
425         bool ime:1;
426         bool app_sync_updates:1;
427 
428         bool sixel_display_mode:1;
429         bool sixel_private_palette:1;
430         bool sixel_cursor_right_of_graphics:1;
431     } xtsave;
432 
433     bool window_title_has_been_set;
434     char *window_title;
435     tll(char *) window_title_stack;
436 
437     struct {
438         bool active;
439         int fd;
440     } flash;
441 
442     struct {
443         enum { BLINK_ON, BLINK_OFF } state;
444         int fd;
445     } blink;
446 
447     int scale;
448     int width;  /* pixels */
449     int height; /* pixels */
450     int stashed_width;
451     int stashed_height;
452     struct {
453         int left;
454         int right;
455         int top;
456         int bottom;
457     } margins;
458     int cell_width;  /* pixels per cell, x-wise */
459     int cell_height; /* pixels per cell, y-wise */
460 
461     struct {
462         uint32_t fg;
463         uint32_t bg;
464         uint32_t table[256];
465         uint16_t alpha;
466         uint32_t selection_fg;
467         uint32_t selection_bg;
468         bool use_custom_selection;
469     } colors;
470 
471     enum cursor_style cursor_style;
472     struct {
473         bool decset;   /* Blink enabled via '\E[?12h' */
474         bool deccsusr; /* Blink enabled via '\E[X q' */
475         int fd;
476         enum { CURSOR_BLINK_ON, CURSOR_BLINK_OFF } state;
477     } cursor_blink;
478     struct {
479         uint32_t text;
480         uint32_t cursor;
481     } cursor_color;
482 
483     struct {
484         enum selection_kind kind;
485         enum selection_direction direction;
486         struct coord start;
487         struct coord end;
488         bool ongoing;
489         bool spaces_only; /* SELECTION_SEMANTIC_WORD */
490 
491         struct {
492             struct coord start;
493             struct coord end;
494         } pivot;
495 
496         struct {
497             int fd;
498             int col;
499             enum selection_scroll_direction direction;
500         } auto_scroll;
501     } selection;
502 
503     bool is_searching;
504     struct {
505         wchar_t *buf;
506         size_t len;
507         size_t sz;
508         size_t cursor;
509         enum { SEARCH_BACKWARD, SEARCH_FORWARD} direction;
510 
511         int original_view;
512         bool view_followed_offset;
513         struct coord match;
514         size_t match_len;
515     } search;
516 
517     struct wayland *wl;
518     struct wl_window *window;
519     bool visual_focus;
520     bool kbd_focus;
521     enum term_surface active_surface;
522 
523     struct {
524         struct {
525             struct buffer_chain *grid;
526             struct buffer_chain *search;
527             struct buffer_chain *scrollback_indicator;
528             struct buffer_chain *render_timer;
529             struct buffer_chain *url;
530             struct buffer_chain *csd;
531         } chains;
532 
533         /* Scheduled for rendering, as soon-as-possible */
534         struct {
535             bool grid;
536             bool csd;
537             bool search;
538             bool urls;
539         } refresh;
540 
541         /* Scheduled for rendering, in the next frame callback */
542         struct {
543             bool grid;
544             bool csd;
545             bool search;
546             bool urls;
547         } pending;
548 
549         bool margins;  /* Someone explicitly requested a refresh of the margins */
550         bool urgency;  /* Signal 'urgency' (paint borders red) */
551 
552         struct {
553             struct timeval last_update;
554             bool is_armed;
555             int timer_fd;
556         } title;
557 
558         uint32_t scrollback_lines; /* Number of scrollback lines, from conf (TODO: move out from render struct?) */
559 
560         struct {
561             bool enabled;
562             int timer_fd;
563         } app_sync_updates;
564 
565         /* Render threads + synchronization primitives */
566         struct {
567             uint16_t count;
568             sem_t start;
569             sem_t done;
570             mtx_t lock;
571             tll(int) queue;
572             thrd_t *threads;
573             struct buffer *buf;
574         } workers;
575 
576         /* Last rendered cursor position */
577         struct {
578             struct row *row;
579             int col;
580             bool hidden;
581         } last_cursor;
582 
583         struct buffer *last_buf;     /* Buffer we rendered to last time */
584         bool was_flashing;           /* Flash was active last time we rendered */
585         bool was_searching;
586 
587         size_t search_glyph_offset;
588 
589         bool presentation_timings;
590         struct timespec input_time;
591     } render;
592 
593     struct {
594         enum {
595             SIXEL_DECSIXEL,  /* DECSIXEL body part ", $, -, ? ... ~ */
596             SIXEL_DECGRA,    /* DECGRA Set Raster Attributes " Pan; Pad; Ph; Pv */
597             SIXEL_DECGRI,    /* DECGRI Graphics Repeat Introducer ! Pn Ch */
598             SIXEL_DECGCI,    /* DECGCI Graphics Color Introducer # Pc; Pu; Px; Py; Pz */
599         } state;
600 
601         struct coord pos;    /* Current sixel coordinate */
602         int max_non_empty_row_no;
603         size_t row_byte_ofs; /* Byte position into image, for current row */
604         int color_idx;       /* Current palette index */
605         uint32_t *private_palette;   /* Private palette, used when private mode 1070 is enabled */
606         uint32_t *shared_palette;    /* Shared palette, used when private mode 1070 is disabled */
607         uint32_t *palette;   /* Points to either private_palette or shared_palette */
608         uint32_t color;
609 
610         struct {
611             uint32_t *data;  /* Raw image data, in ARGB */
612             int width;       /* Image width, in pixels */
613             int height;      /* Image height, in pixels */
614         } image;
615 
616         bool scrolling:1;                 /* Private mode 80 */
617         bool use_private_palette:1;       /* Private mode 1070 */
618         bool cursor_right_of_graphics:1;  /* Private mode 8452 */
619 
620         unsigned params[5];  /* Collected parameters, for RASTER, COLOR_SPEC */
621         unsigned param;      /* Currently collecting parameter, for RASTER, COLOR_SPEC and REPEAT */
622         unsigned param_idx;  /* Parameters seen */
623 
624         bool transparent_bg;
625         uint32_t default_bg;
626 
627         /* Application configurable */
628         unsigned palette_size;  /* Number of colors in palette */
629         unsigned max_width;     /* Maximum image width, in pixels */
630         unsigned max_height;    /* Maximum image height, in pixels */
631     } sixel;
632 
633     /* TODO: wrap in a struct */
634     url_list_t urls;
635     wchar_t url_keys[5];
636     bool urls_show_uri_on_jump_label;
637     struct grid *url_grid_snapshot;
638 
639 #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
640     bool ime_enabled;
641 #endif
642 
643     struct {
644         bool in_progress;
645         bool client_has_terminated;
646         int terminate_timeout_fd;
647         int exit_status;
648 
649         void (*cb)(void *data, int exit_code);
650         void *cb_data;
651     } shutdown;
652 
653     char *foot_exe;
654     char *cwd;
655 };
656 
657 extern const char *const XCURSOR_HIDDEN;
658 extern const char *const XCURSOR_LEFT_PTR;
659 extern const char *const XCURSOR_TEXT;
660 //extern const char *const XCURSOR_HAND2;
661 extern const char *const XCURSOR_TOP_LEFT_CORNER;
662 extern const char *const XCURSOR_TOP_RIGHT_CORNER;
663 extern const char *const XCURSOR_BOTTOM_LEFT_CORNER;
664 extern const char *const XCURSOR_BOTTOM_RIGHT_CORNER;
665 extern const char *const XCURSOR_LEFT_SIDE;
666 extern const char *const XCURSOR_RIGHT_SIDE;
667 extern const char *const XCURSOR_TOP_SIDE;
668 extern const char *const XCURSOR_BOTTOM_SIDE;
669 
670 struct config;
671 struct terminal *term_init(
672     const struct config *conf, struct fdm *fdm, struct reaper *reaper,
673     struct wayland *wayl, const char *foot_exe, const char *cwd,
674     const char *token, int argc, char *const *argv,
675     void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data);
676 
677 bool term_shutdown(struct terminal *term);
678 int term_destroy(struct terminal *term);
679 
680 void term_update_ascii_printer(struct terminal *term);
681 void term_single_shift(struct terminal *term, enum charset_designator idx);
682 
683 void term_reset(struct terminal *term, bool hard);
684 bool term_to_slave(struct terminal *term, const void *data, size_t len);
685 bool term_paste_data_to_slave(
686     struct terminal *term, const void *data, size_t len);
687 
688 bool term_font_size_increase(struct terminal *term);
689 bool term_font_size_decrease(struct terminal *term);
690 bool term_font_size_reset(struct terminal *term);
691 bool term_font_dpi_changed(struct terminal *term, int old_scale);
692 void term_font_subpixel_changed(struct terminal *term);
693 
694 int term_pt_or_px_as_pixels(
695     const struct terminal *term, const struct pt_or_px *pt_or_px);
696 
697 
698 void term_window_configured(struct terminal *term);
699 
700 void term_damage_rows(struct terminal *term, int start, int end);
701 void term_damage_rows_in_view(struct terminal *term, int start, int end);
702 
703 void term_damage_all(struct terminal *term);
704 void term_damage_view(struct terminal *term);
705 
706 void term_damage_cursor(struct terminal *term);
707 void term_damage_margins(struct terminal *term);
708 
709 void term_reset_view(struct terminal *term);
710 
711 void term_damage_scroll(
712     struct terminal *term, enum damage_type damage_type,
713     struct scroll_region region, int lines);
714 
715 void term_erase(
716     struct terminal *term, const struct coord *start, const struct coord *end);
717 void term_erase_scrollback(struct terminal *term);
718 
719 int term_row_rel_to_abs(const struct terminal *term, int row);
720 void term_cursor_home(struct terminal *term);
721 void term_cursor_to(struct terminal *term, int row, int col);
722 void term_cursor_left(struct terminal *term, int count);
723 void term_cursor_right(struct terminal *term, int count);
724 void term_cursor_up(struct terminal *term, int count);
725 void term_cursor_down(struct terminal *term, int count);
726 void term_cursor_blink_update(struct terminal *term);
727 
728 void term_print(struct terminal *term, wchar_t wc, int width);
729 
730 void term_scroll(struct terminal *term, int rows);
731 void term_scroll_reverse(struct terminal *term, int rows);
732 
733 void term_scroll_partial(
734     struct terminal *term, struct scroll_region region, int rows);
735 void term_scroll_reverse_partial(
736     struct terminal *term, struct scroll_region region, int rows);
737 
738 void term_carriage_return(struct terminal *term);
739 void term_linefeed(struct terminal *term);
740 void term_reverse_index(struct terminal *term);
741 
742 void term_arm_blink_timer(struct terminal *term);
743 
744 void term_save_cursor(struct terminal *term);
745 void term_restore_cursor(struct terminal *term, const struct cursor *cursor);
746 
747 void term_visual_focus_in(struct terminal *term);
748 void term_visual_focus_out(struct terminal *term);
749 void term_kbd_focus_in(struct terminal *term);
750 void term_kbd_focus_out(struct terminal *term);
751 void term_mouse_down(
752     struct terminal *term, int button, int row, int col,
753     bool shift, bool alt, bool ctrl);
754 void term_mouse_up(
755     struct terminal *term, int button, int row, int col,
756     bool shift, bool alt, bool ctrl);
757 void term_mouse_motion(
758     struct terminal *term, int button, int row, int col,
759     bool shift, bool alt, bool ctrl);
760 bool term_mouse_grabbed(const struct terminal *term, struct seat *seat);
761 void term_xcursor_update(struct terminal *term);
762 void term_xcursor_update_for_seat(struct terminal *term, struct seat *seat);
763 
764 void term_set_window_title(struct terminal *term, const char *title);
765 void term_flash(struct terminal *term, unsigned duration_ms);
766 void term_bell(struct terminal *term);
767 bool term_spawn_new(const struct terminal *term);
768 
769 void term_enable_app_sync_updates(struct terminal *term);
770 void term_disable_app_sync_updates(struct terminal *term);
771 
772 enum term_surface term_surface_kind(
773     const struct terminal *term, const struct wl_surface *surface);
774 
775 bool term_scrollback_to_text(
776     const struct terminal *term, char **text, size_t *len);
777 bool term_view_to_text(
778     const struct terminal *term, char **text, size_t *len);
779 
780 bool term_ime_is_enabled(const struct terminal *term);
781 void term_ime_enable(struct terminal *term);
782 void term_ime_disable(struct terminal *term);
783 bool term_ime_reset(struct terminal *term);
784 void term_ime_set_cursor_rect(
785     struct terminal *term, int x, int y, int width, int height);
786 
787 void term_urls_reset(struct terminal *term);
788 void term_collect_urls(struct terminal *term);
789 
790 void term_osc8_open(struct terminal *term, uint64_t id, const char *uri);
791 void term_osc8_close(struct terminal *term);
792 
term_reset_grapheme_state(struct terminal * term)793 static inline void term_reset_grapheme_state(struct terminal *term)
794 {
795 #if defined(FOOT_GRAPHEME_CLUSTERING)
796     term->vt.grapheme_state = 0;
797 #endif
798 }
799