From dcebf9c7f954a55350b68d0ead1935612c4e2e05 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Thu, 15 Oct 2026 13:04:01 +0300 Subject: Rename the library to wsap_vtcore ncurses installs and defines struct term. In a file that includes both headers, an ncurses TERMINAL * and this library's terminal are silently the same type. The name wsap_vtcore avoids the clash. The public header is now . Every global symbol uses the wsap_vtcore_ prefix, every macro uses WSAP_VTCORE_, and the shared library is libwsap_vtcore.so.0. The default terminal name is now "wsap_vtcore". The ISA override variable is WSAP_VTCORE_ISA. No other behavior changes. The amalgamation writes wsap_vtcore.c and wsap_vtcore.h. Co-Authored-By: Claude Haiku 5.5 --- include/term/term.h | 492 ---------------------------------------------------- 1 file changed, 492 deletions(-) delete mode 100644 include/term/term.h (limited to 'include/term/term.h') 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 -#include -#include - -#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 -- cgit v1.2.3