summaryrefslogtreecommitdiff
path: root/include/term/term.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/term/term.h')
-rw-r--r--include/term/term.h492
1 files changed, 0 insertions, 492 deletions
diff --git a/include/term/term.h b/include/term/term.h
deleted file mode 100644
index 8b98a25..0000000
--- a/include/term/term.h
+++ /dev/null
@@ -1,492 +0,0 @@
-#ifndef TERM_H
-#define TERM_H
-
-/*
- * Terminal emulator core.
- *
- * A struct term parses the bytes that a program writes and keeps the screen,
- * the history, and the modes. The application feeds bytes with term_feed()
- * and reads state with the getters below. A renderer never reads the
- * terminal directly: it copies the viewport into a struct term_snapshot and
- * paints from that copy.
- *
- * All functions take the terminal as the first argument. Functions that take
- * a const struct term do not change what it shows. Selection, history, link,
- * directory, and pointer-shape queries return owned strings; release them
- * with term_text_free().
- *
- * Threads. Any thread can call any function. Each call that reads or changes
- * a terminal enters its writer section, so calls on one terminal run one at a
- * time. A thread that waits for the section sleeps. On POSIX the section is a
- * mutex with priority inheritance where the platform has it. A snapshot
- * belongs to one thread at a time. term_free() is the last call on a terminal.
- */
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "term_input.h"
-#include "term_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct term;
-struct term_snapshot;
-
-/* A row holds at most this many cells. */
-#define TERM_MAX_COLS 65535
-/* The history limit when term_options.scrollback is 0. */
-#define TERM_SCROLLBACK_DEFAULT 10000
-/* The largest term_options.scrollback. */
-#define TERM_SCROLLBACK_MAX 1000000
-
-/*
- * The version of this header. A host compares TERM_VERSION_CODE with
- * term_version() to check that the library matches the header.
- */
-#define TERM_VERSION(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch))
-#define TERM_VERSION_MAJOR 0
-#define TERM_VERSION_MINOR 1
-#define TERM_VERSION_PATCH 0
-#define TERM_VERSION_CODE TERM_VERSION(TERM_VERSION_MAJOR, TERM_VERSION_MINOR, TERM_VERSION_PATCH)
-
-/*
- * Colors. A term_color is either a direct color (alpha 0xFF, then RGB) or a
- * palette slot: an index 0-255, the default foreground, or the default
- * background. A slot resolves when a snapshot is painted, so a theme change
- * recolors text that is already on screen.
- */
-typedef uint32_t term_color;
-
-#define TERM_COLOR_SLOT 0x01000000u
-/* The palette index of a slot; see struct term_view.palette. */
-#define TERM_COLOR_SLOT_INDEX 0x1FFu
-#define TERM_COLOR_FG (TERM_COLOR_SLOT | 0x100u)
-#define TERM_COLOR_BG (TERM_COLOR_SLOT | 0x101u)
-
-static inline term_color term_color_index(int n)
-{
- return TERM_COLOR_SLOT | ((uint32_t)n & 0xFFu);
-}
-
-static inline term_color term_color_rgb(uint8_t r, uint8_t g, uint8_t b)
-{
- return 0xFF000000u | (uint32_t)r << 16 | (uint32_t)g << 8 | b;
-}
-
-static inline bool term_color_is_slot(term_color c)
-{
- return (c >> 24) == (TERM_COLOR_SLOT >> 24);
-}
-
-/* Parse an X11 or OSC color specification ("#rgb", "rgb:r/g/b", ...). */
-TERM_API bool term_color_parse(const char *spec, uint32_t *argb);
-
-/* The colors a terminal starts with. All values are ARGB. An all-zero theme
- * selects the built-in theme. */
-struct term_theme {
- uint32_t fg, bg, cursor;
- uint32_t ansi[16];
-};
-
-/* Fill theme with the built-in theme. */
-TERM_API void term_theme_default(struct term_theme *theme);
-/* Fill theme with the high-contrast theme. */
-TERM_API void term_theme_high_contrast(struct term_theme *theme);
-/* Sets one palette key: foreground, background, or color0 to color15.
- * An empty value resets the key to the built-in theme. False, with no
- * change, for an unknown key or a bad color. */
-TERM_API bool term_theme_set_key(struct term_theme *p, const char *key, const char *val);
-
-enum term_cursor_style {
- TERM_CURSOR_BLOCK,
- TERM_CURSOR_UNDERLINE,
- TERM_CURSOR_BAR,
-};
-
-/* Mouse reporting modes and encodings. The values are the DEC mode numbers. */
-enum term_mouse {
- TERM_MOUSE_OFF = 0,
- TERM_MOUSE_X10 = 9,
- TERM_MOUSE_NORMAL = 1000,
- TERM_MOUSE_BUTTON = 1002,
- TERM_MOUSE_ANY = 1003,
-};
-
-enum term_mouse_encoding {
- TERM_MOUSE_ENC_X10 = 0,
- TERM_MOUSE_ENC_UTF8 = 1005,
- TERM_MOUSE_ENC_SGR = 1006,
- TERM_MOUSE_ENC_URXVT = 1015,
- TERM_MOUSE_ENC_SGR_PIXELS = 1016,
-};
-
-/*
- * Callbacks. They run inside term_feed() and term_focus(), on the thread
- * that calls those functions. A callback must not call back into the
- * terminal. String arguments are valid only during the call.
- */
-struct term_callbacks {
- void *ud;
- /* Bytes the terminal sends back to the program (replies to queries). */
- void (*reply)(void *ud, const char *bytes, size_t len);
- void (*title)(void *ud, const char *title);
- /*
- * OSC 52 clipboard callback.
- * selection names the target clipboard buffer(s), commonly:
- * "c" - clipboard (system clipboard)
- * "p" - primary selection (X11 primary)
- * "q" - secondary selection
- * "s" - select selection
- * "0".."7" - cut buffers 0 to 7
- * A parameter may contain multiple targets (e.g. "cp").
- * data contains decoded bytes of length len.
- */
- void (*clipboard)(void *ud, const char *selection, const char *data, size_t len);
- void (*notify)(void *ud, const char *title, const char *body);
- void (*bell)(void *ud);
- /* Parser trace lines for debugging. NULL turns tracing off. The line has no newline. */
- void (*trace)(void *ud, const char *line);
-};
-
-/*
- * Options for term_new(). An all-zero value is valid. A size component of 0
- * selects 80 columns or 24 rows. A negative component, or columns above
- * TERM_MAX_COLS, makes term_new() fail. A scrollback below 0 or above
- * TERM_SCROLLBACK_MAX fails too.
- * cursor_style must be a value of enum term_cursor_style.
- */
-struct term_options {
- struct term_vector2i size; /* columns and rows */
- int scrollback; /* history lines; 0 selects TERM_SCROLLBACK_DEFAULT */
- struct term_theme theme;
- enum term_cursor_style cursor_style;
- bool cursor_steady; /* false: the cursor blinks */
- /*
- * The terminal's name. Programs read it with XTVERSION and XTGETTCAP.
- * It is also the title of a notification that has none. NULL or ""
- * selects "term". Otherwise 1 to 63 printable ASCII bytes, or term_new()
- * returns NULL. term_new() copies the name.
- */
- const char *name;
- struct term_callbacks callbacks;
- /* Must be zero. term_new() returns NULL if any word is nonzero, so a
- * later version can give a word a meaning. */
- uint32_t reserved[8];
-};
-
-/* The Unicode version of the width tables, such as "18.0.0". A host can
- * pass it to programs as UNICODE_VERSION. */
-TERM_API const char *term_unicode_version(void);
-/* The TERM_VERSION_CODE the library was built with. */
-TERM_API unsigned term_version(void);
-
-/* The length of the prefix of buf made of bytes in [0x20, hi). With hi
- * 0x7f, it finds a run of printable ASCII in UTF-8 text, so a host can
- * skip shaping for it. Any thread can call it. */
-TERM_API size_t term_scan_printable_span(const char *buf, size_t len, unsigned char hi);
-
-/* The instruction set level of the running code: "base", "avx2", "avx512",
- * or "neon". On x86-64, the first term_new() picks the highest level the CPU
- * supports. Set TERM_HEADLESS_ISA to a lower level to force it, for tests
- * and comparisons. */
-TERM_API const char *term_isa(void);
-
-/* NULL when memory runs out or an option is invalid. */
-TERM_API struct term *term_new(const struct term_options *opt);
-TERM_API void term_free(struct term *t);
-
-/* Hold the writer section across several calls, so that no other thread
- * changes the terminal between them. The section is a mutex, and a waiting
- * thread sleeps. Keep it short. The thread that holds it can call every
- * function, and it can enter the section again. Each term_lock() needs one
- * term_unlock(). */
-TERM_API void term_lock(struct term *t);
-TERM_API void term_unlock(struct term *t);
-
-/* Change the size in cells. Returns false, and the terminal is unchanged,
- * when a component is below 1, when cols is above TERM_MAX_COLS, or when
- * memory runs out. The screen reflows to the new width. */
-TERM_API bool term_resize(struct term *t, struct term_vector2i size);
-
-/* Replace the theme. A different theme also drops the colors that the
- * program set with OSC; the same theme changes nothing. */
-TERM_API void term_set_theme(struct term *t, const struct term_theme *theme);
-
-/* The cursor style that DECSCUSR 0 and a reset restore. */
-TERM_API void term_set_cursor_default(struct term *t, enum term_cursor_style style, bool steady);
-
-/*
- * Bytes from the program.
- *
- * TERM_FEED_ONLCR: a line feed also returns the cursor to column 0, as a tty
- * with OPOST and ONLCR does. Set it when the bytes did not pass through the
- * tty output processing (for example the fast pipe).
- */
-enum term_feed_flags {
- TERM_FEED_ONLCR = 1u << 0,
-};
-
-/*
- * Feed bytes from the program. Returns false, and changes nothing, when t is
- * NULL, when bytes is NULL and len is not 0, or when flags has a bit that is
- * not in enum term_feed_flags. A len of 0 is a no-op that returns true.
- */
-TERM_API bool term_feed(struct term *t, const char *bytes, size_t len, unsigned flags);
-
-/* Report a focus change. The terminal replies only in focus-event mode. */
-TERM_API void term_focus(struct term *t, bool focused);
-
-/* Modes that affect how the application encodes input. */
-struct term_modes {
- unsigned keyboard; /* kitty keyboard protocol flags */
- enum term_mouse mouse;
- enum term_mouse_encoding mouse_encoding;
- struct term_vector2i grid; /* columns and rows */
- bool app_cursor; /* DECCKM */
- bool app_keypad; /* DECKPAM */
- bool backarrow_bs; /* DECBKM */
- bool bracketed_paste;
- bool focus_events;
- bool alternate; /* the alternate screen is active */
- bool reverse_video; /* DECSCNM */
- bool synchronized; /* mode 2026 */
-};
-
-struct term_cursor {
- struct term_vector2i pos;
- enum term_cursor_style style;
- bool visible;
- bool blink;
-};
-
-TERM_API struct term_vector2i term_size(const struct term *t);
-TERM_API struct term_modes term_modes(const struct term *t);
-
-/*
- * Encode an input event as the bytes the program expects. Get modes from
- * term_modes(). Record ev in keyboard with term_keyboard_update() first. Send
- * the bytes to the program yourself.
- */
-TERM_API struct term_input_result term_input_encode_key(
- const struct term_keyboard_state *keyboard,
- const struct term_key_event *ev,
- const struct term_modes *modes,
- char *buf, size_t capacity
-);
-
-TERM_API struct term_input_result term_input_encode_mouse(
- const struct term_mouse_event *ev,
- const struct term_modes *modes,
- char *buf, size_t capacity
-);
-
-/* Bytes term_input_encode_paste() adds to the text at most. */
-#define TERM_PASTE_EXTRA 12
-
-/*
- * Encode pasted text. Drop control characters and bidi controls, so the
- * program sees only what the user saw. Send a line break as CR. Add the
- * bracketed-paste markers when the program asked for them. A buffer of
- * len + TERM_PASTE_EXTRA bytes is always large enough. Text that is empty
- * after the filter gives TERM_INPUT_CONSUMED.
- */
-TERM_API struct term_input_result term_input_encode_paste(
- const struct term_modes *modes,
- const char *text, size_t len,
- char *buf, size_t capacity
-);
-/* The cursor in screen coordinates (not the viewport). */
-TERM_API struct term_cursor term_cursor(const struct term *t);
-/* Owned, NUL-terminated text from OSC 7 and OSC 22. NULL when unavailable
- * or allocation fails. The strings stay valid after the terminal changes
- * or is freed. Release them with term_text_free(). */
-TERM_API char *term_cwd(const struct term *t);
-TERM_API char *term_pointer_shape(const struct term *t);
-/* Release any owned text returned by the library. NULL is safe. */
-TERM_API void term_text_free(char *text);
-
-/*
- * Viewport. The viewport shows as many rows as the screen. Offset 0 shows
- * the live screen; a larger offset shows that many rows of history above it.
- * The alternate screen has no history, so its offset is always 0.
- */
-struct term_scrollback {
- int offset; /* rows between the viewport and the live screen */
- int total; /* history rows at the current width */
-};
-
-TERM_API struct term_scrollback term_scrollback(const struct term *t);
-/* Scroll the viewport. A positive count moves back into history. */
-TERM_API void term_scroll(struct term *t, int lines);
-TERM_API void term_scroll_to(struct term *t, int offset);
-
-/*
- * Selection, in viewport coordinates. A selection starts at one cell and
- * extends to another; the unit widens both ends to words or whole lines.
- * The terminal clears the selection when the text under it changes.
- */
-enum term_select_unit {
- TERM_SELECT_CELL,
- TERM_SELECT_WORD,
- TERM_SELECT_LINE,
-};
-
-/* Start a selection at cell. For TERM_SELECT_CELL, right_half means the
- * pointer is on the right half of the cell, so the selection starts after it.
- * Returns false when memory runs out; the selection is then unchanged. */
-TERM_API bool term_select_start(struct term *t, struct term_vector2i cell, bool right_half,
- enum term_select_unit unit);
-/* Extend the selection from its start to cell. Returns false when memory runs
- * out; the selection is then unchanged. */
-TERM_API bool term_select_extend(struct term *t, struct term_vector2i cell, bool right_half);
-TERM_API void term_select_clear(struct term *t);
-TERM_API bool term_has_selection(const struct term *t);
-/* Owned, NUL-terminated UTF-8 of the selection. NULL when nothing is
- * selected or allocation fails; a selection of blanks may produce an empty
- * string. Capture is atomic with respect to other calls on t. Release the
- * result with term_text_free(). */
-TERM_API char *term_selection_text(const struct term *t);
-/* Owned OSC 8 link or detected URL at a viewport cell. NULL when there is
- * no link or allocation fails. Release the result with term_text_free(). */
-TERM_API char *term_link_at(const struct term *t, struct term_vector2i cell);
-
-/* Cell attributes share the write core's bit layout. Underline styles are
- * mutually exclusive flags, not a shifted enum; use term_attr_underline(). */
-enum term_attr {
- TERM_ATTR_BOLD = 1u << 0,
- TERM_ATTR_ITALIC = 1u << 1,
- TERM_ATTR_UNDERLINE = 1u << 2,
- TERM_ATTR_STRIKE = 1u << 3,
- TERM_ATTR_OVERLINE = 1u << 4,
- TERM_ATTR_EMOJI = 1u << 5, /* the text requested emoji presentation */
- TERM_ATTR_TEXT = 1u << 6, /* the text requested text presentation */
- TERM_ATTR_FAINT = 1u << 10,
- TERM_ATTR_DOUBLE_UNDERLINE = 1u << 11,
- TERM_ATTR_CURLY_UNDERLINE = 1u << 12,
- TERM_ATTR_DOTTED_UNDERLINE = 1u << 13,
- TERM_ATTR_DASHED_UNDERLINE = 1u << 14,
- TERM_ATTR_LINK = 1u << 15,
-};
-
-#define TERM_ATTR_UNDERLINE_MASK \
- (TERM_ATTR_UNDERLINE | TERM_ATTR_DOUBLE_UNDERLINE | TERM_ATTR_CURLY_UNDERLINE | \
- TERM_ATTR_DOTTED_UNDERLINE | TERM_ATTR_DASHED_UNDERLINE)
-
-enum term_underline {
- TERM_UNDERLINE_NONE,
- TERM_UNDERLINE_SINGLE,
- TERM_UNDERLINE_DOUBLE,
- TERM_UNDERLINE_CURLY,
- TERM_UNDERLINE_DOTTED,
- TERM_UNDERLINE_DASHED,
-};
-
-static inline enum term_underline term_attr_underline(uint16_t attrs)
-{
- if (attrs & TERM_ATTR_DOUBLE_UNDERLINE) return TERM_UNDERLINE_DOUBLE;
- if (attrs & TERM_ATTR_CURLY_UNDERLINE) return TERM_UNDERLINE_CURLY;
- if (attrs & TERM_ATTR_DOTTED_UNDERLINE) return TERM_UNDERLINE_DOTTED;
- if (attrs & TERM_ATTR_DASHED_UNDERLINE) return TERM_UNDERLINE_DASHED;
- return attrs & TERM_ATTR_UNDERLINE ? TERM_UNDERLINE_SINGLE : TERM_UNDERLINE_NONE;
-}
-
-/* text refers to a grapheme cluster in the snapshot; see term_snapshot_cluster(). */
-#define TERM_TEXT_CLUSTER 0x80000000u
-
-/* One cell as a snapshot shows it. */
-struct term_cell {
- uint32_t text; /* a code point, TERM_TEXT_CLUSTER | n, or 0 for an empty cell */
- term_color fg, bg;
- uint16_t attrs; /* enum term_attr flags; at most one underline flag */
- uint8_t width; /* 1; 2 for a wide glyph; 0 for the right half of a wide glyph */
- uint8_t reserved;
-};
-
-#ifdef __cplusplus
-static_assert(sizeof(struct term_cell) == 16, "four cells fill one 64-byte line");
-#else
-_Static_assert(sizeof(struct term_cell) == 16, "four cells fill one 64-byte line");
-#endif
-
-/*
- * Snapshot: a copy of the viewport for a renderer. It holds no pointer into
- * the terminal, so it stays valid while the terminal changes. One terminal
- * may have several snapshots, for example a window and a tab preview.
- */
-TERM_API struct term_snapshot *term_snapshot_new(void);
-TERM_API void term_snapshot_free(struct term_snapshot *s);
-
-/* Copy the viewport of t into s. Keep rows with unchanged content keys.
- * Update the history view index and refine counts for visible wide lines.
- * Return false when memory runs out. The snapshot then keeps its previous content. */
-TERM_API bool term_snapshot_update(struct term_snapshot *s, struct term *t);
-
-/* Palette entries of struct term_view.palette after the 256 indexed colors. */
-enum {
- TERM_PALETTE_FG = 256,
- TERM_PALETTE_BG = 257,
- TERM_PALETTE_CURSOR = 258,
- TERM_PALETTE_SIZE = 259,
-};
-
-struct term_view {
- struct term_vector2i size;
- struct term_cursor cursor; /* viewport coordinates; not visible when scrolled away */
- int scroll_offset;
- /* Rows the content moved up since the previous update, when that movement
- * explains the change; otherwise 0. */
- int scrolled;
- bool reverse_video;
- /* Changes when any part of the view changes. */
- uint64_t version;
- /* Changes when a palette entry changes. */
- uint64_t palette_version;
- const uint32_t *palette; /* TERM_PALETTE_SIZE ARGB entries */
-};
-
-/* The view of s, NULL for a NULL s. The view and view->palette keep their
- * address until term_snapshot_free(); their contents change on each update. */
-TERM_API const struct term_view *term_snapshot_view(const struct term_snapshot *s);
-/* The cells of viewport row y: view->size.x entries. NULL when y is outside
- * the viewport or s is NULL. An update can move the cells, so the pointer is
- * valid only until the next term_snapshot_update() or term_snapshot_free() of s. */
-TERM_API const struct term_cell *term_snapshot_row(const struct term_snapshot *s, int y);
-/* An identity for the content of row y. Two rows with the same key hold the
- * same cells, also when the content moved to another row. 0 when y is outside
- * the viewport or s is NULL. */
-TERM_API uint64_t term_snapshot_row_key(const struct term_snapshot *s, int y);
-
-/* Number of rows in history above the screen. 0 if alternate screen or no history. */
-TERM_API int term_history_rows(const struct term *t);
-/* Owned, NUL-terminated UTF-8 of up to max_rows history rows before the
- * current viewport. Join soft-wrapped rows and end closed lines with a
- * newline. Does not change the selection. No history or max_rows <= 0 gives
- * an empty string; NULL means allocation failed or t is NULL. Release the
- * result with term_text_free(). */
-TERM_API char *term_history_text(struct term *t, int max_rows);
-/* The selected columns of viewport row y, end exclusive. An empty span when y
- * is outside the viewport or s is NULL. */
-TERM_API struct term_span term_snapshot_row_selection(const struct term_snapshot *s, int y);
-
-/* The code points of a cluster cell. Returns the number of code points and
- * writes at most cap of them. Writes nothing when cps is NULL or cap is 0.
- * Returns 0 when s is NULL. */
-TERM_API int term_snapshot_cluster(const struct term_snapshot *s, uint32_t text, uint32_t *cps, int cap);
-
-/* The ARGB value of a color in a view. */
-static inline uint32_t term_view_color(const struct term_view *v, term_color c)
-{
- if (!term_color_is_slot(c))
- return c;
- return v->palette[c & TERM_COLOR_SLOT_INDEX];
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif