From 62ec922b6fac0faa3a01ce39c227c63f392743cc Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Tue, 16 Jul 2024 14:39:42 +0000 Subject: [PATCH] Added sb_pushline4 screen callback, which adds an extra 'continuation' argument --- include/vterm.h | 4 ++++ src/screen.c | 32 ++++++++++++++++++++++++-------- t/harness.c | 19 ++++++++++--------- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/include/vterm.h b/include/vterm.h index 3ad813e..1ae2028 100644 --- a/include/vterm.h +++ b/include/vterm.h @@ -545,6 +545,8 @@ typedef struct { int (*sb_pushline)(int cols, const VTermScreenCell *cells, void *user); int (*sb_popline)(int cols, VTermScreenCell *cells, void *user); int (*sb_clear)(void* user); + /* ABI-compat this is only used if vterm_screen_callbacks_has_pushline4() is called */ + int (*sb_pushline4)(int cols, const VTermScreenCell *cells, bool continuation, void *user); } VTermScreenCallbacks; VTermScreen *vterm_obtain_screen(VTerm *vt); @@ -552,6 +554,8 @@ VTermScreen *vterm_obtain_screen(VTerm *vt); void vterm_screen_set_callbacks(VTermScreen *screen, const VTermScreenCallbacks *callbacks, void *user); void *vterm_screen_get_cbdata(VTermScreen *screen); +void vterm_screen_callbacks_has_pushline4(VTermScreen *screen); + void vterm_screen_set_unrecognised_fallbacks(VTermScreen *screen, const VTermStateFallbacks *fallbacks, void *user); void *vterm_screen_get_unrecognised_fbdata(VTermScreen *screen); diff --git a/src/screen.c b/src/screen.c index 389e198..5775e67 100644 --- a/src/screen.c +++ b/src/screen.c @@ -48,6 +48,7 @@ struct VTermScreen const VTermScreenCallbacks *callbacks; void *cbdata; + bool callbacks_has_pushline4; VTermDamageSize damage_merge; /* start_row == -1 => no damage */ @@ -205,25 +206,31 @@ static int putglyph(VTermGlyphInfo *info, VTermPos pos, void *user) return 1; } -static void sb_pushline_from_row(VTermScreen *screen, int row) +static void sb_pushline_from_row(VTermScreen *screen, int row, bool continuation) { VTermPos pos = { .row = row }; for(pos.col = 0; pos.col < screen->cols; pos.col++) vterm_screen_get_cell(screen, pos, screen->sb_buffer + pos.col); - (screen->callbacks->sb_pushline)(screen->cols, screen->sb_buffer, screen->cbdata); + if(screen->callbacks_has_pushline4 && screen->callbacks->sb_pushline4) + (screen->callbacks->sb_pushline4)(screen->cols, screen->sb_buffer, continuation, screen->cbdata); + else + (screen->callbacks->sb_pushline)(screen->cols, screen->sb_buffer, screen->cbdata); } static int premove(VTermRect rect, void *user) { VTermScreen *screen = user; - if(screen->callbacks && screen->callbacks->sb_pushline && + if(((screen->callbacks && screen->callbacks->sb_pushline) || + (screen->callbacks_has_pushline4 && screen->callbacks && screen->callbacks->sb_pushline4)) && rect.start_row == 0 && rect.start_col == 0 && // starts top-left corner rect.end_col == screen->cols && // full width screen->buffer == screen->buffers[BUFIDX_PRIMARY]) { // not altscreen - for(int row = 0; row < rect.end_row; row++) - sb_pushline_from_row(screen, row); + for(int row = 0; row < rect.end_row; row++) { + const VTermLineInfo *lineinfo = vterm_state_get_lineinfo(screen->state, row); + sb_pushline_from_row(screen, row, lineinfo->continuation); + } } return 1; @@ -674,9 +681,12 @@ static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new if(old_row >= 0 && bufidx == BUFIDX_PRIMARY) { /* Push spare lines to scrollback buffer */ - if(screen->callbacks && screen->callbacks->sb_pushline) - for(int row = 0; row <= old_row; row++) - sb_pushline_from_row(screen, row); + if((screen->callbacks && screen->callbacks->sb_pushline) || + (screen->callbacks_has_pushline4 && screen->callbacks && screen->callbacks->sb_pushline4)) + for(int row = 0; row <= old_row; row++) { + const VTermLineInfo *lineinfo = old_lineinfo + row; + sb_pushline_from_row(screen, row, lineinfo->continuation); + } if(active) statefields->pos.row -= (old_row + 1); } @@ -884,6 +894,7 @@ static VTermScreen *screen_new(VTerm *vt) screen->callbacks = NULL; screen->cbdata = NULL; + screen->callbacks_has_pushline4 = false; screen->buffers[BUFIDX_PRIMARY] = alloc_buffer(screen, rows, cols); @@ -1070,6 +1081,11 @@ void *vterm_screen_get_cbdata(VTermScreen *screen) return screen->cbdata; } +void vterm_screen_callbacks_has_pushline4(VTermScreen *screen) +{ + screen->callbacks_has_pushline4 = true; +} + void vterm_screen_set_unrecognised_fallbacks(VTermScreen *screen, const VTermStateFallbacks *fallbacks, void *user) { vterm_state_set_unrecognised_fallbacks(screen->state, fallbacks, user); diff --git a/t/harness.c b/t/harness.c index 6c844fe..3ec60ee 100644 --- a/t/harness.c +++ b/t/harness.c @@ -582,7 +582,7 @@ static int screen_damage(VTermRect rect, void *user) } static int want_screen_scrollback = 0; -static int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user) +static int screen_sb_pushline4(int cols, const VTermScreenCell *cells, bool continuation, void *user) { if(!want_screen_scrollback) return 1; @@ -591,7 +591,7 @@ static int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user while(eol && !cells[eol-1].chars[0]) eol--; - printf("sb_pushline %d =", cols); + printf("sb_pushline %d%s =", cols, continuation ? " cont" : ""); for(int c = 0; c < eol; c++) printf(" %02X", cells[c].chars[0]); printf("\n"); @@ -628,13 +628,13 @@ static int screen_sb_clear(void *user) } VTermScreenCallbacks screen_cbs = { - .damage = screen_damage, - .moverect = moverect, - .movecursor = movecursor, - .settermprop = settermprop, - .sb_pushline = screen_sb_pushline, - .sb_popline = screen_sb_popline, - .sb_clear = screen_sb_clear, + .damage = screen_damage, + .moverect = moverect, + .movecursor = movecursor, + .settermprop = settermprop, + .sb_popline = screen_sb_popline, + .sb_clear = screen_sb_clear, + .sb_pushline4 = screen_sb_pushline4, }; int main(int argc, char **argv) @@ -725,6 +725,7 @@ int main(int argc, char **argv) if(!screen) screen = vterm_obtain_screen(vt); vterm_screen_set_callbacks(screen, &screen_cbs, NULL); + vterm_screen_callbacks_has_pushline4(screen); int i = 10; int sense = 1;