diff options
Diffstat (limited to 'tests/extern/kitty/screen_bridge.c')
| -rw-r--r-- | tests/extern/kitty/screen_bridge.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/tests/extern/kitty/screen_bridge.c b/tests/extern/kitty/screen_bridge.c new file mode 100644 index 0000000..63a3583 --- /dev/null +++ b/tests/extern/kitty/screen_bridge.c @@ -0,0 +1,113 @@ +/* Test-only entry points for the Kitty screen wrapper in screen.py. + * Python calls only these functions, so it needs no struct layouts other + * than the public struct term_cell. The kitty_screen_* accessors read + * properties that term.h does not expose. They compile against the current + * terminal layout rather than duplicating byte offsets in Python. */ +#include "internal.h" +#include "screen.h" + +typedef void (*kitty_reply_fn)(void *ud, const char *bytes, size_t len); + +struct term *kitty_term_new(int cols, int rows, kitty_reply_fn reply, void *ud) +{ + return term_new(&(struct term_options){ + .size = { .x = cols, .y = rows }, + .callbacks = { .ud = ud, .reply = reply }, + }); +} + +/* One snapshot serves every cell read. */ +static struct term_snapshot *snap; + +void kitty_term_free(struct term *t) +{ + /* A new terminal can get the address of the freed one. The snapshot + * would then keep its rows, so it goes away too. */ + term_snapshot_free(snap); + snap = NULL; + term_free(t); +} + +void kitty_term_write(struct term *t, const char *bytes, size_t len) +{ + term_feed(t, bytes, len, 0); +} + +bool kitty_term_resize(struct term *t, int cols, int rows) +{ + return term_resize(t, (struct term_vector2i){ .x = cols, .y = rows }); +} + +int kitty_term_cols(struct term *t) { return term_size(t).x; } +int kitty_term_rows(struct term *t) { return term_size(t).y; } +int kitty_term_cursor_x(struct term *t) { return term_cursor(t).pos.x; } +int kitty_term_cursor_y(struct term *t) { return term_cursor(t).pos.y; } +int kitty_term_cursor_style(struct term *t) { return (int)term_cursor(t).style; } +bool kitty_term_cursor_blink(struct term *t) { return term_cursor(t).blink; } +bool kitty_term_application_cursor(struct term *t) { return term_modes(t).app_cursor; } + +/* Update the snapshot from the live screen, as a renderer reads it. + * Returns NULL when the cell is out of range or memory runs out. */ +static struct term_snapshot *cell_snapshot(struct term *t, int col, int row) +{ + struct term_vector2i size = term_size(t); + if (col < 0 || col >= size.x || row < 0 || row >= size.y) + return NULL; + if (!snap) + snap = term_snapshot_new(); + term_scroll_to(t, 0); + if (!snap || !term_snapshot_update(snap, t)) + return NULL; + return snap; +} + +bool kitty_term_cell(struct term *t, int col, int row, struct term_cell *out) +{ + struct term_snapshot *s = cell_snapshot(t, col, row); + if (!s) + return false; + *out = term_snapshot_row(s, row)[col]; + return true; +} + +/* The code points of a cell's text: one, or a whole grapheme cluster. + * Returns the number of code points and writes at most cap of them. */ +int kitty_term_cell_text(struct term *t, int col, int row, uint32_t *cps, int cap) +{ + struct term_snapshot *s = cell_snapshot(t, col, row); + if (!s) + return 0; + return term_snapshot_cluster(s, term_snapshot_row(s, row)[col].text, cps, cap); +} + +#define PROPERTY(type, name) \ + type kitty_screen_##name(struct term *t) { return t->name; } + +PROPERTY(int, scroll_top) +PROPERTY(int, scroll_bottom) +PROPERTY(uint32_t, cur_fg) +PROPERTY(uint32_t, cur_bg) +PROPERTY(bool, bold) +PROPERTY(bool, faint) +PROPERTY(bool, italic) +PROPERTY(bool, strike) +PROPERTY(bool, inverse) +PROPERTY(uint8_t, underline) + +int kitty_screen_row_length(struct term *t, int row) +{ + if (!t || row < 0 || row >= t->rows) return 0; + const struct srow *r = term_screen_row(t, row); + return r ? (int)r->len : 0; +} + +/* A tab stores a marker cell that a snapshot shows as a blank. Kitty keeps + * the tab in its line text, so the wrapper asks for the marker. */ +bool kitty_screen_cell_is_tab(struct term *t, int col, int row) +{ + if (col < 0 || col >= t->cols || row < 0 || row >= t->rows) + return false; + term_scroll_to(t, 0); + const struct cell *cells = term_screen_view_row(t, row); + return cells && cells[col].c == '\t'; +} |
