You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

599 lines
16 KiB

  1. #pragma once
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <stddef.h>
  5. #include <wchar.h>
  6. #include <threads.h>
  7. #include <semaphore.h>
  8. #include <tllist.h>
  9. #include <fcft/fcft.h>
  10. //#include "config.h"
  11. #include "fdm.h"
  12. #include "macros.h"
  13. #include "reaper.h"
  14. #include "wayland.h"
  15. /*
  16. * Note: we want the cells to be as small as possible. Larger cells
  17. * means fewer scrollback lines (or performance drops due to cache
  18. * misses)
  19. *
  20. * Note that the members are laid out optimized for x86
  21. */
  22. struct attributes {
  23. uint32_t bold:1;
  24. uint32_t dim:1;
  25. uint32_t italic:1;
  26. uint32_t underline:1;
  27. uint32_t strikethrough:1;
  28. uint32_t blink:1;
  29. uint32_t conceal:1;
  30. uint32_t reverse:1;
  31. uint32_t fg:24;
  32. uint32_t clean:1;
  33. uint32_t have_fg:1;
  34. uint32_t have_bg:1;
  35. uint32_t selected:2;
  36. uint32_t reserved:3;
  37. uint32_t bg:24;
  38. };
  39. static_assert(sizeof(struct attributes) == 8, "bad size");
  40. #define CELL_COMB_CHARS_LO 0x40000000ul
  41. #define CELL_COMB_CHARS_HI 0x400ffffful
  42. #define CELL_MULT_COL_SPACER 0x40100000ul
  43. struct cell {
  44. wchar_t wc;
  45. struct attributes attrs;
  46. };
  47. static_assert(sizeof(struct cell) == 12, "bad size");
  48. struct scroll_region {
  49. int start;
  50. int end;
  51. };
  52. struct coord {
  53. int col;
  54. int row;
  55. };
  56. struct cursor {
  57. struct coord point;
  58. bool lcf;
  59. };
  60. enum damage_type {DAMAGE_SCROLL, DAMAGE_SCROLL_REVERSE,
  61. DAMAGE_SCROLL_IN_VIEW, DAMAGE_SCROLL_REVERSE_IN_VIEW};
  62. struct damage {
  63. enum damage_type type;
  64. struct scroll_region region;
  65. int lines;
  66. };
  67. struct composed {
  68. wchar_t base;
  69. wchar_t combining[5];
  70. uint8_t count;
  71. };
  72. struct row {
  73. struct cell *cells;
  74. bool dirty;
  75. bool linebreak;
  76. };
  77. struct sixel {
  78. void *data;
  79. pixman_image_t *pix;
  80. int width;
  81. int height;
  82. int rows;
  83. int cols;
  84. struct coord pos;
  85. };
  86. struct grid {
  87. int num_rows;
  88. int num_cols;
  89. int offset;
  90. int view;
  91. struct cursor cursor;
  92. struct cursor saved_cursor;
  93. struct row **rows;
  94. struct row *cur_row;
  95. tll(struct damage) scroll_damage;
  96. tll(struct sixel) sixel_images;
  97. };
  98. struct vt_subparams {
  99. unsigned value[16];
  100. uint8_t idx;
  101. };
  102. struct vt_param {
  103. unsigned value;
  104. struct vt_subparams sub;
  105. };
  106. struct vt {
  107. int state; /* enum state */
  108. wchar_t last_printed;
  109. wchar_t utf8;
  110. struct {
  111. struct vt_param v[16];
  112. uint8_t idx;
  113. } params;
  114. char private[2];
  115. struct {
  116. uint8_t *data;
  117. size_t size;
  118. size_t idx;
  119. } osc;
  120. struct {
  121. uint8_t *data;
  122. size_t size;
  123. size_t idx;
  124. void (*put_handler)(struct terminal *term, uint8_t c);
  125. void (*unhook_handler)(struct terminal *term);
  126. } dcs;
  127. struct attributes attrs;
  128. struct attributes saved_attrs;
  129. };
  130. enum cursor_origin { ORIGIN_ABSOLUTE, ORIGIN_RELATIVE };
  131. enum cursor_keys { CURSOR_KEYS_DONTCARE, CURSOR_KEYS_NORMAL, CURSOR_KEYS_APPLICATION };
  132. enum keypad_keys { KEYPAD_DONTCARE, KEYPAD_NUMERICAL, KEYPAD_APPLICATION };
  133. enum charset { CHARSET_ASCII, CHARSET_GRAPHIC };
  134. struct charsets {
  135. int selected;
  136. enum charset set[4]; /* G0-G3 */
  137. };
  138. /* *What* to report */
  139. enum mouse_tracking {
  140. MOUSE_NONE,
  141. MOUSE_X10, /* ?9h */
  142. MOUSE_CLICK, /* ?1000h - report mouse clicks */
  143. MOUSE_DRAG, /* ?1002h - report clicks and drag motions */
  144. MOUSE_MOTION, /* ?1003h - report clicks and motion */
  145. };
  146. /* *How* to report */
  147. enum mouse_reporting {
  148. MOUSE_NORMAL,
  149. MOUSE_UTF8, /* ?1005h */
  150. MOUSE_SGR, /* ?1006h */
  151. MOUSE_URXVT, /* ?1015h */
  152. };
  153. enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BAR };
  154. enum selection_kind { SELECTION_NONE, SELECTION_NORMAL, SELECTION_BLOCK };
  155. enum selection_direction {SELECTION_UNDIR, SELECTION_LEFT, SELECTION_RIGHT};
  156. enum selection_scroll_direction {SELECTION_SCROLL_NOT, SELECTION_SCROLL_UP, SELECTION_SCROLL_DOWN};
  157. struct ptmx_buffer {
  158. void *data;
  159. size_t len;
  160. size_t idx;
  161. };
  162. enum term_surface {
  163. TERM_SURF_NONE,
  164. TERM_SURF_GRID,
  165. TERM_SURF_SEARCH,
  166. TERM_SURF_SCROLLBACK_INDICATOR,
  167. TERM_SURF_RENDER_TIMER,
  168. TERM_SURF_TITLE,
  169. TERM_SURF_BORDER_LEFT,
  170. TERM_SURF_BORDER_RIGHT,
  171. TERM_SURF_BORDER_TOP,
  172. TERM_SURF_BORDER_BOTTOM,
  173. TERM_SURF_BUTTON_MINIMIZE,
  174. TERM_SURF_BUTTON_MAXIMIZE,
  175. TERM_SURF_BUTTON_CLOSE,
  176. };
  177. typedef tll(struct ptmx_buffer) ptmx_buffer_list_t;
  178. struct terminal {
  179. struct fdm *fdm;
  180. struct reaper *reaper;
  181. const struct config *conf;
  182. pid_t slave;
  183. int ptmx;
  184. bool quit;
  185. struct grid normal;
  186. struct grid alt;
  187. struct grid *grid;
  188. size_t composed_count;
  189. struct composed *composed;
  190. struct fcft_font *fonts[4];
  191. struct config_font *font_sizes;
  192. float font_dpi;
  193. enum fcft_subpixel font_subpixel;
  194. bool is_sending_paste_data;
  195. ptmx_buffer_list_t ptmx_buffers;
  196. ptmx_buffer_list_t ptmx_paste_buffers;
  197. enum cursor_origin origin;
  198. enum cursor_keys cursor_keys_mode;
  199. enum keypad_keys keypad_keys_mode;
  200. bool reverse;
  201. bool hide_cursor;
  202. bool reverse_wrap;
  203. bool auto_margin;
  204. bool insert_mode;
  205. bool bracketed_paste;
  206. bool focus_events;
  207. bool alt_scrolling;
  208. enum mouse_tracking mouse_tracking;
  209. enum mouse_reporting mouse_reporting;
  210. struct {
  211. bool esc_prefix;
  212. bool eight_bit;
  213. } meta;
  214. bool bell_is_urgent;
  215. /* Saved DECSET modes - we save the SET state */
  216. struct {
  217. uint32_t origin:1;
  218. uint32_t application_cursor_keys:1;
  219. uint32_t reverse:1;
  220. uint32_t show_cursor:1;
  221. uint32_t reverse_wrap:1;
  222. uint32_t auto_margin:1;
  223. uint32_t cursor_blink:1;
  224. uint32_t bracketed_paste:1;
  225. uint32_t focus_events:1;
  226. uint32_t alt_scrolling:1;
  227. //uint32_t mouse_x10:1;
  228. uint32_t mouse_click:1;
  229. uint32_t mouse_drag:1;
  230. uint32_t mouse_motion:1;
  231. //uint32_t mouse_utf8:1;
  232. uint32_t mouse_sgr:1;
  233. uint32_t mouse_urxvt:1;
  234. uint32_t meta_eight_bit:1;
  235. uint32_t meta_esc_prefix:1;
  236. uint32_t bell_is_urgent:1;
  237. uint32_t alt_screen:1;
  238. } xtsave;
  239. struct charsets charsets;
  240. struct charsets saved_charsets; /* For save/restore cursor + attributes */
  241. char *window_title;
  242. tll(char *) window_title_stack;
  243. struct {
  244. bool active;
  245. int fd;
  246. } flash;
  247. struct {
  248. enum { BLINK_ON, BLINK_OFF } state;
  249. int fd;
  250. } blink;
  251. struct vt vt;
  252. int scale;
  253. int width; /* pixels */
  254. int height; /* pixels */
  255. int unmaximized_width; /* last unmaximized size, pixels */
  256. int unmaximized_height; /* last unmaximized size, pixels */
  257. struct {
  258. int left;
  259. int right;
  260. int top;
  261. int bottom;
  262. } margins;
  263. int cols; /* number of columns */
  264. int rows; /* number of rows */
  265. int cell_width; /* pixels per cell, x-wise */
  266. int cell_height; /* pixels per cell, y-wise */
  267. struct scroll_region scroll_region;
  268. struct {
  269. uint32_t fg;
  270. uint32_t bg;
  271. uint32_t table[256];
  272. uint16_t alpha;
  273. uint32_t default_fg;
  274. uint32_t default_bg;
  275. uint32_t default_table[256];
  276. } colors;
  277. enum cursor_style default_cursor_style;
  278. enum cursor_style cursor_style;
  279. struct {
  280. bool active;
  281. enum { CURSOR_BLINK_ON, CURSOR_BLINK_OFF } state;
  282. int fd;
  283. } cursor_blink;
  284. bool default_cursor_blink;
  285. struct {
  286. uint32_t text;
  287. uint32_t cursor;
  288. } default_cursor_color;
  289. struct {
  290. uint32_t text;
  291. uint32_t cursor;
  292. } cursor_color;
  293. struct {
  294. enum selection_kind kind;
  295. enum selection_direction direction;
  296. struct coord start;
  297. struct coord end;
  298. bool ongoing;
  299. struct {
  300. int fd;
  301. int col;
  302. enum selection_scroll_direction direction;
  303. } auto_scroll;
  304. } selection;
  305. bool is_searching;
  306. struct {
  307. wchar_t *buf;
  308. size_t len;
  309. size_t sz;
  310. size_t cursor;
  311. enum { SEARCH_BACKWARD, SEARCH_FORWARD} direction;
  312. int original_view;
  313. bool view_followed_offset;
  314. struct coord match;
  315. size_t match_len;
  316. } search;
  317. tll(int) tab_stops;
  318. struct wayland *wl;
  319. struct wl_window *window;
  320. bool visual_focus;
  321. bool kbd_focus;
  322. enum term_surface active_surface;
  323. struct {
  324. /* Scheduled for rendering, as soon-as-possible */
  325. struct {
  326. bool grid;
  327. bool csd;
  328. bool search;
  329. bool title;
  330. } refresh;
  331. /* Scheduled for rendering, in the next frame callback */
  332. struct {
  333. bool grid;
  334. bool csd;
  335. bool search;
  336. bool title;
  337. } pending;
  338. bool margins; /* Someone explicitly requested a refresh of the margins */
  339. bool urgency; /* Signal 'urgency' (paint borders red) */
  340. int scrollback_lines; /* Number of scrollback lines, from conf (TODO: move out from render struct?) */
  341. struct {
  342. bool enabled;
  343. int timer_fd;
  344. bool flipped;
  345. } app_sync_updates;
  346. /* Render threads + synchronization primitives */
  347. struct {
  348. size_t count;
  349. sem_t start;
  350. sem_t done;
  351. mtx_t lock;
  352. tll(int) queue;
  353. thrd_t *threads;
  354. struct buffer *buf;
  355. } workers;
  356. /* Last rendered cursor position */
  357. struct {
  358. struct row *row;
  359. int col;
  360. bool hidden;
  361. } last_cursor;
  362. struct buffer *last_buf; /* Buffer we rendered to last time */
  363. bool was_flashing; /* Flash was active last time we rendered */
  364. bool was_searching;
  365. size_t search_glyph_offset;
  366. bool presentation_timings;
  367. struct timespec input_time;
  368. } render;
  369. /* Temporary: for FDM */
  370. struct {
  371. bool is_armed;
  372. int lower_fd;
  373. int upper_fd;
  374. } delayed_render_timer;
  375. struct {
  376. enum {
  377. SIXEL_DECSIXEL, /* DECSIXEL body part ", $, -, ? ... ~ */
  378. SIXEL_DECGRA, /* DECGRA Set Raster Attributes " Pan; Pad; Ph; Pv */
  379. SIXEL_DECGRI, /* DECGRI Graphics Repeat Introducer ! Pn Ch */
  380. SIXEL_DECGCI, /* DECGCI Graphics Color Introducer # Pc; Pu; Px; Py; Pz */
  381. } state;
  382. struct coord pos; /* Current sixel coordinate */
  383. int color_idx; /* Current palette index */
  384. int max_col; /* Largest column index we've seen (aka the image width) */
  385. uint32_t *palette; /* Color palette */
  386. struct {
  387. uint32_t *data; /* Raw image data, in ARGB */
  388. int width; /* Image width, in pixels */
  389. int height; /* Image height, in pixels */
  390. bool autosize;
  391. } image;
  392. unsigned params[5]; /* Collected parameters, for RASTER, COLOR_SPEC */
  393. unsigned param; /* Currently collecting parameter, for RASTER, COLOR_SPEC and REPEAT */
  394. unsigned param_idx; /* Parameters seen */
  395. /* Application configurable */
  396. unsigned palette_size; /* Number of colors in palette */
  397. unsigned max_width; /* Maximum image width, in pixels */
  398. unsigned max_height; /* Maximum image height, in pixels */
  399. } sixel;
  400. bool hold_at_exit;
  401. bool is_shutting_down;
  402. void (*shutdown_cb)(void *data, int exit_code);
  403. void *shutdown_data;
  404. char *foot_exe;
  405. char *cwd;
  406. };
  407. extern const char *const XCURSOR_HIDDEN;
  408. extern const char *const XCURSOR_LEFT_PTR;
  409. extern const char *const XCURSOR_TEXT;
  410. //extern const char *const XCURSOR_HAND2;
  411. extern const char *const XCURSOR_TOP_LEFT_CORNER;
  412. extern const char *const XCURSOR_TOP_RIGHT_CORNER;
  413. extern const char *const XCURSOR_BOTTOM_LEFT_CORNER;
  414. extern const char *const XCURSOR_BOTTOM_RIGHT_CORNER;
  415. extern const char *const XCURSOR_LEFT_SIDE;
  416. extern const char *const XCURSOR_RIGHT_SIDE;
  417. extern const char *const XCURSOR_TOP_SIDE;
  418. extern const char *const XCURSOR_BOTTOM_SIDE;
  419. struct config;
  420. struct terminal *term_init(
  421. const struct config *conf, struct fdm *fdm, struct reaper *reaper,
  422. struct wayland *wayl, const char *foot_exe, const char *cwd,
  423. int argc, char *const *argv,
  424. void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data);
  425. bool term_shutdown(struct terminal *term);
  426. int term_destroy(struct terminal *term);
  427. void term_reset(struct terminal *term, bool hard);
  428. bool term_to_slave(struct terminal *term, const void *data, size_t len);
  429. bool term_paste_data_to_slave(
  430. struct terminal *term, const void *data, size_t len);
  431. bool term_font_size_increase(struct terminal *term);
  432. bool term_font_size_decrease(struct terminal *term);
  433. bool term_font_size_reset(struct terminal *term);
  434. bool term_font_dpi_changed(struct terminal *term);
  435. void term_font_subpixel_changed(struct terminal *term);
  436. void term_window_configured(struct terminal *term);
  437. void term_damage_rows(struct terminal *term, int start, int end);
  438. void term_damage_rows_in_view(struct terminal *term, int start, int end);
  439. void term_damage_all(struct terminal *term);
  440. void term_damage_view(struct terminal *term);
  441. void term_damage_cursor(struct terminal *term);
  442. void term_damage_margins(struct terminal *term);
  443. void term_reset_view(struct terminal *term);
  444. void term_damage_scroll(
  445. struct terminal *term, enum damage_type damage_type,
  446. struct scroll_region region, int lines);
  447. void term_erase(
  448. struct terminal *term, const struct coord *start, const struct coord *end);
  449. int term_row_rel_to_abs(const struct terminal *term, int row);
  450. void term_cursor_home(struct terminal *term);
  451. void term_cursor_to(struct terminal *term, int row, int col);
  452. void term_cursor_left(struct terminal *term, int count);
  453. void term_cursor_right(struct terminal *term, int count);
  454. void term_cursor_up(struct terminal *term, int count);
  455. void term_cursor_down(struct terminal *term, int count);
  456. void term_cursor_blink_enable(struct terminal *term);
  457. void term_cursor_blink_disable(struct terminal *term);
  458. void term_cursor_blink_restart(struct terminal *term);
  459. void term_print(struct terminal *term, wchar_t wc, int width);
  460. void term_scroll(struct terminal *term, int rows);
  461. void term_scroll_reverse(struct terminal *term, int rows);
  462. void term_scroll_partial(
  463. struct terminal *term, struct scroll_region region, int rows);
  464. void term_scroll_reverse_partial(
  465. struct terminal *term, struct scroll_region region, int rows);
  466. void term_carriage_return(struct terminal *term);
  467. void term_linefeed(struct terminal *term);
  468. void term_reverse_index(struct terminal *term);
  469. void term_arm_blink_timer(struct terminal *term);
  470. void term_restore_cursor(struct terminal *term, const struct cursor *cursor);
  471. void term_visual_focus_in(struct terminal *term);
  472. void term_visual_focus_out(struct terminal *term);
  473. void term_kbd_focus_in(struct terminal *term);
  474. void term_kbd_focus_out(struct terminal *term);
  475. void term_mouse_down(
  476. struct terminal *term, int button, int row, int col,
  477. bool shift, bool alt, bool ctrl);
  478. void term_mouse_up(
  479. struct terminal *term, int button, int row, int col,
  480. bool shift, bool alt, bool ctrl);
  481. void term_mouse_motion(
  482. struct terminal *term, int button, int row, int col,
  483. bool shift, bool alt, bool ctrl);
  484. bool term_mouse_grabbed(const struct terminal *term, struct seat *seat);
  485. void term_xcursor_update(struct terminal *term);
  486. void term_xcursor_update_for_seat(struct terminal *term, struct seat *seat);
  487. void term_set_window_title(struct terminal *term, const char *title);
  488. void term_flash(struct terminal *term, unsigned duration_ms);
  489. void term_bell(struct terminal *term);
  490. bool term_spawn_new(const struct terminal *term);
  491. void term_enable_app_sync_updates(struct terminal *term);
  492. void term_disable_app_sync_updates(struct terminal *term);
  493. enum term_surface term_surface_kind(
  494. const struct terminal *term, const struct wl_surface *surface);
  495. bool term_scrollback_to_text(
  496. const struct terminal *term, char **text, size_t *len);
  497. bool term_view_to_text(
  498. const struct terminal *term, char **text, size_t *len);