diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
commit | d5f194ce780c95821a855aca3c19426576d28ae0 (patch) | |
tree | d45f461b19f9118ad2bb1f440a7a08973ad18832 /src/vterm/vterm.c | |
parent | c5d770d311841ea5230426cc4c868e8db27300a8 (diff) | |
parent | 44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff) | |
download | rneovim-rahm.tar.gz rneovim-rahm.tar.bz2 rneovim-rahm.zip |
Diffstat (limited to 'src/vterm/vterm.c')
-rw-r--r-- | src/vterm/vterm.c | 938 |
1 files changed, 0 insertions, 938 deletions
diff --git a/src/vterm/vterm.c b/src/vterm/vterm.c deleted file mode 100644 index e8c87929e2..0000000000 --- a/src/vterm/vterm.c +++ /dev/null @@ -1,938 +0,0 @@ -#include "vterm_internal.h" - -#include "auto/config.h" -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -/***************** - * API functions * - *****************/ - -static void *default_malloc(size_t size, void *allocdata) -{ - void *ptr = malloc(size); - if(ptr) - memset(ptr, 0, size); - return ptr; -} - -static void default_free(void *ptr, void *allocdata) -{ - free(ptr); -} - -static VTermAllocatorFunctions default_allocator = { - .malloc = &default_malloc, - .free = &default_free, -}; - -VTerm *vterm_new(int rows, int cols) -{ - return vterm_build(&(const struct VTermBuilder){ - .rows = rows, - .cols = cols, - }); -} - -VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *funcs, void *allocdata) -{ - return vterm_build(&(const struct VTermBuilder){ - .rows = rows, - .cols = cols, - .allocator = funcs, - .allocdata = allocdata, - }); -} - -/* A handy macro for defaulting values out of builder fields */ -#define DEFAULT(v, def) ((v) ? (v) : (def)) - -VTerm *vterm_build(const struct VTermBuilder *builder) -{ - const VTermAllocatorFunctions *allocator = DEFAULT(builder->allocator, &default_allocator); - - /* Need to bootstrap using the allocator function directly */ - VTerm *vt = (*allocator->malloc)(sizeof(VTerm), builder->allocdata); - - vt->allocator = allocator; - vt->allocdata = builder->allocdata; - - vt->rows = builder->rows; - vt->cols = builder->cols; - - vt->parser.state = NORMAL; - - vt->parser.callbacks = NULL; - vt->parser.cbdata = NULL; - - vt->parser.emit_nul = false; - - vt->outfunc = NULL; - vt->outdata = NULL; - - vt->outbuffer_len = DEFAULT(builder->outbuffer_len, 4096); - vt->outbuffer_cur = 0; - vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len); - - vt->tmpbuffer_len = DEFAULT(builder->tmpbuffer_len, 4096); - vt->tmpbuffer = vterm_allocator_malloc(vt, vt->tmpbuffer_len); - - return vt; -} - -void vterm_free(VTerm *vt) -{ - if(vt->screen) - vterm_screen_free(vt->screen); - - if(vt->state) - vterm_state_free(vt->state); - - vterm_allocator_free(vt, vt->outbuffer); - vterm_allocator_free(vt, vt->tmpbuffer); - - vterm_allocator_free(vt, vt); -} - -INTERNAL void *vterm_allocator_malloc(VTerm *vt, size_t size) -{ - return (*vt->allocator->malloc)(size, vt->allocdata); -} - -INTERNAL void vterm_allocator_free(VTerm *vt, void *ptr) -{ - (*vt->allocator->free)(ptr, vt->allocdata); -} - -void vterm_get_size(const VTerm *vt, int *rowsp, int *colsp) -{ - if(rowsp) - *rowsp = vt->rows; - if(colsp) - *colsp = vt->cols; -} - -void vterm_set_size(VTerm *vt, int rows, int cols) -{ - if(rows < 1 || cols < 1) - return; - - vt->rows = rows; - vt->cols = cols; - - if(vt->parser.callbacks && vt->parser.callbacks->resize) - (*vt->parser.callbacks->resize)(rows, cols, vt->parser.cbdata); -} - -int vterm_get_utf8(const VTerm *vt) -{ - return vt->mode.utf8; -} - -void vterm_set_utf8(VTerm *vt, int is_utf8) -{ - vt->mode.utf8 = is_utf8; -} - -void vterm_output_set_callback(VTerm *vt, VTermOutputCallback *func, void *user) -{ - vt->outfunc = func; - vt->outdata = user; -} - -INTERNAL void vterm_push_output_bytes(VTerm *vt, const char *bytes, size_t len) -{ - if(vt->outfunc) { - (vt->outfunc)(bytes, len, vt->outdata); - return; - } - - if(len > vt->outbuffer_len - vt->outbuffer_cur) - return; - - memcpy(vt->outbuffer + vt->outbuffer_cur, bytes, len); - vt->outbuffer_cur += len; -} - -INTERNAL void vterm_push_output_vsprintf(VTerm *vt, const char *format, va_list args) -{ - size_t len = vsnprintf(vt->tmpbuffer, vt->tmpbuffer_len, - format, args); - - vterm_push_output_bytes(vt, vt->tmpbuffer, len); -} - -INTERNAL void vterm_push_output_sprintf(VTerm *vt, const char *format, ...) -{ - va_list args; - va_start(args, format); - vterm_push_output_vsprintf(vt, format, args); - va_end(args); -} - -INTERNAL void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...) -{ - size_t cur; - - if(ctrl >= 0x80 && !vt->mode.ctrl8bit) - cur = snprintf(vt->tmpbuffer, vt->tmpbuffer_len, - ESC_S "%c", ctrl - 0x40); - else - cur = snprintf(vt->tmpbuffer, vt->tmpbuffer_len, - "%c", ctrl); - - if(cur >= vt->tmpbuffer_len) - return; - - va_list args; - va_start(args, fmt); - cur += vsnprintf(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur, - fmt, args); - va_end(args); - - if(cur >= vt->tmpbuffer_len) - return; - - vterm_push_output_bytes(vt, vt->tmpbuffer, cur); -} - -INTERNAL void vterm_push_output_sprintf_str(VTerm *vt, unsigned char ctrl, bool term, const char *fmt, ...) -{ - size_t cur = 0; - - if(ctrl) { - if(ctrl >= 0x80 && !vt->mode.ctrl8bit) - cur = snprintf(vt->tmpbuffer, vt->tmpbuffer_len, - ESC_S "%c", ctrl - 0x40); - else - cur = snprintf(vt->tmpbuffer, vt->tmpbuffer_len, - "%c", ctrl); - - if(cur >= vt->tmpbuffer_len) - return; - } - - va_list args; - va_start(args, fmt); - cur += vsnprintf(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur, - fmt, args); - va_end(args); - - if(cur >= vt->tmpbuffer_len) - return; - - if(term) { - cur += snprintf(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur, - vt->mode.ctrl8bit ? "\x9C" : ESC_S "\\"); // ST - - if(cur >= vt->tmpbuffer_len) - return; - } - - vterm_push_output_bytes(vt, vt->tmpbuffer, cur); -} - -size_t vterm_output_get_buffer_size(const VTerm *vt) -{ - return vt->outbuffer_len; -} - -size_t vterm_output_get_buffer_current(const VTerm *vt) -{ - return vt->outbuffer_cur; -} - -size_t vterm_output_get_buffer_remaining(const VTerm *vt) -{ - return vt->outbuffer_len - vt->outbuffer_cur; -} - -size_t vterm_output_read(VTerm *vt, char *buffer, size_t len) -{ - if(len > vt->outbuffer_cur) - len = vt->outbuffer_cur; - - memcpy(buffer, vt->outbuffer, len); - - if(len < vt->outbuffer_cur) - memmove(vt->outbuffer, vt->outbuffer + len, vt->outbuffer_cur - len); - - vt->outbuffer_cur -= len; - - return len; -} - -VTermValueType vterm_get_attr_type(VTermAttr attr) -{ - switch(attr) { - case VTERM_ATTR_BOLD: return VTERM_VALUETYPE_BOOL; - case VTERM_ATTR_UNDERLINE: return VTERM_VALUETYPE_INT; - case VTERM_ATTR_ITALIC: return VTERM_VALUETYPE_BOOL; - case VTERM_ATTR_BLINK: return VTERM_VALUETYPE_BOOL; - case VTERM_ATTR_REVERSE: return VTERM_VALUETYPE_BOOL; - case VTERM_ATTR_CONCEAL: return VTERM_VALUETYPE_BOOL; - case VTERM_ATTR_STRIKE: return VTERM_VALUETYPE_BOOL; - case VTERM_ATTR_FONT: return VTERM_VALUETYPE_INT; - case VTERM_ATTR_FOREGROUND: return VTERM_VALUETYPE_COLOR; - case VTERM_ATTR_BACKGROUND: return VTERM_VALUETYPE_COLOR; - case VTERM_ATTR_SMALL: return VTERM_VALUETYPE_BOOL; - case VTERM_ATTR_BASELINE: return VTERM_VALUETYPE_INT; - case VTERM_ATTR_URI: return VTERM_VALUETYPE_INT; - - case VTERM_N_ATTRS: return 0; - } - return 0; /* UNREACHABLE */ -} - -VTermValueType vterm_get_prop_type(VTermProp prop) -{ - switch(prop) { - case VTERM_PROP_CURSORVISIBLE: return VTERM_VALUETYPE_BOOL; - case VTERM_PROP_CURSORBLINK: return VTERM_VALUETYPE_BOOL; - case VTERM_PROP_ALTSCREEN: return VTERM_VALUETYPE_BOOL; - case VTERM_PROP_TITLE: return VTERM_VALUETYPE_STRING; - case VTERM_PROP_ICONNAME: return VTERM_VALUETYPE_STRING; - case VTERM_PROP_REVERSE: return VTERM_VALUETYPE_BOOL; - case VTERM_PROP_CURSORSHAPE: return VTERM_VALUETYPE_INT; - case VTERM_PROP_MOUSE: return VTERM_VALUETYPE_INT; - case VTERM_PROP_FOCUSREPORT: return VTERM_VALUETYPE_BOOL; - - case VTERM_N_PROPS: return 0; - } - return 0; /* UNREACHABLE */ -} - -void vterm_scroll_rect(VTermRect rect, - int downward, - int rightward, - int (*moverect)(VTermRect src, VTermRect dest, void *user), - int (*eraserect)(VTermRect rect, int selective, void *user), - void *user) -{ - VTermRect src; - VTermRect dest; - - if(abs(downward) >= rect.end_row - rect.start_row || - abs(rightward) >= rect.end_col - rect.start_col) { - /* Scroll more than area; just erase the lot */ - (*eraserect)(rect, 0, user); - return; - } - - if(rightward >= 0) { - /* rect: [XXX................] - * src: [----------------] - * dest: [----------------] - */ - dest.start_col = rect.start_col; - dest.end_col = rect.end_col - rightward; - src.start_col = rect.start_col + rightward; - src.end_col = rect.end_col; - } - else { - /* rect: [................XXX] - * src: [----------------] - * dest: [----------------] - */ - int leftward = -rightward; - dest.start_col = rect.start_col + leftward; - dest.end_col = rect.end_col; - src.start_col = rect.start_col; - src.end_col = rect.end_col - leftward; - } - - if(downward >= 0) { - dest.start_row = rect.start_row; - dest.end_row = rect.end_row - downward; - src.start_row = rect.start_row + downward; - src.end_row = rect.end_row; - } - else { - int upward = -downward; - dest.start_row = rect.start_row + upward; - dest.end_row = rect.end_row; - src.start_row = rect.start_row; - src.end_row = rect.end_row - upward; - } - - if(moverect) - (*moverect)(dest, src, user); - - if(downward > 0) - rect.start_row = rect.end_row - downward; - else if(downward < 0) - rect.end_row = rect.start_row - downward; - - if(rightward > 0) - rect.start_col = rect.end_col - rightward; - else if(rightward < 0) - rect.end_col = rect.start_col - rightward; - - (*eraserect)(rect, 0, user); -} - -void vterm_copy_cells(VTermRect dest, - VTermRect src, - void (*copycell)(VTermPos dest, VTermPos src, void *user), - void *user) -{ - int downward = src.start_row - dest.start_row; - int rightward = src.start_col - dest.start_col; - - int init_row, test_row, init_col, test_col; - int inc_row, inc_col; - - if(downward < 0) { - init_row = dest.end_row - 1; - test_row = dest.start_row - 1; - inc_row = -1; - } - else /* downward >= 0 */ { - init_row = dest.start_row; - test_row = dest.end_row; - inc_row = +1; - } - - if(rightward < 0) { - init_col = dest.end_col - 1; - test_col = dest.start_col - 1; - inc_col = -1; - } - else /* rightward >= 0 */ { - init_col = dest.start_col; - test_col = dest.end_col; - inc_col = +1; - } - - VTermPos pos; - for(pos.row = init_row; pos.row != test_row; pos.row += inc_row) - for(pos.col = init_col; pos.col != test_col; pos.col += inc_col) { - VTermPos srcpos = { pos.row + downward, pos.col + rightward }; - (*copycell)(pos, srcpos, user); - } -} - -void vterm_check_version(int major, int minor) -{ - if(major != VTERM_VERSION_MAJOR) { - fprintf(stderr, "libvterm major version mismatch; %d (wants) != %d (library)\n", - major, VTERM_VERSION_MAJOR); - exit(1); - } - - if(minor > VTERM_VERSION_MINOR) { - fprintf(stderr, "libvterm minor version mismatch; %d (wants) > %d (library)\n", - minor, VTERM_VERSION_MINOR); - exit(1); - } - - // Happy -} - -// For unit tests. -#ifndef NDEBUG - -int parser_text(const char bytes[], size_t len, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "text "); - int i; - for(i = 0; i < len; i++) { - unsigned char b = bytes[i]; - if(b < 0x20 || b == 0x7f || (b >= 0x80 && b < 0xa0)) { - break; - } - fprintf(f, i ? ",%x" : "%x", b); - } - fprintf(f, "\n"); - fclose(f); - - return i; -} - -static void printchars(const char *s, size_t len, FILE *f) -{ - while(len--) { - fprintf(f, "%c", (s++)[0]); - } -} - -int parser_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "csi %02x", command); - - if(leader && leader[0]) { - fprintf(f, " L="); - for(int i = 0; leader[i]; i++) { - fprintf(f, "%02x", leader[i]); - } - } - - for(int i = 0; i < argcount; i++) { - char sep = i ? ',' : ' '; - - if(args[i] == CSI_ARG_MISSING) { - fprintf(f, "%c*", sep); - } else { - fprintf(f, "%c%ld%s", sep, CSI_ARG(args[i]), CSI_ARG_HAS_MORE(args[i]) ? "+" : ""); - } - } - - if(intermed && intermed[0]) { - fprintf(f, " I="); - for(int i = 0; intermed[i]; i++) { - fprintf(f, "%02x", intermed[i]); - } - } - - fprintf(f, "\n"); - - fclose(f); - - return 1; -} - -int parser_osc(int command, VTermStringFragment frag, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "osc "); - - if(frag.initial) { - if(command == -1) { - fprintf(f, "["); - } else { - fprintf(f, "[%d;", command); - } - } - - printchars(frag.str, frag.len, f); - - if(frag.final) { - fprintf(f, "]"); - } - - fprintf(f, "\n"); - fclose(f); - - return 1; -} - -int parser_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "dcs "); - - if(frag.initial) { - fprintf(f, "["); - for(int i = 0; i < commandlen; i++) { - fprintf(f, "%c", command[i]); - } - } - - printchars(frag.str, frag.len,f); - - if(frag.final) { - fprintf(f, "]"); - } - - fprintf(f, "\n"); - fclose(f); - - return 1; -} - -int parser_apc(VTermStringFragment frag, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "apc "); - - if(frag.initial) { - fprintf(f, "["); - } - - printchars(frag.str, frag.len, f); - - if(frag.final) { - fprintf(f, "]"); - } - - fprintf(f, "\n"); - fclose(f); - - return 1; -} - -int parser_pm(VTermStringFragment frag, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "pm "); - - if(frag.initial) { - fprintf(f, "["); - } - - printchars(frag.str, frag.len,f); - - if(frag.final) { - fprintf(f, "]"); - } - - fprintf(f, "\n"); - fclose(f); - - return 1; -} - -int parser_sos(VTermStringFragment frag, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "sos "); - - if(frag.initial) { - fprintf(f, "["); - } - - printchars(frag.str, frag.len,f); - - if(frag.final) { - fprintf(f, "]"); - } - - fprintf(f, "\n"); - fclose(f); - - return 1; -} - -int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "selection-set mask=%04X ", mask); - if(frag.initial) { - fprintf(f, "["); -} - printchars(frag.str, frag.len, f); - if(frag.final) { - fprintf(f, "]"); -} - fprintf(f,"\n"); - - fclose(f); - return 1; -} - -int selection_query(VTermSelectionMask mask, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f,"selection-query mask=%04X\n", mask); - - fclose(f); - return 1; -} - -bool want_state_putglyph; -int state_putglyph(VTermGlyphInfo *info, VTermPos pos, void *user) -{ - if(!want_state_putglyph) { - return 1; - } - - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "putglyph "); - for(int i = 0; i < VTERM_MAX_CHARS_PER_CELL && info->chars[i]; i++) { - fprintf(f, i ? ",%x" : "%x", info->chars[i]); - } - fprintf(f, " %d %d,%d", info->width, pos.row, pos.col); - if(info->protected_cell) { - fprintf(f, " prot"); - } - if(info->dwl) { - fprintf(f, " dwl"); - } - if(info->dhl) { - fprintf(f, " dhl-%s", info->dhl == 1 ? "top" : info->dhl == 2 ? "bottom" : "?" ); - } - fprintf(f, "\n"); - - fclose(f); - - return 1; -} - -bool want_state_movecursor; -VTermPos state_pos; -int state_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - state_pos = pos; - - if(want_state_movecursor) { - fprintf(f,"movecursor %d,%d\n", pos.row, pos.col); - } - - fclose(f); - return 1; -} - -bool want_state_scrollrect; -int state_scrollrect(VTermRect rect, int downward, int rightward, void *user) -{ - if(!want_state_scrollrect) { - return 0; - } - - FILE *f = fopen(VTERM_TEST_FILE, "a"); - - fprintf(f,"scrollrect %d..%d,%d..%d => %+d,%+d\n", - rect.start_row, rect.end_row, rect.start_col, rect.end_col, - downward, rightward); - - fclose(f); - return 1; -} - -bool want_state_moverect; -int state_moverect(VTermRect dest, VTermRect src, void *user) -{ - if(!want_state_moverect) { - return 0; - } - - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f,"moverect %d..%d,%d..%d -> %d..%d,%d..%d\n", - src.start_row, src.end_row, src.start_col, src.end_col, - dest.start_row, dest.end_row, dest.start_col, dest.end_col); - - fclose(f); - return 1; -} - -void print_color(const VTermColor *col) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - if (VTERM_COLOR_IS_RGB(col)) { - fprintf(f,"rgb(%d,%d,%d", col->rgb.red, col->rgb.green, col->rgb.blue); - } - else if (VTERM_COLOR_IS_INDEXED(col)) { - fprintf(f,"idx(%d", col->indexed.idx); - } - else { - fprintf(f,"invalid(%d", col->type); - } - if (VTERM_COLOR_IS_DEFAULT_FG(col)) { - fprintf(f,",is_default_fg"); - } - if (VTERM_COLOR_IS_DEFAULT_BG(col)) { - fprintf(f,",is_default_bg"); - } - fprintf(f,")"); - fclose(f); -} - -bool want_state_settermprop; -int state_settermprop(VTermProp prop, VTermValue *val, void *user) -{ - if(!want_state_settermprop) { - return 1; - } - - int errcode = 0; - FILE *f = fopen(VTERM_TEST_FILE, "a"); - - VTermValueType type = vterm_get_prop_type(prop); - switch(type) { - case VTERM_VALUETYPE_BOOL: - fprintf(f,"settermprop %d %s\n", prop, val->boolean ? "true" : "false"); - errcode = 1; - goto end; - case VTERM_VALUETYPE_INT: - fprintf(f,"settermprop %d %d\n", prop, val->number); - errcode = 1; - goto end; - case VTERM_VALUETYPE_STRING: - fprintf(f,"settermprop %d %s\"%.*s\"%s\n", prop, - val->string.initial ? "[" : "", (int)val->string.len, val->string.str, val->string.final ? "]" : ""); - errcode=0; - goto end; - case VTERM_VALUETYPE_COLOR: - fprintf(f,"settermprop %d ", prop); - print_color(&val->color); - fprintf(f,"\n"); - errcode=1; - goto end; - case VTERM_N_VALUETYPES: - goto end; - } - -end: - fclose(f); - return errcode; -} - -bool want_state_erase; -int state_erase(VTermRect rect, int selective, void *user) -{ - if(!want_state_erase) { - return 1; - } - - FILE *f = fopen(VTERM_TEST_FILE, "a"); - - fprintf(f,"erase %d..%d,%d..%d%s\n", - rect.start_row, rect.end_row, rect.start_col, rect.end_col, - selective ? " selective" : ""); - - fclose(f); - return 1; -} - -struct { - int bold; - int underline; - int italic; - int blink; - int reverse; - int conceal; - int strike; - int font; - int small; - int baseline; - VTermColor foreground; - VTermColor background; -} state_pen; - -int state_setpenattr(VTermAttr attr, VTermValue *val, void *user) -{ - switch(attr) { - case VTERM_ATTR_BOLD: - state_pen.bold = val->boolean; - break; - case VTERM_ATTR_UNDERLINE: - state_pen.underline = val->number; - break; - case VTERM_ATTR_ITALIC: - state_pen.italic = val->boolean; - break; - case VTERM_ATTR_BLINK: - state_pen.blink = val->boolean; - break; - case VTERM_ATTR_REVERSE: - state_pen.reverse = val->boolean; - break; - case VTERM_ATTR_CONCEAL: - state_pen.conceal = val->boolean; - break; - case VTERM_ATTR_STRIKE: - state_pen.strike = val->boolean; - break; - case VTERM_ATTR_FONT: - state_pen.font = val->number; - break; - case VTERM_ATTR_SMALL: - state_pen.small = val->boolean; - break; - case VTERM_ATTR_BASELINE: - state_pen.baseline = val->number; - break; - case VTERM_ATTR_FOREGROUND: - state_pen.foreground = val->color; - break; - case VTERM_ATTR_BACKGROUND: - state_pen.background = val->color; - break; - - case VTERM_N_ATTRS: - return 0; - default: - break; - } - - return 1; -} - -bool want_state_scrollback; -int state_sb_clear(void *user) { - if(!want_state_scrollback) { - return 1; - } - - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f,"sb_clear\n"); - fclose(f); - - return 0; -} - -bool want_screen_scrollback; -int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user) -{ - if(!want_screen_scrollback) { - return 1; - } - - int eol = cols; - while(eol && !cells[eol-1].chars[0]) { - eol--; - } - - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "sb_pushline %d =", cols); - for(int c = 0; c < eol; c++) { - fprintf(f, " %02X", cells[c].chars[0]); - } - fprintf(f, "\n"); - - fclose(f); - - return 1; -} - -int screen_sb_popline(int cols, VTermScreenCell *cells, void *user) -{ - if(!want_screen_scrollback) { - return 0; - } - - // All lines of scrollback contain "ABCDE" - for(int col = 0; col < cols; col++) { - if(col < 5) { - cells[col].chars[0] = 'A' + col; - } else { - cells[col].chars[0] = 0; - } - - cells[col].width = 1; - } - - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f,"sb_popline %d\n", cols); - fclose(f); - return 1; -} - -int screen_sb_clear(void *user) -{ - if(!want_screen_scrollback) { - return 1; - } - - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "sb_clear\n"); - fclose(f); - return 0; -} - -void term_output(const char *s, size_t len, void *user) -{ - FILE *f = fopen(VTERM_TEST_FILE, "a"); - fprintf(f, "output "); - for(int i = 0; i < len; i++) { - fprintf(f, "%x%s", (unsigned char)s[i], i < len-1 ? "," : "\n"); - } - fclose(f); -} - -#endif |