2019-06-15 22:22:44 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stddef.h>
|
2019-08-02 18:19:07 +02:00
|
|
|
#include <wchar.h>
|
2019-06-15 22:22:44 +02:00
|
|
|
|
2019-06-19 10:04:47 +02:00
|
|
|
#include <threads.h>
|
2019-07-29 20:13:26 +02:00
|
|
|
#include <semaphore.h>
|
2019-06-19 10:04:47 +02:00
|
|
|
|
2019-10-28 18:25:19 +01:00
|
|
|
//#include "config.h"
|
|
|
|
|
#include "fdm.h"
|
2019-07-30 18:04:28 +02:00
|
|
|
#include "font.h"
|
2019-06-19 14:17:43 +02:00
|
|
|
#include "tllist.h"
|
2019-10-27 13:06:39 +01:00
|
|
|
#include "wayland.h"
|
2019-06-19 14:17:43 +02:00
|
|
|
|
2019-07-06 13:25:36 +02:00
|
|
|
#define likely(c) __builtin_expect(!!(c), 1)
|
|
|
|
|
#define unlikely(c) __builtin_expect(!!(c), 0)
|
|
|
|
|
|
2019-07-16 13:19:17 +02:00
|
|
|
struct rgb { float r, g, b; };
|
2019-06-26 20:33:32 +02:00
|
|
|
|
2019-07-10 18:48:46 +02:00
|
|
|
/*
|
|
|
|
|
* Note: we want the cells to be as small as possible. Larger cells
|
|
|
|
|
* means fewer scrollback lines (or performance drops due to cache
|
2019-08-02 18:19:07 +02:00
|
|
|
* misses)
|
|
|
|
|
*
|
|
|
|
|
* Note that the members are laid out optimized for x86
|
|
|
|
|
*/
|
2019-06-16 16:44:42 +02:00
|
|
|
struct attributes {
|
2019-08-02 18:19:07 +02:00
|
|
|
uint32_t bold:1;
|
|
|
|
|
uint32_t dim:1;
|
|
|
|
|
uint32_t italic:1;
|
|
|
|
|
uint32_t underline:1;
|
|
|
|
|
uint32_t strikethrough:1;
|
|
|
|
|
uint32_t blink:1;
|
|
|
|
|
uint32_t conceal:1;
|
|
|
|
|
uint32_t reverse:1;
|
|
|
|
|
uint32_t fg:24;
|
2019-07-10 18:48:46 +02:00
|
|
|
|
2019-07-30 18:03:03 +02:00
|
|
|
uint32_t clean:1;
|
2019-08-02 18:19:07 +02:00
|
|
|
uint32_t have_fg:1;
|
|
|
|
|
uint32_t have_bg:1;
|
|
|
|
|
uint32_t reserved:5;
|
|
|
|
|
uint32_t bg:24;
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(struct attributes) == 8, "bad size");
|
2019-06-16 16:44:42 +02:00
|
|
|
|
|
|
|
|
struct cell {
|
2019-08-02 18:19:07 +02:00
|
|
|
wchar_t wc;
|
2019-06-16 16:44:42 +02:00
|
|
|
struct attributes attrs;
|
2019-08-02 18:19:07 +02:00
|
|
|
};
|
|
|
|
|
static_assert(sizeof(struct cell) == 12, "bad size");
|
2019-06-15 22:22:44 +02:00
|
|
|
|
2019-06-25 20:11:08 +02:00
|
|
|
struct scroll_region {
|
|
|
|
|
int start;
|
|
|
|
|
int end;
|
|
|
|
|
};
|
|
|
|
|
|
2019-07-08 13:57:31 +02:00
|
|
|
struct coord {
|
2019-06-29 21:15:32 +02:00
|
|
|
int col;
|
2019-07-08 13:57:31 +02:00
|
|
|
int row;
|
2019-06-29 21:15:32 +02:00
|
|
|
};
|
|
|
|
|
|
2019-10-29 21:09:37 +01:00
|
|
|
enum damage_type {DAMAGE_SCROLL, DAMAGE_SCROLL_REVERSE,
|
|
|
|
|
DAMAGE_SCROLL_IN_VIEW, DAMAGE_SCROLL_REVERSE_IN_VIEW};
|
|
|
|
|
|
2019-06-19 14:17:43 +02:00
|
|
|
struct damage {
|
|
|
|
|
enum damage_type type;
|
2019-07-09 09:17:24 +02:00
|
|
|
/* DAMAGE_SCROLL, DAMAGE_SCROLL_REVERSE */
|
|
|
|
|
struct {
|
|
|
|
|
struct scroll_region region;
|
|
|
|
|
int lines;
|
|
|
|
|
} scroll;
|
2019-06-19 14:17:43 +02:00
|
|
|
};
|
|
|
|
|
|
2019-07-08 13:57:31 +02:00
|
|
|
struct row {
|
|
|
|
|
struct cell *cells;
|
|
|
|
|
bool dirty;
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-15 22:22:44 +02:00
|
|
|
struct grid {
|
2019-07-08 13:57:31 +02:00
|
|
|
int num_rows;
|
2019-07-10 16:27:55 +02:00
|
|
|
int num_cols;
|
2019-07-01 12:23:38 +02:00
|
|
|
int offset;
|
2019-07-09 16:26:36 +02:00
|
|
|
int view;
|
2019-06-29 21:23:36 +02:00
|
|
|
|
2019-07-08 13:57:31 +02:00
|
|
|
struct row **rows;
|
|
|
|
|
struct row *cur_row;
|
2019-06-15 22:22:44 +02:00
|
|
|
|
2019-06-19 14:17:43 +02:00
|
|
|
tll(struct damage) damage;
|
2019-06-25 20:11:08 +02:00
|
|
|
tll(struct damage) scroll_damage;
|
2019-06-15 22:22:44 +02:00
|
|
|
};
|
|
|
|
|
|
2019-06-23 14:12:20 +02:00
|
|
|
struct vt_subparams {
|
|
|
|
|
unsigned value[16];
|
2019-07-05 09:46:48 +02:00
|
|
|
size_t idx;
|
2019-06-23 14:12:20 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct vt_param {
|
|
|
|
|
unsigned value;
|
|
|
|
|
struct vt_subparams sub;
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-15 22:22:44 +02:00
|
|
|
struct vt {
|
|
|
|
|
int state; /* enum state */
|
|
|
|
|
struct {
|
2019-06-23 14:12:20 +02:00
|
|
|
struct vt_param v[16];
|
2019-07-05 09:46:48 +02:00
|
|
|
size_t idx;
|
2019-06-15 22:22:44 +02:00
|
|
|
} params;
|
2019-07-19 09:56:59 +02:00
|
|
|
char private[2];
|
2019-06-15 22:22:44 +02:00
|
|
|
struct {
|
2019-07-19 08:59:35 +02:00
|
|
|
uint8_t *data;
|
|
|
|
|
size_t size;
|
2019-07-05 09:46:48 +02:00
|
|
|
size_t idx;
|
2019-06-15 22:22:44 +02:00
|
|
|
} osc;
|
|
|
|
|
struct {
|
|
|
|
|
uint8_t data[4];
|
2019-07-05 09:46:48 +02:00
|
|
|
size_t idx;
|
|
|
|
|
size_t left;
|
2019-06-15 22:22:44 +02:00
|
|
|
} utf8;
|
2019-06-16 16:44:42 +02:00
|
|
|
struct attributes attrs;
|
2019-07-04 19:23:25 +02:00
|
|
|
struct attributes saved_attrs;
|
2019-06-15 22:22:44 +02:00
|
|
|
};
|
|
|
|
|
|
2019-07-09 11:07:06 +02:00
|
|
|
enum cursor_keys { CURSOR_KEYS_DONTCARE, CURSOR_KEYS_NORMAL, CURSOR_KEYS_APPLICATION};
|
|
|
|
|
enum keypad_keys { KEYPAD_DONTCARE, KEYPAD_NUMERICAL, KEYPAD_APPLICATION };
|
2019-07-04 19:17:18 +02:00
|
|
|
enum charset { CHARSET_ASCII, CHARSET_GRAPHIC };
|
2019-06-23 14:12:20 +02:00
|
|
|
|
2019-07-05 14:24:51 +02:00
|
|
|
/* *What* to report */
|
|
|
|
|
enum mouse_tracking {
|
|
|
|
|
MOUSE_NONE,
|
|
|
|
|
MOUSE_X10, /* ?9h */
|
|
|
|
|
MOUSE_CLICK, /* ?1000h - report mouse clicks*/
|
|
|
|
|
MOUSE_DRAG, /* ?1002h - report clicks and drag motions */
|
|
|
|
|
MOUSE_MOTION, /* ?1003h - report clicks and motion*/
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* *How* to report */
|
|
|
|
|
enum mouse_reporting {
|
|
|
|
|
MOUSE_NORMAL,
|
|
|
|
|
MOUSE_UTF8, /* ?1005h */
|
|
|
|
|
MOUSE_SGR, /* ?1006h */
|
|
|
|
|
MOUSE_URXVT, /* ?1015h */
|
|
|
|
|
};
|
|
|
|
|
|
2019-07-22 20:15:14 +02:00
|
|
|
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BAR };
|
|
|
|
|
|
2019-06-15 22:22:44 +02:00
|
|
|
struct terminal {
|
2019-10-28 18:25:19 +01:00
|
|
|
struct fdm *fdm;
|
|
|
|
|
|
2019-06-19 10:04:47 +02:00
|
|
|
pid_t slave;
|
2019-06-17 18:57:12 +02:00
|
|
|
int ptmx;
|
2019-07-05 10:16:56 +02:00
|
|
|
bool quit;
|
2019-06-29 21:03:28 +02:00
|
|
|
|
2019-07-09 11:07:06 +02:00
|
|
|
enum cursor_keys cursor_keys_mode;
|
|
|
|
|
enum keypad_keys keypad_keys_mode;
|
2019-07-05 20:12:40 +02:00
|
|
|
bool reverse;
|
2019-07-03 21:16:41 +02:00
|
|
|
bool hide_cursor;
|
|
|
|
|
bool auto_margin;
|
|
|
|
|
bool insert_mode;
|
2019-06-22 22:25:50 +02:00
|
|
|
bool bracketed_paste;
|
2019-07-16 10:34:08 +02:00
|
|
|
bool focus_events;
|
2019-08-19 21:16:47 +02:00
|
|
|
bool alt_scrolling;
|
2019-07-05 14:24:51 +02:00
|
|
|
enum mouse_tracking mouse_tracking;
|
|
|
|
|
enum mouse_reporting mouse_reporting;
|
2019-06-29 21:03:28 +02:00
|
|
|
|
2019-07-04 19:17:18 +02:00
|
|
|
int selected_charset;
|
|
|
|
|
enum charset charset[4]; /* G0-G3 */
|
2019-07-21 17:35:53 +02:00
|
|
|
char *window_title;
|
2019-07-21 17:48:06 +02:00
|
|
|
tll(char *) window_title_stack;
|
2019-07-04 19:17:18 +02:00
|
|
|
|
2019-07-22 19:15:56 +02:00
|
|
|
struct {
|
|
|
|
|
bool active;
|
|
|
|
|
int fd;
|
|
|
|
|
} flash;
|
2019-07-21 19:14:19 +02:00
|
|
|
|
2019-07-22 19:17:57 +02:00
|
|
|
struct {
|
|
|
|
|
bool active;
|
|
|
|
|
enum { BLINK_ON, BLINK_OFF } state;
|
|
|
|
|
int fd;
|
|
|
|
|
} blink;
|
2019-07-21 20:11:20 +02:00
|
|
|
|
2019-06-15 22:22:44 +02:00
|
|
|
struct vt vt;
|
2019-06-29 21:08:08 +02:00
|
|
|
|
2019-08-12 21:22:38 +02:00
|
|
|
int scale;
|
2019-07-05 10:16:56 +02:00
|
|
|
int width; /* pixels */
|
|
|
|
|
int height; /* pixels */
|
2019-08-27 15:25:35 +02:00
|
|
|
int x_margin;
|
|
|
|
|
int y_margin;
|
2019-07-05 10:16:56 +02:00
|
|
|
int cols; /* number of columns */
|
|
|
|
|
int rows; /* number of rows */
|
|
|
|
|
int cell_width; /* pixels per cell, x-wise */
|
|
|
|
|
int cell_height; /* pixels per cell, y-wise */
|
2019-06-29 21:08:08 +02:00
|
|
|
|
2019-06-29 21:16:06 +02:00
|
|
|
bool print_needs_wrap;
|
2019-06-29 21:08:08 +02:00
|
|
|
struct scroll_region scroll_region;
|
|
|
|
|
|
2019-07-21 10:58:09 +02:00
|
|
|
struct {
|
|
|
|
|
uint32_t fg;
|
|
|
|
|
uint32_t bg;
|
2019-08-21 18:50:24 +02:00
|
|
|
uint32_t table[256];
|
2019-08-15 18:15:43 +02:00
|
|
|
double alpha;
|
2019-07-21 10:58:09 +02:00
|
|
|
|
|
|
|
|
uint32_t default_fg;
|
2019-07-21 11:06:28 +02:00
|
|
|
uint32_t default_bg;
|
2019-08-21 18:50:24 +02:00
|
|
|
uint32_t default_table[256];
|
2019-07-21 10:58:09 +02:00
|
|
|
} colors;
|
2019-06-29 21:15:32 +02:00
|
|
|
|
2019-07-08 13:57:31 +02:00
|
|
|
struct coord cursor;
|
|
|
|
|
struct coord saved_cursor;
|
|
|
|
|
struct coord alt_saved_cursor;
|
2019-07-22 20:19:27 +02:00
|
|
|
enum cursor_style default_cursor_style;
|
2019-07-22 20:15:14 +02:00
|
|
|
enum cursor_style cursor_style;
|
2019-07-22 19:44:21 +02:00
|
|
|
bool cursor_blinking;
|
2019-07-23 18:54:58 +02:00
|
|
|
struct {
|
|
|
|
|
uint32_t text;
|
|
|
|
|
uint32_t cursor;
|
|
|
|
|
} default_cursor_color;
|
|
|
|
|
struct {
|
|
|
|
|
uint32_t text;
|
|
|
|
|
uint32_t cursor;
|
|
|
|
|
} cursor_color;
|
2019-06-29 21:23:36 +02:00
|
|
|
|
2019-07-10 20:57:09 +02:00
|
|
|
struct {
|
|
|
|
|
struct coord start;
|
|
|
|
|
struct coord end;
|
|
|
|
|
} selection;
|
|
|
|
|
|
2019-08-27 17:23:28 +02:00
|
|
|
bool is_searching;
|
|
|
|
|
struct {
|
|
|
|
|
wchar_t *buf;
|
|
|
|
|
size_t len;
|
|
|
|
|
size_t sz;
|
2019-08-29 21:02:35 +02:00
|
|
|
size_t cursor;
|
2019-08-30 20:15:12 +02:00
|
|
|
enum { SEARCH_BACKWARD, SEARCH_FORWARD} direction;
|
2019-08-27 19:33:19 +02:00
|
|
|
|
|
|
|
|
int original_view;
|
|
|
|
|
bool view_followed_offset;
|
|
|
|
|
struct coord match;
|
|
|
|
|
size_t match_len;
|
2019-08-27 17:23:28 +02:00
|
|
|
} search;
|
|
|
|
|
|
2019-06-29 21:23:36 +02:00
|
|
|
struct grid normal;
|
|
|
|
|
struct grid alt;
|
|
|
|
|
struct grid *grid;
|
2019-07-05 10:16:56 +02:00
|
|
|
|
2019-10-16 21:52:12 +02:00
|
|
|
struct font *fonts[4];
|
2019-07-28 12:39:56 +02:00
|
|
|
struct {
|
|
|
|
|
int height;
|
|
|
|
|
int descent;
|
|
|
|
|
int ascent;
|
|
|
|
|
int max_x_advance;
|
|
|
|
|
} fextents;
|
2019-07-05 10:16:56 +02:00
|
|
|
|
2019-10-27 18:51:14 +01:00
|
|
|
struct wayland *wl;
|
2019-10-27 19:08:48 +01:00
|
|
|
struct wl_window *window;
|
2019-10-27 12:57:37 +01:00
|
|
|
|
2019-07-24 20:11:49 +02:00
|
|
|
struct {
|
2019-08-01 19:28:14 +02:00
|
|
|
int scrollback_lines;
|
2019-07-24 20:21:41 +02:00
|
|
|
|
2019-07-29 20:13:26 +02:00
|
|
|
struct {
|
|
|
|
|
size_t count;
|
|
|
|
|
sem_t start;
|
|
|
|
|
sem_t done;
|
|
|
|
|
cnd_t cond;
|
|
|
|
|
mtx_t lock;
|
|
|
|
|
tll(int) queue;
|
|
|
|
|
thrd_t *threads;
|
|
|
|
|
struct buffer *buf;
|
|
|
|
|
} workers;
|
|
|
|
|
|
2019-07-24 20:21:41 +02:00
|
|
|
/* Last rendered cursor position */
|
|
|
|
|
struct {
|
|
|
|
|
struct coord actual; /* Absolute */
|
|
|
|
|
struct coord in_view; /* Offset by view */
|
2019-07-30 20:18:20 +02:00
|
|
|
struct cell *cell; /* For easy access to content */
|
2019-07-24 20:21:41 +02:00
|
|
|
} last_cursor;
|
|
|
|
|
|
2019-11-02 01:28:29 +01:00
|
|
|
struct buffer *last_buf; /* Buffer we rendered to last time */
|
2019-07-24 20:21:41 +02:00
|
|
|
bool was_flashing; /* Flash was active last time we rendered */
|
2019-08-27 17:23:28 +02:00
|
|
|
bool was_searching;
|
2019-07-24 20:11:49 +02:00
|
|
|
} render;
|
2019-10-27 11:46:18 +01:00
|
|
|
|
|
|
|
|
/* Temporary: for FDM */
|
|
|
|
|
struct {
|
|
|
|
|
bool is_armed;
|
|
|
|
|
int lower_fd;
|
|
|
|
|
int upper_fd;
|
|
|
|
|
} delayed_render_timer;
|
2019-11-01 20:34:32 +01:00
|
|
|
|
|
|
|
|
bool is_shutting_down;
|
|
|
|
|
void (*shutdown_cb)(void *data, int exit_code);
|
|
|
|
|
void *shutdown_data;
|
2019-06-15 22:22:44 +02:00
|
|
|
};
|
2019-06-29 21:03:28 +02:00
|
|
|
|
2019-10-28 18:25:19 +01:00
|
|
|
struct config;
|
|
|
|
|
struct terminal *term_init(
|
|
|
|
|
const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
2019-11-01 21:03:08 +01:00
|
|
|
const char *term_env, int argc, char *const *argv,
|
2019-11-01 20:34:32 +01:00
|
|
|
void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data);
|
|
|
|
|
|
2019-10-30 20:03:11 +01:00
|
|
|
bool term_shutdown(struct terminal *term);
|
2019-10-28 18:25:19 +01:00
|
|
|
int term_destroy(struct terminal *term);
|
|
|
|
|
|
2019-08-01 20:51:11 +02:00
|
|
|
void term_reset(struct terminal *term, bool hard);
|
|
|
|
|
|
2019-07-11 09:51:51 +02:00
|
|
|
void term_damage_rows(struct terminal *term, int start, int end);
|
|
|
|
|
void term_damage_rows_in_view(struct terminal *term, int start, int end);
|
|
|
|
|
|
2019-06-29 21:03:28 +02:00
|
|
|
void term_damage_all(struct terminal *term);
|
2019-07-10 14:32:40 +02:00
|
|
|
void term_damage_view(struct terminal *term);
|
2019-07-11 09:51:51 +02:00
|
|
|
|
2019-08-28 17:25:42 +02:00
|
|
|
void term_reset_view(struct terminal *term);
|
|
|
|
|
|
2019-06-29 21:03:28 +02:00
|
|
|
void term_damage_scroll(
|
|
|
|
|
struct terminal *term, enum damage_type damage_type,
|
|
|
|
|
struct scroll_region region, int lines);
|
|
|
|
|
|
2019-07-08 13:57:31 +02:00
|
|
|
void term_erase(
|
|
|
|
|
struct terminal *term, const struct coord *start, const struct coord *end);
|
2019-06-29 21:03:28 +02:00
|
|
|
|
|
|
|
|
void term_cursor_to(struct terminal *term, int row, int col);
|
|
|
|
|
void term_cursor_left(struct terminal *term, int count);
|
|
|
|
|
void term_cursor_right(struct terminal *term, int count);
|
|
|
|
|
void term_cursor_up(struct terminal *term, int count);
|
|
|
|
|
void term_cursor_down(struct terminal *term, int count);
|
|
|
|
|
|
|
|
|
|
void term_scroll(struct terminal *term, int rows);
|
|
|
|
|
void term_scroll_reverse(struct terminal *term, int rows);
|
|
|
|
|
|
|
|
|
|
void term_scroll_partial(
|
|
|
|
|
struct terminal *term, struct scroll_region region, int rows);
|
|
|
|
|
void term_scroll_reverse_partial(
|
|
|
|
|
struct terminal *term, struct scroll_region region, int rows);
|
|
|
|
|
|
2019-07-10 16:02:03 +02:00
|
|
|
void term_linefeed(struct terminal *term);
|
|
|
|
|
void term_reverse_index(struct terminal *term);
|
|
|
|
|
|
2019-07-23 17:57:07 +02:00
|
|
|
void term_restore_cursor(struct terminal *term);
|
|
|
|
|
|
2019-07-16 10:34:08 +02:00
|
|
|
void term_focus_in(struct terminal *term);
|
|
|
|
|
void term_focus_out(struct terminal *term);
|
2019-07-05 14:24:51 +02:00
|
|
|
void term_mouse_down(struct terminal *term, int button, int row, int col,
|
|
|
|
|
bool shift, bool alt, bool ctrl);
|
|
|
|
|
void term_mouse_up(struct terminal *term, int button, int row, int col,
|
|
|
|
|
bool shift, bool alt, bool ctrl);
|
2019-07-05 15:13:06 +02:00
|
|
|
void term_mouse_motion(struct terminal *term, int button, int row, int col,
|
|
|
|
|
bool shift, bool alt, bool ctrl);
|
2019-07-21 17:35:53 +02:00
|
|
|
|
|
|
|
|
void term_set_window_title(struct terminal *term, const char *title);
|
2019-07-30 22:06:02 +02:00
|
|
|
void term_flash(struct terminal *term, unsigned duration_ms);
|