From 513bf031a589d9e2a1a2730adf56f95e5e316a06 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Wed, 14 Oct 2026 17:17:43 +0300 Subject: Remove unused private functions and inline trivial helpers --- src/compat.h | 9 ---- src/core.c | 40 +---------------- src/core.h | 21 --------- src/escape.c | 41 ++++++++---------- src/hist.c | 65 ++++------------------------ src/hist.h | 7 --- src/hist_view.c | 22 ++-------- src/hist_view.h | 3 -- src/input.c | 125 +++++++++++++++++------------------------------------ src/internal.h | 7 +-- src/osc/dispatch.c | 12 +---- src/osc/osc.h | 3 -- src/palette.c | 45 +++++-------------- src/palette.h | 5 --- src/screen.c | 68 +++++------------------------ src/screen.h | 14 ++---- src/selection.c | 6 +-- src/text.c | 34 ++++++--------- 18 files changed, 114 insertions(+), 413 deletions(-) (limited to 'src') diff --git a/src/compat.h b/src/compat.h index dc345d0..cb62679 100644 --- a/src/compat.h +++ b/src/compat.h @@ -144,15 +144,6 @@ static inline uint64_t term_next_pow2_64(uint64_t x) return (x <= 1) ? 1 : (lz == 0 ? UINT64_MAX : res); } -static inline size_t term_next_pow2(size_t x) -{ -#if SIZE_MAX > UINT32_MAX - return (size_t)term_next_pow2_64(x); -#else - return (size_t)term_next_pow2_32((uint32_t)x); -#endif -} - /* Grows cap by doubling until >= need, branchlessly. * If cap >= need, returns cap. Otherwise returns next power of two >= need. */ static inline uint32_t term_grow_cap32(uint32_t cap, uint32_t need) diff --git a/src/core.c b/src/core.c index f9d547d..7bca76e 100644 --- a/src/core.c +++ b/src/core.c @@ -356,16 +356,6 @@ void term_sc_tab(struct term *t, int n) if (cur) cur->version++; } -void term_sc_scroll_region(struct term *t, int top, int bottom, int n, bool down) -{ - term_screen_scroll_region(t, top, bottom, n, down, false); -} - -void term_sc_scroll(struct term *t, int n, bool down) -{ - term_screen_scroll_region(t, t->scroll_top, t->scroll_bottom, n, down, true); -} - #define CELL_SGR_FLAGS (CELL_BOLD | CELL_FAINT | CELL_ITALIC | \ CELL_STRIKE | CELL_OVERLINE | CELL_ANY_UNDERLINE) @@ -510,20 +500,6 @@ void term_sc_reset(struct term *t) t->full_gen++; } -void term_sc_set_reverse_video(struct term *t, bool enabled) -{ - if (t->reverse_video != enabled) { - t->reverse_video = enabled; - t->full_gen++; - } -} - -void term_sc_set_autowrap(struct term *t, bool enabled) -{ - t->autowrap = enabled; - t->pending_wrap = false; -} - void term_sc_set_cursor_style(struct term *t, int ps) { if (ps == 0) { @@ -537,13 +513,6 @@ void term_sc_set_cursor_style(struct term *t, int ps) term_row(t, t->cursor_y)->version++; } -static inline int newline_bytes(const char *buf, size_t len) -{ - if (len >= 2 && buf[0] == '\r' && buf[1] == '\n') return 2; - if (len >= 1 && buf[0] == '\n') return 1; - return 0; -} - static inline bool next_byte_wraps(const char *buf, size_t len, size_t pos, uint32_t last) { if (pos >= len) return false; @@ -1289,15 +1258,8 @@ narrow_done: continue; } - if (!run) { - int neol = newline_bytes(buf + i, len - i); - if (neol == 2 || (neol == 1 && lnm)) { - emit_stream_row(&ctx, buf + i, 0, false); - i += (size_t)neol; - continue; - } + if (!run) break; - } bool wrapped = run == cols && autowrap && next_byte_wraps(buf, len, i + (size_t)run, diff --git a/src/core.h b/src/core.h index aab2cde..823a57d 100644 --- a/src/core.h +++ b/src/core.h @@ -117,15 +117,6 @@ static inline void sc_move(struct term *t, int x, int y) /* Advance cursor by n tab stops. */ void term_sc_tab(struct term *t, int n); -/* Move cursor back one column. */ -static inline void sc_bs(struct term *t) -{ - t->pending_wrap = false; - if (t->cursor_x > 0) - t->cursor_x--; - term_row(t, t->cursor_y)->version++; -} - /* Erase cells in span [from, to) on physical row y. */ static inline void sc_erase_span(struct term *t, int y, int from, int to) { @@ -136,12 +127,6 @@ static inline void sc_erase_span(struct term *t, int y, int from, int to) t->scr.slot[p].version++; } -/* Scroll margins: top to bottom, n lines up or down. */ -void term_sc_scroll_region(struct term *t, int top, int bottom, int n, bool down); - -/* Scroll the active scroll region up or down by n lines (with history). */ -void term_sc_scroll(struct term *t, int n, bool down); - /* Restore saved cursor state and position. */ static inline void sc_restore_cursor(struct term *t, const struct term_saved_cursor *s) { @@ -159,12 +144,6 @@ void term_sc_decaln(struct term *t); /* Reset screen and cursor state for full reset (RIS). */ void term_sc_reset(struct term *t); -/* Set reverse video mode (DECSCNM). */ -void term_sc_set_reverse_video(struct term *t, bool enabled); - -/* Set autowrap mode (DECAWM). */ -void term_sc_set_autowrap(struct term *t, bool enabled); - /* Set cursor style (DECSCUSR). */ void term_sc_set_cursor_style(struct term *t, int ps); diff --git a/src/escape.c b/src/escape.c index 7956017..da0449a 100644 --- a/src/escape.c +++ b/src/escape.c @@ -20,7 +20,8 @@ static int sgr_color_param(const struct term *t, char *buf, size_t sz, int base, return snprintf(buf, sz, ";%d", i < 8 ? base + i : base + 60 + i - 8); return snprintf(buf, sz, ";%d:5:%d", base + 8, i); } - c = palette_resolve(&t->palette, c); + if (term_color_is_slot(c)) + c = t->palette.colors[c & TERM_COLOR_SLOT_INDEX]; return snprintf(buf, sz, ";%d:2:%d:%d:%d", base + 8, (int)((c >> 16) & 0xff), (int)((c >> 8) & 0xff), (int)(c & 0xff)); } @@ -557,12 +558,6 @@ static int mode_get(const struct term *t, int mode, bool priv) return -1; } -static int mode_status(const struct term *t, int mode, bool priv) -{ - int set = mode_get(t, mode, priv); - return set < 0 ? 0 : set ? 1 : 2; -} - static int cursor_top(const struct term *t) { return t->origin_mode ? t->scroll_top : 0; } static int cursor_bottom(const struct term *t) { return t->origin_mode ? t->scroll_bottom : t->rows - 1; } static int cursor_left(const struct term *t) { return t->origin_mode && t->lr_margin_mode ? t->left_margin : 0; } @@ -585,12 +580,16 @@ static void mode_set(struct term *t, int mode, bool enabled, bool priv) default: break; } if (mode == 5) { - term_sc_set_reverse_video(t, enabled); + if (t->reverse_video != enabled) { + t->reverse_video = enabled; + t->full_gen++; + } } else if (mode == 6) { t->origin_mode = enabled; sc_move(t, 0, enabled ? t->scroll_top : 0); } else if (mode == 7) { - term_sc_set_autowrap(t, enabled); + t->autowrap = enabled; + t->pending_wrap = false; } else if (mode == 1048) { if (enabled) t->saved = term_cursor_save(t); else sc_restore_cursor(t, &t->saved); @@ -685,14 +684,16 @@ static inline TERM_ALWAYS_INLINE void dispatch_csi(struct term *t, const struct case 'L': case 'M': if (csi->prefix || t->cursor_y < t->scroll_top || t->cursor_y > t->scroll_bottom) break; - term_sc_scroll_region(t, t->cursor_y, t->scroll_bottom, csi_count(csi), csi->final == 'L'); + term_screen_scroll_region(t, t->cursor_y, t->scroll_bottom, + csi_count(csi), csi->final == 'L', false); /* IL and DL move the cursor to the left margin (xterm). */ sc_move(t, t->lr_margin_mode ? t->left_margin : 0, t->cursor_y); break; case 'S': case 'T': if (csi->prefix || csi->nparams > 1) break; - term_sc_scroll(t, csi_count(csi), csi->final == 'T'); + term_screen_scroll_region(t, t->scroll_top, t->scroll_bottom, + csi_count(csi), csi->final == 'T', true); break; case 'd': { int64_t r = (int64_t)csi_count(csi) - 1 + cursor_top(t); @@ -845,9 +846,10 @@ static inline TERM_ALWAYS_INLINE void dispatch_csi(struct term *t, const struct sc_move(t, 0, 0); } else if (csi->intermediate == '$' && csi->nparams >= 1) { char reply[32]; + int set = mode_get(t, csi->params[0], csi->prefix == '?'); snprintf(reply, sizeof(reply), "\033[%s%d;%d$y", csi->prefix == '?' ? "?" : "", csi->params[0], - mode_status(t, csi->params[0], csi->prefix == '?')); + set < 0 ? 0 : set ? 1 : 2); send_response(t, reply); } break; @@ -935,7 +937,7 @@ static void dispatch_esc(struct term *t, unsigned char ch) break; case 'M': if (t->cursor_y == t->scroll_top) - term_sc_scroll_region(t, t->scroll_top, t->scroll_bottom, 1, true); + term_screen_scroll_region(t, t->scroll_top, t->scroll_bottom, 1, true, false); else sc_move(t, t->cursor_x, t->cursor_y > 0 ? t->cursor_y - 1 : 0); break; @@ -1029,7 +1031,7 @@ void term_escape_byte(struct term *t, unsigned char ch) term_text_ground(t, ch); } else if (term_osc_room(t) || term_osc_grow(t)) { *term_osc_tail(t) = (char)ch; - term_osc_commit(t, 1); + t->osc_len++; } else { t->str_truncated = true; } @@ -1078,21 +1080,16 @@ void term_escape_byte(struct term *t, unsigned char ch) } } -static inline size_t str_appendable_span(const char *buf, size_t len) -{ - return scan_printable_span(buf, len, 0x80); -} - size_t term_escape_str(struct term *t, const char *buf, size_t len) { if (t->state == ST_IGNORE) { - size_t take = str_appendable_span(buf, len); + size_t take = scan_printable_span(buf, len, 0x80); if (take < len) term_escape_byte(t, (unsigned char)buf[take++]); return take; } int is_osc = t->state == ST_OSC; - size_t take = str_appendable_span(buf, len); + size_t take = scan_printable_span(buf, len, 0x80); if (is_osc) { size_t room = term_osc_room(t); if (take > room && term_osc_grow(t)) @@ -1101,7 +1098,7 @@ size_t term_escape_str(struct term *t, const char *buf, size_t len) if (take > room) take = room; memcpy(term_osc_tail(t), buf, take); - term_osc_commit(t, take); + t->osc_len += (int)take; } else { t->str_truncated = true; } diff --git a/src/hist.c b/src/hist.c index 7bd9d04..344cdc8 100644 --- a/src/hist.c +++ b/src/hist.c @@ -106,11 +106,6 @@ static inline bool ring_fit(struct hist *h, uint64_t n) return ring_grow(h, n); } -static inline bool ring_reserve(struct hist *h) -{ - return ring_fit(h, 1); -} - static inline uint64_t cont_at(const struct hist *h, uint32_t i) { return h->cont[(h->cont_first + i) & h->cont_mask]; @@ -756,27 +751,14 @@ void term_hist_runs_emit_slow(struct hist_runs *r) r->len = (uint32_t)(emit_run(r->data + r->len, &r->base, &r->pen, r->count) - r->data); } -static inline void runs_repeat(struct hist_runs *r) -{ - hist_runs_switch(r, text_pen_from_attr(&r->pen)); -} - /* Emit the pending run unless it is a default tail, which readers imply. */ static void runs_finish(struct hist_runs *r) { if (r->count && !pen_attr_is_default(&r->pen)) - runs_repeat(r); + hist_runs_switch(r, text_pen_from_attr(&r->pen)); r->count = 0; } -/* Emit the pending run, default or not, so the next run can use it as its - * delta base. */ -static void runs_flush(struct hist_runs *r) -{ - if (r->count) - runs_repeat(r); -} - /* ---- Encoding ---- */ static inline size_t put_utf8(uint8_t *dst, uint32_t cp) @@ -1310,7 +1292,7 @@ static bool push_line(struct hist *h, const struct cell *cells, int len, const c size_t runs_need = ascii ? RUN_MAX * 2 : (size_t)(len + 2) * RUN_MAX; size_t text_need = ascii ? (size_t)len : (size_t)len * CELL_BYTES; int pg = page_for(h, text_need + runs_need + RUN_MAX); - if (pg < 0 || !ring_reserve(h) || !runs_reserve(&h->runs, runs_need + RUN_MAX)) + if (pg < 0 || !ring_fit(h, 1) || !runs_reserve(&h->runs, runs_need + RUN_MAX)) return false; uint32_t off = h->page_used[pg]; uint8_t *dst = h->pages[pg] + off; @@ -1393,7 +1375,7 @@ static struct hline *begin_line(struct hist *h, size_t need) if (h->lines >= h->line_limit) evict_line(h); int pg = page_for(h, need); - if (pg < 0 || !ring_reserve(h)) + if (pg < 0 || !ring_fit(h, 1)) return NULL; struct hline *p = part(h, h->head++); *p = (struct hline){ @@ -1527,7 +1509,7 @@ static struct hline *open_room(struct hist *h, struct hline *p, size_t text_need h->runs.pen = pen; return p; } - if (!ring_reserve(h)) + if (!ring_fit(h, 1)) return NULL; p = part(h, h->head - 1); p->flags &= (uint8_t)~HLINE_OPEN; @@ -1699,7 +1681,7 @@ void term_hist_push_text(struct hist *h, const struct text_row *row, bool wrappe if (h->lines >= h->line_limit) evict_line(h); int pg = page_for(h, (size_t)row->text_len + rr->len + RUN_MAX); - if (pg < 0 || !ring_reserve(h)) + if (pg < 0 || !ring_fit(h, 1)) return; uint32_t off = h->page_used[pg]; uint8_t *dst = h->pages[pg] + off; @@ -1733,7 +1715,8 @@ void term_hist_push_text(struct hist *h, const struct text_row *row, bool wrappe } /* The runs copy when their delta base is the pen of the open part, else * they are added again pen by pen, which can take more room. */ - runs_flush(&h->runs); + if (h->runs.count) + hist_runs_switch(&h->runs, text_pen_from_attr(&h->runs.pen)); bool copy = pen_attr_equal(&h->runs.base, &row->start); struct hline *q = open_room(h, p, row->text_len, copy ? rr->len + RUN_MAX : runs_need, row->cells); @@ -3153,38 +3136,6 @@ uint64_t term_hist_rows(const struct hist *h, int cols) return total; } -bool term_hist_find_row(const struct hist *h, int target_row, int cols, - uint64_t *out_id, int *out_seg) -{ - if (!h || target_row < 0 || cols <= 0) - return false; - uint64_t total = term_hist_rows(h, cols); - if ((uint64_t)target_row >= total) - return false; - uint64_t id, start; - if ((uint64_t)target_row >= total / 2) { - start = total; - id = hist_end_id(h); - do { - id--; - start -= (uint64_t)term_hist_line_rows(h, id, cols); - } while (start > (uint64_t)target_row && id > h->base_id); - } else { - start = 0; - id = h->base_id; - for (;;) { - uint64_t rows = (uint64_t)term_hist_line_rows(h, id, cols); - if ((uint64_t)target_row < start + rows) - break; - start += rows; - id++; - } - } - *out_id = id; - *out_seg = target_row - (int)start; - return true; -} - /* Locate a row boundary by its cell offset. Wide wrap pads do not count. */ uint64_t term_hist_segment_cell(const struct hist *h, uint64_t id, int seg, int cols) { @@ -3275,7 +3226,7 @@ bool term_hist_init(struct hist *h, int line_limit, size_t byte_cap) h->page_used = calloc(h->max_pages, sizeof(*h->page_used)); h->page_parts = calloc(h->max_pages, sizeof(*h->page_parts)); h->free_pages = malloc(h->max_pages * sizeof(*h->free_pages)); - if (!h->pages || !h->page_used || !h->page_parts || !h->free_pages || !ring_reserve(h)) { + if (!h->pages || !h->page_used || !h->page_parts || !h->free_pages || !ring_fit(h, 1)) { term_hist_free(h); return false; } diff --git a/src/hist.h b/src/hist.h index 74ccb09..3c90bde 100644 --- a/src/hist.h +++ b/src/hist.h @@ -159,12 +159,6 @@ static inline void text_row_unshare(struct text_row *row) } } -/* The pen of the last cell of a text row. */ -static inline struct pen_attr text_row_last_pen(const struct text_row *row) -{ - return row->runs.pen; -} - /* Write the cells of a text row to out; return the cell count. */ int term_hist_text_decode(const struct text_row *row, struct cell *out, int cap, struct gstore *g); void term_hist_text_mark_links(const struct text_row *row, void (*mark)(void *ud, uint16_t link), void *ud); @@ -299,6 +293,5 @@ uint64_t term_hist_line_estimate(const struct hist *h, uint64_t id, int cols); uint64_t term_hist_estimated_rows(const struct hist *h, int cols); void term_hist_prepare_rows(struct hist *h, int cols); void term_hist_refine_rows(struct hist *h, uint64_t id, int cols, int rows); -bool term_hist_find_row(const struct hist *h, int target_row, int cols, uint64_t *out_id, int *out_seg); #endif diff --git a/src/hist_view.c b/src/hist_view.c index f5a287b..362e995 100644 --- a/src/hist_view.c +++ b/src/hist_view.c @@ -3,11 +3,6 @@ #include #include -void term_hist_view_init(struct hist_view *v) -{ - *v = (struct hist_view){0}; -} - void term_hist_view_free(struct hist_view *v) { if (!v) @@ -17,17 +12,6 @@ void term_hist_view_free(struct hist_view *v) *v = (struct hist_view){0}; } -void term_hist_view_clear(struct hist_view *v) -{ - v->anchor = (struct view_anchor){0}; - v->index_cols = 0; -} - -void term_hist_view_reset_bottom(struct hist_view *v) -{ - v->anchor = (struct view_anchor){0}; -} - static uint64_t prefix(const struct hist_view *v, uint32_t n) { uint64_t sum = 0; @@ -240,7 +224,7 @@ void term_hist_view_rewrap(struct hist_view *v, const struct hist *h, int cols) term_hist_view_note_push(v, h, cols); if (v->anchor.active) { if (v->anchor.line_id >= hist_end_id(h)) - term_hist_view_reset_bottom(v); + v->anchor = (struct view_anchor){0}; else v->anchor.seg = (uint32_t)term_hist_cell_segment(h, v->anchor.line_id, v->anchor.cell, cols); } @@ -253,7 +237,7 @@ void term_hist_view_scroll_to(struct hist_view *v, const struct hist *h, int col { (void)screen_top; if (offset <= 0 || cols <= 0 || !h->lines) { - term_hist_view_reset_bottom(v); + v->anchor = (struct view_anchor){0}; return; } /* Allocation failure uses the read-only history walk. */ @@ -306,7 +290,7 @@ void term_hist_view_scroll(struct hist_view *v, const struct hist *h, int cols, break; seg -= count; if (++id == hist_end_id(h)) { - term_hist_view_reset_bottom(v); + v->anchor = (struct view_anchor){0}; return; } } diff --git a/src/hist_view.h b/src/hist_view.h index d09b5d0..61b4e89 100644 --- a/src/hist_view.h +++ b/src/hist_view.h @@ -30,9 +30,7 @@ struct hist_view { int index_cols; }; -void term_hist_view_init(struct hist_view *v); void term_hist_view_free(struct hist_view *v); -void term_hist_view_clear(struct hist_view *v); /* Update the index during snapshot capture. Reads do not change it. */ bool term_hist_view_sync(struct hist_view *v, const struct hist *h, int cols); @@ -47,7 +45,6 @@ void term_hist_view_scroll(struct hist_view *v, const struct hist *h, int cols, struct line_pos screen_top, int lines); void term_hist_view_scroll_to(struct hist_view *v, const struct hist *h, int cols, struct line_pos screen_top, int offset); -void term_hist_view_reset_bottom(struct hist_view *v); struct hist_view_pos { uint64_t id; diff --git a/src/input.c b/src/input.c index 960f488..9fee179 100644 --- a/src/input.c +++ b/src/input.c @@ -9,13 +9,6 @@ struct seqbuf { bool overflow; }; -static inline void sb_init(struct seqbuf *sb, char *buf, size_t buf_sz) -{ - sb->p = buf; - sb->left = buf_sz; - sb->overflow = false; -} - static inline void sb_ch(struct seqbuf *sb, char c) { if (!sb->left) { sb->overflow = true; return; } @@ -57,9 +50,23 @@ static inline void sb_u32(struct seqbuf *sb, uint32_t val) sb_bytes(sb, p, (size_t)(end - p)); } -static inline size_t sb_len(const struct seqbuf *sb, const char *buf) +static inline void sb_utf8(struct seqbuf *sb, uint32_t cp) { - return (size_t)(sb->p - buf); + char tmp[8]; + size_t n = (size_t)utf8_encode(cp, tmp); + sb_bytes(sb, tmp, n); +} + +static struct term_input_result sb_result(const struct seqbuf *sb, const char *buf) +{ + if (sb->overflow) + return (struct term_input_result){ .status = TERM_INPUT_BUFFER_FULL }; + + size_t len = (size_t)(sb->p - buf); + return (struct term_input_result){ + .status = len ? TERM_INPUT_BYTES : TERM_INPUT_CONSUMED, + .len = len, + }; } struct kitty_desc { @@ -295,12 +302,6 @@ static inline bool key_is_modifier(enum term_key k) mod_desc[k].group == MOD_KEY_ISO5); } -static inline bool key_is_lock(enum term_key k) -{ - return k == TERM_KEY_CAPS_LOCK || k == TERM_KEY_SCROLL_LOCK || - k == TERM_KEY_NUM_LOCK; -} - static unsigned effective_mods(const struct term_keyboard_state *s, const struct term_key_event *ev) { @@ -317,27 +318,6 @@ static unsigned effective_mods(const struct term_keyboard_state *s, return mods; } -static unsigned lock_mod_bit(enum term_key key) -{ - if (key == TERM_KEY_CAPS_LOCK) return TERM_MOD_CAPS; - if (key == TERM_KEY_NUM_LOCK) return TERM_MOD_NUM; - return 0; -} - -static unsigned toggle_locks(enum term_key key, enum term_key_action action, - unsigned mods) -{ - unsigned bit = lock_mod_bit(key); - if (bit && action == TERM_KEY_PRESS) mods ^= bit; - return mods; -} - -/* Convert logical input modifiers to terminal protocol bits. */ -static inline unsigned protocol_modifiers(unsigned mods) -{ - return mods & 0xff; -} - static void format_kitty(struct seqbuf *sb, uint32_t code, char final, unsigned flags, bool functional, uint32_t shifted, uint32_t base, unsigned mods, unsigned event, @@ -392,11 +372,16 @@ static bool encode_kitty(const struct term_keyboard_state *s, char final = functional ? d->final : 'u'; bool all = (flags & TERM_KEYBOARD_ALL_KEYS) != 0; - if ((key_is_modifier(ev->key) || key_is_lock(ev->key)) && !all) + bool lock = ev->key == TERM_KEY_CAPS_LOCK || ev->key == TERM_KEY_SCROLL_LOCK || + ev->key == TERM_KEY_NUM_LOCK; + if ((key_is_modifier(ev->key) || lock) && !all) return true; unsigned mods = effective_mods(s, ev); - mods = toggle_locks(ev->key, ev->action, mods); + if (ev->action == TERM_KEY_PRESS) { + if (ev->key == TERM_KEY_CAPS_LOCK) mods ^= TERM_MOD_CAPS; + if (ev->key == TERM_KEY_NUM_LOCK) mods ^= TERM_MOD_NUM; + } bool plain_control = ev->key == TERM_KEY_RETURN || ev->key == TERM_KEY_TAB || ev->key == TERM_KEY_BACKSPACE; @@ -411,7 +396,7 @@ static bool encode_kitty(const struct term_keyboard_state *s, bool has_text = text >= 32 && !(text >= 127 && text < 160) && !(mods & command_mods); if (!all && has_text) return ev->action == TERM_KEY_RELEASE; - if (!all && plain_control && !(protocol_modifiers(mods) & 63)) + if (!all && plain_control && !(mods & 63)) return ev->action == TERM_KEY_RELEASE; if (!(flags & (TERM_KEYBOARD_DISAMBIGUATE | TERM_KEYBOARD_EVENT_TYPES | TERM_KEYBOARD_ALL_KEYS))) return ev->action == TERM_KEY_RELEASE; @@ -430,7 +415,7 @@ static bool encode_kitty(const struct term_keyboard_state *s, bool report_text = all && (flags & TERM_KEYBOARD_ASSOCIATED_TEXT) && has_text && ev->action != TERM_KEY_RELEASE; - format_kitty(sb, code, final, flags, functional, shifted, base, protocol_modifiers(mods), + format_kitty(sb, code, final, flags, functional, shifted, base, mods & 0xff, event, report_text, text); return true; } @@ -463,12 +448,12 @@ static bool encode_legacy(const struct term_key_event *ev, if (ch == '-') { sb_ch(sb, 0x1f); return true; } } - unsigned csi = protocol_modifiers(ev->mods) & 63; + unsigned csi = ev->mods & 63; unsigned p = csi + 1; bool shift = (ev->mods & TERM_MOD_SHIFT) != 0; enum term_key k = ev->key; - if ((unsigned)k < TERM_KEY_COUNT && legacy_desc[k].equiv != TERM_KEY_NONE) + if (legacy_desc[k].equiv != TERM_KEY_NONE) k = legacy_desc[k].equiv; if ((unsigned)k < TERM_KEY_COUNT) { @@ -511,9 +496,7 @@ static bool encode_legacy(const struct term_key_event *ev, } if (ev->text && !ev->text_deferred) { - char tmp[8]; - size_t n = (size_t)utf8_encode(ev->text, tmp); - sb_bytes(sb, tmp, n); + sb_utf8(sb, ev->text); return true; } return false; @@ -544,7 +527,7 @@ static inline bool legacy_is_escape(const struct term_key_event *ev, if ((ev->mods & TERM_MOD_CTRL) && control_base_char(ev) == '[') return true; enum term_key k = ev->key; - if ((unsigned)k < TERM_KEY_COUNT && legacy_desc[k].equiv != TERM_KEY_NONE) + if (legacy_desc[k].equiv != TERM_KEY_NONE) k = legacy_desc[k].equiv; if ((unsigned)k < TERM_KEY_COUNT && legacy_desc[k].final) return true; @@ -569,8 +552,7 @@ struct term_input_result term_input_encode_key(const struct term_keyboard_state (unsigned)ev->key >= TERM_KEY_COUNT) return out; - struct seqbuf sb; - sb_init(&sb, buf, buf_sz); + struct seqbuf sb = { .p = buf, .left = buf_sz }; bool handled = encode_kitty(s, ev, m, &sb); if (!handled) { @@ -586,14 +568,7 @@ struct term_input_result term_input_encode_key(const struct term_keyboard_state if (!handled) return out; - if (sb.overflow) { - out.status = TERM_INPUT_BUFFER_FULL; - out.len = 0; - } else { - out.len = sb_len(&sb, buf); - out.status = out.len ? TERM_INPUT_BYTES : TERM_INPUT_CONSUMED; - } - return out; + return sb_result(&sb, buf); } struct term_input_result term_input_encode_mouse(const struct term_mouse_event *ev, @@ -641,8 +616,7 @@ struct term_input_result term_input_encode_mouse(const struct term_mouse_event * uint32_t report_x = (uint32_t)report.x + 1; uint32_t report_y = (uint32_t)report.y + 1; - struct seqbuf sb; - sb_init(&sb, buf, buf_sz); + struct seqbuf sb = { .p = buf, .left = buf_sz }; if (m->mouse_encoding == TERM_MOUSE_ENC_SGR || m->mouse_encoding == TERM_MOUSE_ENC_SGR_PIXELS) { @@ -663,14 +637,9 @@ struct term_input_result term_input_encode_mouse(const struct term_mouse_event * sb_ch(&sb, 'M'); } else if (m->mouse_encoding == TERM_MOUSE_ENC_UTF8) { sb_bytes(&sb, "\033[M", 3); - char tmp[8]; - size_t n; - n = (size_t)utf8_encode((unsigned)legacy_code + 32, tmp); - sb_bytes(&sb, tmp, n); - n = (size_t)utf8_encode((unsigned)cell.x + 33, tmp); - sb_bytes(&sb, tmp, n); - n = (size_t)utf8_encode((unsigned)cell.y + 33, tmp); - sb_bytes(&sb, tmp, n); + sb_utf8(&sb, (unsigned)legacy_code + 32); + sb_utf8(&sb, (unsigned)cell.x + 33); + sb_utf8(&sb, (unsigned)cell.y + 33); } else { if (legacy_code > 223 || cell.x > 222 || cell.y > 222) return out; @@ -683,14 +652,7 @@ struct term_input_result term_input_encode_mouse(const struct term_mouse_event * sb_bytes(&sb, tmp, 6); } - if (sb.overflow) { - out.status = TERM_INPUT_BUFFER_FULL; - out.len = 0; - return out; - } - out.len = sb_len(&sb, buf); - out.status = TERM_INPUT_BYTES; - return out; + return sb_result(&sb, buf); } /* Bidi controls can make pasted text look different from what runs. */ @@ -710,10 +672,9 @@ struct term_input_result term_input_encode_paste(const struct term_modes *m, struct term_input_result out = {0}; if (!m || !buf || (!text && len)) return out; - struct seqbuf sb; - sb_init(&sb, buf, capacity); + struct seqbuf sb = { .p = buf, .left = capacity }; if (m->bracketed_paste) sb_bytes(&sb, "\033[200~", 6); - size_t body = sb_len(&sb, buf); + char *body = sb.p; for (size_t i = 0; i < len;) { if (sb.overflow) break; size_t run = term_scan_printable_span(text + i, len - i, 0x7f); @@ -743,13 +704,7 @@ struct term_input_result term_input_encode_paste(const struct term_modes *m, } out.status = TERM_INPUT_CONSUMED; - if (!sb.overflow && sb_len(&sb, buf) == body) return out; + if (!sb.overflow && sb.p == body) return out; if (m->bracketed_paste) sb_bytes(&sb, "\033[201~", 6); - if (sb.overflow) { - out.status = TERM_INPUT_BUFFER_FULL; - return out; - } - out.len = sb_len(&sb, buf); - out.status = TERM_INPUT_BYTES; - return out; + return sb_result(&sb, buf); } diff --git a/src/internal.h b/src/internal.h index 477210d..d823018 100644 --- a/src/internal.h +++ b/src/internal.h @@ -382,15 +382,10 @@ static inline size_t term_copy_out(const char *text, char *buf, size_t cap) /* Every thread has its own anchor, so its address names the thread. */ extern _Thread_local char term_thread_anchor; -static inline uint64_t term_thread_id(void) -{ - return (uint64_t)(uintptr_t)&term_thread_anchor; -} - static inline void term_write_begin(struct term *t) { if (!t) return; - uint64_t self = term_thread_id(); + uint64_t self = (uint64_t)(uintptr_t)&term_thread_anchor; if (atomic_load_explicit(&t->writer_tid, memory_order_relaxed) == self) { t->write_depth++; return; diff --git a/src/osc/dispatch.c b/src/osc/dispatch.c index 74863ed..400adbf 100644 --- a/src/osc/dispatch.c +++ b/src/osc/dispatch.c @@ -20,16 +20,6 @@ char *term_osc_tail(struct term *t) return (t->osc_heap ? t->osc_heap : t->osc_buf) + t->osc_len; } -void term_osc_commit(struct term *t, size_t n) -{ - t->osc_len += (int)n; -} - -char *term_osc_data(struct term *t) -{ - return t->osc_heap ? t->osc_heap : t->osc_buf; -} - bool term_osc_grow(struct term *t) { if (!t->osc_heap) { @@ -151,7 +141,7 @@ static void osc104_handle(struct term *t, const char *params) void term_osc_finish(struct term *t) { if (!term_str_was_truncated(t)) { - char *buf = term_osc_data(t); + char *buf = t->osc_heap ? t->osc_heap : t->osc_buf; buf[t->osc_len] = '\0'; if (!t->alternate && t->osc_len >= 5 && !strncmp(buf, "133;", 4) && diff --git a/src/osc/osc.h b/src/osc/osc.h index 1398534..1d6680e 100644 --- a/src/osc/osc.h +++ b/src/osc/osc.h @@ -11,11 +11,8 @@ struct term; size_t term_osc_room(const struct term *t); char *term_osc_tail(struct term *t); -void term_osc_commit(struct term *t, size_t n); bool term_osc_grow(struct term *t); -char *term_osc_data(struct term *t); - void term_osc_finish(struct term *t); void term_osc_cleanup(struct term *t); diff --git a/src/palette.c b/src/palette.c index bfaba6c..cee5bad 100644 --- a/src/palette.c +++ b/src/palette.c @@ -245,25 +245,6 @@ static bool parse_fraction(const char *s, size_t len, uint8_t *out) return true; } -static const char *skip_leading_ws(const char *s) -{ - if (*s != ' ' && *s != '\t') - return s; - while (*s == ' ' || *s == '\t') - s++; - return s; -} - -static size_t rtrimmed_len(const char *s) -{ - size_t n = strlen(s); - if (n == 0 || (s[n - 1] != ' ' && s[n - 1] != '\t')) - return n; - while (n > 0 && (s[n - 1] == ' ' || s[n - 1] == '\t')) - n--; - return n; -} - static bool parse_hex_rgb(const char *s, size_t cw, uint32_t *out) { uint8_t r, g, b; @@ -279,8 +260,12 @@ bool term_color_parse(const char *input, uint32_t *out) { if (!input || !out) return false; - const char *s = skip_leading_ws(input); - size_t len = rtrimmed_len(s); + const char *s = input; + while (*s == ' ' || *s == '\t') + s++; + size_t len = strlen(s); + while (len > 0 && (s[len - 1] == ' ' || s[len - 1] == '\t')) + len--; if (len == 0) return false; @@ -466,15 +451,10 @@ static void derive_palette(uint32_t *p, const struct term_theme *theme) } } -static bool theme_is_zero(const struct term_theme *theme) -{ - static const struct term_theme zero; - return !memcmp(theme, &zero, sizeof(zero)); -} - void term_palette_init(struct palette *p, const struct term_theme *theme) { - p->theme = theme && !theme_is_zero(theme) ? *theme : builtin_theme; + static const struct term_theme zero; + p->theme = theme && memcmp(theme, &zero, sizeof(zero)) ? *theme : builtin_theme; if (!p->theme.cursor) p->theme.cursor = builtin_theme.cursor; derive_palette(p->base, &p->theme); @@ -482,14 +462,9 @@ void term_palette_init(struct palette *p, const struct term_theme *theme) p->version++; } -static bool valid_slot(int slot) -{ - return slot >= 0 && slot < TERM_PALETTE_SIZE; -} - void term_palette_set(struct palette *p, int slot, uint32_t argb) { - if (!valid_slot(slot) || p->colors[slot] == argb) + if ((unsigned)slot >= TERM_PALETTE_SIZE || p->colors[slot] == argb) return; p->colors[slot] = argb; p->version++; @@ -497,7 +472,7 @@ void term_palette_set(struct palette *p, int slot, uint32_t argb) void term_palette_reset(struct palette *p, int slot) { - if (valid_slot(slot)) + if ((unsigned)slot < TERM_PALETTE_SIZE) term_palette_set(p, slot, p->base[slot]); } diff --git a/src/palette.h b/src/palette.h index f60e41e..083ad8d 100644 --- a/src/palette.h +++ b/src/palette.h @@ -26,9 +26,4 @@ void term_palette_set(struct palette *p, int slot, uint32_t argb); void term_palette_reset(struct palette *p, int slot); void term_palette_reset_all(struct palette *p); -static inline uint32_t palette_resolve(const struct palette *p, term_color c) -{ - return term_color_is_slot(c) ? p->colors[c & TERM_COLOR_SLOT_INDEX] : c; -} - #endif diff --git a/src/screen.c b/src/screen.c index 99e788c..d9dfe31 100644 --- a/src/screen.c +++ b/src/screen.c @@ -145,50 +145,6 @@ int term_history_rows(const struct term *t) return rows; } -const struct cell *term_ring_row(const struct term *t, int row) -{ - if (!t) - return NULL; - int total = term_screen_history_rows(t); - if (row < 0 || row >= total + t->rows) - return NULL; - - if (row < total) { - uint64_t id; - int seg; - if (!term_hist_view_find_row(&t->view, &t->hist, row, t->cols, &id, &seg)) - return NULL; - struct cell *out = t->view_row_scratch; - int got = term_hist_decode_segment(&t->hist, id, seg, t->cols, out, t->gstore); - if (got < t->cols) { - fill_cells(out + got, t->cols - got, TERM_COLOR_FG, TERM_COLOR_BG); - int line_rows = term_hist_line_rows(&t->hist, id, t->cols); - if (seg + 1 < line_rows || (row + 1 == total && hist_is_open(&t->hist))) - set_cells_wrap_pad(out + got, t->cols - got); - } - return out; - } - - int y = row - total; - const struct screen *s = term_active_screen(t); - struct srow *srow = screen_row_at(s, y); - if (!srow) - return NULL; - - struct cell *out = t->view_row_scratch; - if (srow->kind == ROW_CELLS) { - if (srow->len >= t->cols || (srow->flags & RF_TAIL_PADDED)) - return srow->cells; - if (srow->len > 0) - memcpy(out, srow->cells, (size_t)srow->len * sizeof(struct cell)); - fill_cells(out + srow->len, t->cols - srow->len, TERM_COLOR_FG, TERM_COLOR_BG); - return out; - } - - text_row_cells(srow, out, t->cols); - return out; -} - const struct cell *term_screen_view_row(const struct term *t, int y) { if (!t || y < 0 || y >= t->rows) @@ -205,8 +161,7 @@ const struct cell *term_screen_view_row(const struct term *t, int y) } return out; } - const struct screen *s = term_active_screen(t); - struct srow *srow = screen_row_at(s, pos.screen_y); + struct srow *srow = screen_row_at(&t->scr, pos.screen_y); if (!srow) return NULL; struct cell *out = t->view_row_scratch; @@ -243,8 +198,7 @@ uint64_t term_screen_view_row_key(const struct term *t, int y) line_ver ^= mix64(t->hist.base_cell); return mix64(((uint64_t)pos.id << 16) ^ (uint64_t)pos.seg ^ line_ver ^ 0x517cc1b727220a95ull); } - const struct screen *s = term_active_screen(t); - const struct srow *row = screen_row_at(s, pos.screen_y); + const struct srow *row = screen_row_at(&t->scr, pos.screen_y); if (!row) return 0; return mix64(row->uid ^ ((uint64_t)row->version << 32)); @@ -544,7 +498,8 @@ void term_screen_erase(struct term *t, int mode) t->pending_wrap = false; if (mode == 3) { term_hist_clear(&t->hist); - term_hist_view_clear(&t->view); + t->view.anchor = (struct view_anchor){0}; + t->view.index_cols = 0; term_select_clear(t); t->full_gen++; return; @@ -573,12 +528,12 @@ void term_screen_erase(struct term *t, int mode) if (last_active >= 0 && !t->alternate) { term_screen_scroll_region(t, 0, rows - 1, last_active + 1, false, true); if (tail_clean) { - term_hist_view_reset_bottom(&t->view); + t->view.anchor = (struct view_anchor){0}; return; } } term_screen_erase_all(t); - term_hist_view_reset_bottom(&t->view); + t->view.anchor = (struct view_anchor){0}; t->full_gen++; } else if (mode == 0) { int cur_p = phys_row(t, t->cursor_y); @@ -674,7 +629,7 @@ void term_screen_scroll_region(struct term *t, int top, int bottom, int count, /* Whole active screen scroll: optimize using ring rotation. */ if (top == 0 && bottom == t->rows - 1) { - struct screen *s = term_active_screen(t); + struct screen *s = &t->scr; int rows = s->rows; int orig_top = s->top; bool def = using_default_colors(t); @@ -770,7 +725,7 @@ void term_screen_scroll_region(struct term *t, int top, int bottom, int count, return; } - struct screen *s = term_active_screen(t); + struct screen *s = &t->scr; bool def = using_default_colors(t); if (count == height) { @@ -880,7 +835,7 @@ void term_screen_set_alternate(struct term *t, bool enabled) t->left_margin = 0; t->right_margin = t->cols - 1; /* The alternate screen has no history to show. */ - term_hist_view_reset_bottom(&t->view); + t->view.anchor = (struct view_anchor){0}; term_select_clear(t); t->full_gen++; } else { @@ -907,7 +862,7 @@ void term_screen_set_alternate(struct term *t, bool enabled) t->left_margin = 0; t->right_margin = t->cols - 1; /* The alternate screen has no history to show. */ - term_hist_view_reset_bottom(&t->view); + t->view.anchor = (struct view_anchor){0}; term_select_clear(t); t->full_gen++; } @@ -986,7 +941,6 @@ struct term *term_new(const struct term_options *opt) return NULL; } t->hist.wrap_cols = (uint16_t)cols; - term_hist_view_init(&t->view); t->gstore = term_gstore_new(t); t->view_scratch_cap = cols > 256 ? cols : 256; @@ -1338,7 +1292,7 @@ static bool term_resize_internal(struct term *t, int cols, int rows) term_gstore_pin(t->gstore); if (t->alternate || cols == t->scr.cols) { - struct screen *active_scr = term_active_screen(t); + struct screen *active_scr = &t->scr; int old_cols = active_scr->cols; int old_rows = active_scr->rows; diff --git a/src/screen.h b/src/screen.h index 5f92929..0bd95c0 100644 --- a/src/screen.h +++ b/src/screen.h @@ -15,7 +15,6 @@ void term_screen_erase_line(struct term *t, int mode); void term_screen_delete_chars(struct term *t, int count); void term_screen_insert_chars(struct term *t, int count); -const struct cell *term_ring_row(const struct term *t, int row); const struct cell *term_screen_view_row(const struct term *t, int y); uint64_t term_screen_view_row_key(const struct term *t, int y); /* The selected columns [c0, c1] of each view row; c1 < c0 when none. */ @@ -26,11 +25,6 @@ int term_screen_history_rows(const struct term *t); /* Rows of history above the live screen. The view owns the offset. */ int term_view_offset(const struct term *t); -static inline struct screen *term_active_screen(const struct term *t) -{ - return (struct screen *)&t->scr; -} - static inline bool screen_has_history(const struct term *t) { return !t->alternate && t->hist.line_limit > 0; @@ -227,7 +221,7 @@ static inline struct srow *text_append_row(struct term *t) if (t->cursor_y > 0) { const struct srow *prev = term_row(t, t->cursor_y - 1); if (prev->kind == ROW_TEXT && (prev->flags & RF_WRAPPED)) - start = text_row_last_pen(&prev->text); + start = prev->text.runs.pen; } if (row->kind == ROW_TEXT) { struct text_pen p = text_pen_from_attr(&start); @@ -373,8 +367,7 @@ static inline void write_cell_span(struct cell *row, int x, static inline void erase_span(struct term *t, int p, int from, int to) { bool pristine = using_default_colors(t); - struct screen *s = term_active_screen(t); - struct srow *row = &s->slot[p]; + struct srow *row = &t->scr.slot[p]; int len = row->len; if (to > TERM_MAX_COLS) to = TERM_MAX_COLS; if (pristine && to > len) to = len; @@ -417,8 +410,7 @@ static inline void erase_span(struct term *t, int p, int from, int to) static inline int erase_width(const struct term *t, int p) { - const struct screen *s = term_active_screen(t); - return s->slot[p].len > t->cols ? s->slot[p].len : t->cols; + return t->scr.slot[p].len > t->cols ? t->scr.slot[p].len : t->cols; } static inline void erase_row(struct term *t, int p) diff --git a/src/selection.c b/src/selection.c index e4a3e35..2727e8a 100644 --- a/src/selection.c +++ b/src/selection.c @@ -132,7 +132,7 @@ static void lines_init(struct lines *L, const struct term *t) struct line_pos p = screen_top_line(t); for (int y = 0; y < rows; y++) { L->pos[y] = p; - p = line_pos_next(p, screen_get_row(term_active_screen(t), y)); + p = line_pos_next(p, screen_get_row(&t->scr, y)); } } @@ -204,7 +204,7 @@ static const struct cell *line_seg_cells(const struct lines *L, uint64_t id, int int y = screen_row_of(L, id, seg); if (y < 0) return NULL; - const struct srow *srow = screen_get_row(term_active_screen(t), y); + const struct srow *srow = screen_get_row(&t->scr, y); if (out_wrapped) *out_wrapped = (srow->flags & RF_WRAPPED) != 0; if (srow->kind == ROW_CELLS) { @@ -234,7 +234,7 @@ static bool line_has_wide(const struct lines *L, uint64_t id) for (int y = 0; y < rows; y++) { if (L->pos[y].id != id) continue; - const struct srow *r = screen_get_row(term_active_screen(t), y); + const struct srow *r = screen_get_row(&t->scr, y); if (r->flags & RF_WIDE) return true; if (r->kind == ROW_CELLS && r->len >= L->cols && L->cols > 1 && diff --git a/src/text.c b/src/text.c index c72ea26..43c3ef5 100644 --- a/src/text.c +++ b/src/text.c @@ -12,17 +12,6 @@ #include #include -static void dispatch_c1_control(struct term *t, uint32_t cp) -{ - static const char c1_map[32] = { - [4] = 'D', [5] = 'E', [8] = 'H', [13] = 'M', - [16] = 'P', [27] = '[', [28] = '\\', [29] = ']' }; - char ch = c1_map[cp - 0x80]; - if (!ch) return; - t->state = ST_ESC; - term_escape_byte(t, (unsigned char)ch); -} - static inline void emit_codepoint(struct term *t, uint32_t cp, int klass, uint16_t flags) { static const uint32_t dec_graphics[] = { @@ -32,7 +21,15 @@ static inline void emit_codepoint(struct term *t, uint32_t cp, int klass, uint16 0x23bb,0x2500,0x23bc,0x23bd,0x251c,0x2524,0x2534,0x252c, 0x2502,0x2264,0x2265,0x03c0,0x2260,0x00a3,0x00b7 }; if (cp >= 0x80 && cp <= 0x9f) { - dispatch_c1_control(t, cp); + static const char c1_map[32] = { + [4] = 'D', [5] = 'E', [8] = 'H', [13] = 'M', + [16] = 'P', [27] = '[', [28] = '\\', [29] = ']', + }; + char ch = c1_map[cp - 0x80]; + if (ch) { + t->state = ST_ESC; + term_escape_byte(t, (unsigned char)ch); + } return; } if (t->graphics && cp >= '_' && cp <= '~') { @@ -78,7 +75,10 @@ void term_text_ground(struct term *t, unsigned char ch) } else if (ch == '\r') { sc_cr(t); } else if (ch == '\b') { - sc_bs(t); + t->pending_wrap = false; + if (t->cursor_x > 0) + t->cursor_x--; + term_row(t, t->cursor_y)->version++; } else if (ch == '\t') { term_sc_tab(t, 1); } else if (ch == 0x07) { @@ -105,12 +105,6 @@ void term_text_ground(struct term *t, unsigned char ch) } } -static inline int decode_ground_utf8(struct term *t, const char *buf, size_t len, - uint32_t *cp) -{ - return utf8_decode_ground(&t->utf8_state, &t->utf8_codep, buf, len, cp); -} - static inline bool can_stream_bottom(const struct term *t) { return t->state == ST_GROUND && !t->graphics && !t->insert_mode && t->autowrap && @@ -294,7 +288,7 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne continue; } uint32_t cp; - int cp_len = decode_ground_utf8(t, buf + i, len - i, &cp); + int cp_len = utf8_decode_ground(&t->utf8_state, &t->utf8_codep, buf + i, len - i, &cp); if (cp) emit_decoded(t, cp, cur_flags); i += (size_t)(cp_len - 1); -- cgit v1.2.3