From 4384435941b8c7658856b381d071aee2e0035e89 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 17:49:34 +0300 Subject: term: move the term core to subprojects/term The core now builds, tests, and benchmarks alone, as a Meson subproject with no dependency on the main tree. - include/term/ holds term.h and the header-only unicode/. src/ holds the core and its private headers. The main tree gets only include/term through term_dep, so it cannot reach a private header. - The term tests, the term benchmarks, the Kitty parser suite, and tools/amalgamate.py and tools/generate_unicode.py move with it. The tests run as term:. - The main build passes its -march (arch_flag) and b_ndebug to the subproject. A directory configured before this commit needs meson configure -Dterm:arch_flag=-march=... once. - The term tests compile with -UNDEBUG. They do work inside assert. - The subproject exports term_test_dep with term_api.h, for the main tree's render, thumbnail, color, and selection tests. - The Kitty bridge used struct vector2i and has not compiled since the public API redesign. It builds again. 2 of its 14 tests fail: REP after a tab, and a cursor report after a resize. - dirgraph.py drops the term and unicode layers. Its self-test uses pty. - The symbols test ignores the __odr_asan symbols that ASan adds. Co-Authored-By: Claude Opus 5.5 --- src/term.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/term.c (limited to 'src/term.c') diff --git a/src/term.c b/src/term.c new file mode 100644 index 0000000..583bdd8 --- /dev/null +++ b/src/term.c @@ -0,0 +1,125 @@ +#include "internal.h" +#include "screen.h" + +_Thread_local char term_thread_anchor; + +const char *term_unicode_version(void) +{ + return UNICODE_DATA_VERSION; +} + +void term_lock(struct term *t) +{ + term_write_begin(t); +} + +void term_unlock(struct term *t) +{ + term_write_end(t); +} + +struct term_vector2i term_size(const struct term *t) +{ + if (!t) + return (struct term_vector2i){ 0 }; + term_write_begin((struct term *)t); + struct term_vector2i size = { .x = t->cols, .y = t->rows }; + term_write_end((struct term *)t); + return size; +} + +struct term_modes term_modes(const struct term *t) +{ + if (!t) + return (struct term_modes){ 0 }; + term_write_begin((struct term *)t); + struct term_modes m = { + .keyboard = t->keyboard[t->alternate].flags, + .mouse = (enum term_mouse)t->mouse_mode, + .mouse_encoding = (enum term_mouse_encoding)t->mouse_encoding, + .grid = { .x = t->cols, .y = t->rows }, + .app_cursor = t->application_cursor, + .app_keypad = t->application_keypad, + .backarrow_bs = t->backarrow_sends_bs, + .bracketed_paste = t->bracketed_paste, + .focus_events = t->focus_events, + .alternate = t->alternate, + .reverse_video = t->reverse_video, + .synchronized = t->synchronized_output, + }; + term_write_end((struct term *)t); + return m; +} + +struct term_cursor term_cursor(const struct term *t) +{ + if (!t) + return (struct term_cursor){ .visible = true }; + term_write_begin((struct term *)t); + struct term_cursor c = { + .pos = { .x = t->cursor_x, .y = t->cursor_y }, + .style = t->cursor_style, + .visible = t->cursor_visible, + .blink = t->cursor_blink, + }; + term_write_end((struct term *)t); + return c; +} + +void term_set_cursor_default(struct term *t, enum term_cursor_style style, bool steady) +{ + if (!t) + return; + term_write_begin(t); + if (style > TERM_CURSOR_BAR) + style = TERM_CURSOR_BLOCK; + if (t->cursor_style != style || t->cursor_blink == steady) { + struct srow *cur = term_row(t, t->cursor_y); + if (cur) cur->version++; + } + t->default_cursor_style = t->cursor_style = style; + t->default_cursor_blink = t->cursor_blink = !steady; + term_write_end(t); +} + +void term_set_theme(struct term *t, const struct term_theme *theme) +{ + if (!t) + return; + term_write_begin(t); + struct palette next = { .version = t->palette.version }; + term_palette_init(&next, theme); + if (memcmp(&next.theme, &t->palette.theme, sizeof(next.theme))) + t->palette = next; + term_write_end(t); +} + +void term_focus(struct term *t, bool focused) +{ + if (!t) + return; + term_write_begin(t); + if (t->focus_events) + send_response(t, focused ? "\033[I" : "\033[O"); + term_write_end(t); +} + +size_t term_cwd(const struct term *t, char *buf, size_t cap) +{ + if (!t) + return term_copy_out(NULL, buf, cap); + term_write_begin((struct term *)t); + size_t n = term_copy_out(t->cwd, buf, cap); + term_write_end((struct term *)t); + return n; +} + +size_t term_pointer_shape(const struct term *t, char *buf, size_t cap) +{ + if (!t) + return term_copy_out(NULL, buf, cap); + term_write_begin((struct term *)t); + size_t n = term_copy_out(t->pointer_shape, buf, cap); + term_write_end((struct term *)t); + return n; +} -- cgit v1.2.3