# HG changeset patch # User Bram Moolenaar # Date 1589829304 -7200 # Node ID d0bf39eb2b0748f8a3aa9755875bc9ba9dec4712 # Parent c4b13b8932fb22186f8a5ca987b1dfc3db7ab282 patch 8.2.0794: libvterm code lags behind the upstream version Commit: https://github.com/vim/vim/commit/d098b824c10cc20dc55e18c22c4991f61826006e Author: Bram Moolenaar Date: Mon May 18 21:12:59 2020 +0200 patch 8.2.0794: libvterm code lags behind the upstream version Problem: Libvterm code lags behind the upstream version. Solution: Include revisions 743 - 747. diff --git a/src/libvterm/include/vterm.h b/src/libvterm/include/vterm.h --- a/src/libvterm/include/vterm.h +++ b/src/libvterm/include/vterm.h @@ -268,6 +268,15 @@ void *vterm_parser_get_cbdata(VTerm *vt) // State layer // ----------- +/* Copies of VTermState fields that the 'resize' callback might have reason to + * edit. 'resize' callback gets total control of these fields and may + * free-and-reallocate them if required. They will be copied back from the + * struct after the callback has returned. + */ +typedef struct { + VTermPos pos; /* current cursor position */ +} VTermStateFields; + typedef struct { int (*putglyph)(VTermGlyphInfo *info, VTermPos pos, void *user); int (*movecursor)(VTermPos pos, VTermPos oldpos, int visible, void *user); @@ -280,7 +289,7 @@ typedef struct { // was accepted, 0 otherwise. int (*settermprop)(VTermProp prop, VTermValue *val, void *user); int (*bell)(void *user); - int (*resize)(int rows, int cols, VTermPos *delta, void *user); + int (*resize)(int rows, int cols, VTermStateFields *fields, void *user); int (*setlineinfo)(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user); } VTermStateCallbacks; diff --git a/src/libvterm/src/screen.c b/src/libvterm/src/screen.c --- a/src/libvterm/src/screen.c +++ b/src/libvterm/src/screen.c @@ -56,8 +56,6 @@ struct VTermScreen int global_reverse; // Primary and Altscreen. buffers[1] is lazily allocated as needed -#define BUFIDX_PRIMARY 0 -#define BUFIDX_ALTSCREEN 1 ScreenCell *buffers[2]; // buffer will == buffers[0] or buffers[1], depending on altscreen @@ -481,7 +479,7 @@ static int bell(void *user) return 0; } -static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new_cols, int active, VTermPos *delta) +static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new_cols, int active, VTermStateFields *statefields) { int old_rows = screen->rows; int old_cols = screen->cols; @@ -524,8 +522,8 @@ found_oldrow: int row; for(row = 0; row <= old_row; row++) sb_pushline_from_row(screen, row); - if(delta) - delta->row -= (old_row + 1); + if(active) + statefields->pos.row -= (old_row + 1); } if(new_row >= 0 && bufidx == BUFIDX_PRIMARY && screen->callbacks && screen->callbacks->sb_popline) { @@ -563,8 +561,8 @@ found_oldrow: } new_row--; - if(delta) - delta->row++; + if(active) + statefields->pos.row++; } } @@ -590,7 +588,7 @@ found_oldrow: */ } -static int resize(int new_rows, int new_cols, VTermPos *delta, void *user) +static int resize(int new_rows, int new_cols, VTermStateFields *fields, void *user) { VTermScreen *screen = user; @@ -606,9 +604,9 @@ static int resize(int new_rows, int new_ screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * new_cols); } - resize_buffer(screen, 0, new_rows, new_cols, !altscreen_active, altscreen_active ? NULL : delta); + resize_buffer(screen, 0, new_rows, new_cols, !altscreen_active, fields); if(screen->buffers[BUFIDX_ALTSCREEN]) - resize_buffer(screen, 1, new_rows, new_cols, altscreen_active, altscreen_active ? delta : NULL); + resize_buffer(screen, 1, new_rows, new_cols, altscreen_active, fields); screen->buffer = altscreen_active ? screen->buffers[BUFIDX_ALTSCREEN] : screen->buffers[BUFIDX_PRIMARY]; diff --git a/src/libvterm/src/state.c b/src/libvterm/src/state.c --- a/src/libvterm/src/state.c +++ b/src/libvterm/src/state.c @@ -73,13 +73,27 @@ static VTermState *vterm_state_new(VTerm state->bold_is_highbright = 0; + state->combine_chars_size = 16; + state->combine_chars = vterm_allocator_malloc(state->vt, state->combine_chars_size * sizeof(state->combine_chars[0])); + + state->tabstops = vterm_allocator_malloc(state->vt, (state->cols + 7) / 8); + + state->lineinfos[BUFIDX_PRIMARY] = vterm_allocator_malloc(state->vt, state->rows * sizeof(VTermLineInfo)); + state->lineinfo = state->lineinfos[BUFIDX_PRIMARY]; + + state->encoding_utf8.enc = vterm_lookup_encoding(ENC_UTF8, 'u'); + if(*state->encoding_utf8.enc->init) + (*state->encoding_utf8.enc->init)(state->encoding_utf8.enc, state->encoding_utf8.data); + return state; } INTERNAL void vterm_state_free(VTermState *state) { vterm_allocator_free(state->vt, state->tabstops); - vterm_allocator_free(state->vt, state->lineinfo); + vterm_allocator_free(state->vt, state->lineinfos[BUFIDX_PRIMARY]); + if(state->lineinfos[BUFIDX_ALTSCREEN]) + vterm_allocator_free(state->vt, state->lineinfos[BUFIDX_ALTSCREEN]); vterm_allocator_free(state->vt, state->combine_chars); vterm_allocator_free(state->vt, state); } @@ -106,15 +120,22 @@ static void scroll(VTermState *state, VT // Update lineinfo if full line if(rect.start_col == 0 && rect.end_col == state->cols && rightward == 0) { int height = rect.end_row - rect.start_row - abs(downward); + int row; - if(downward > 0) + if(downward > 0) { memmove(state->lineinfo + rect.start_row, state->lineinfo + rect.start_row + downward, height * sizeof(state->lineinfo[0])); - else + for(row = rect.end_row - downward; row < rect.end_row; row++) + state->lineinfo[row] = (VTermLineInfo){ 0 }; + } + else { memmove(state->lineinfo + rect.start_row - downward, state->lineinfo + rect.start_row, height * sizeof(state->lineinfo[0])); + for(row = rect.start_row; row < rect.start_row - downward; row++) + state->lineinfo[row] = (VTermLineInfo){ 0 }; + } } if(state->callbacks && state->callbacks->scrollrect) @@ -1701,7 +1722,7 @@ static int on_resize(int rows, int cols, { VTermState *state = user; VTermPos oldpos = state->pos; - VTermPos delta = { 0, 0 }; + VTermStateFields fields; if(cols != state->cols) { int col; @@ -1731,22 +1752,29 @@ static int on_resize(int rows, int cols, } if(rows != state->rows) { - int row; - VTermLineInfo *newlineinfo = vterm_allocator_malloc(state->vt, rows * sizeof(VTermLineInfo)); - if (newlineinfo == NULL) - return 0; + for(int bufidx = BUFIDX_PRIMARY; bufidx <= BUFIDX_ALTSCREEN; bufidx++) { + int row; + VTermLineInfo *oldlineinfo = state->lineinfos[bufidx]; + if(!oldlineinfo) + continue; + + VTermLineInfo *newlineinfo = vterm_allocator_malloc(state->vt, rows * sizeof(VTermLineInfo)); - for(row = 0; row < state->rows && row < rows; row++) { - newlineinfo[row] = state->lineinfo[row]; + for(row = 0; row < state->rows && row < rows; row++) { + newlineinfo[row] = oldlineinfo[row]; + } + + for( ; row < rows; row++) { + newlineinfo[row] = (VTermLineInfo){ + .doublewidth = 0, + }; + } + + vterm_allocator_free(state->vt, state->lineinfos[bufidx]); + state->lineinfos[bufidx] = newlineinfo; } - for( ; row < rows; row++) { - newlineinfo[row].doublewidth = 0; - newlineinfo[row].doubleheight = 0; - } - - vterm_allocator_free(state->vt, state->lineinfo); - state->lineinfo = newlineinfo; + state->lineinfo = state->lineinfos[state->mode.alt_screen ? BUFIDX_ALTSCREEN : BUFIDX_PRIMARY]; } state->rows = rows; @@ -1757,17 +1785,18 @@ static int on_resize(int rows, int cols, if(state->scrollregion_right > -1) UBOUND(state->scrollregion_right, state->cols); + fields.pos = state->pos; + if(state->callbacks && state->callbacks->resize) - (*state->callbacks->resize)(rows, cols, &delta, state->cbdata); + (*state->callbacks->resize)(rows, cols, &fields, state->cbdata); + + state->pos = fields.pos; if(state->at_phantom && state->pos.col < cols-1) { state->at_phantom = 0; state->pos.col++; } - state->pos.row += delta.row; - state->pos.col += delta.col; - if(state->pos.row >= rows) state->pos.row = rows - 1; if(state->pos.col >= cols) @@ -1803,17 +1832,6 @@ VTermState *vterm_obtain_state(VTerm *vt return NULL; vt->state = state; - state->combine_chars_size = 16; - state->combine_chars = vterm_allocator_malloc(state->vt, state->combine_chars_size * sizeof(state->combine_chars[0])); - - state->tabstops = vterm_allocator_malloc(state->vt, (state->cols + 7) / 8); - - state->lineinfo = vterm_allocator_malloc(state->vt, state->rows * sizeof(VTermLineInfo)); - - state->encoding_utf8.enc = vterm_lookup_encoding(ENC_UTF8, 'u'); - if(*state->encoding_utf8.enc->init != NULL) - (*state->encoding_utf8.enc->init)(state->encoding_utf8.enc, state->encoding_utf8.data); - vterm_parser_set_callbacks(vt, &parser_callbacks, state); return state; @@ -1976,6 +1994,9 @@ int vterm_state_set_termprop(VTermState return 1; case VTERM_PROP_ALTSCREEN: state->mode.alt_screen = val->boolean; + if(state->mode.alt_screen && !state->lineinfos[BUFIDX_ALTSCREEN]) + state->lineinfos[BUFIDX_ALTSCREEN] = vterm_allocator_malloc(state->vt, state->rows * sizeof(VTermLineInfo)); + state->lineinfo = state->lineinfos[state->mode.alt_screen ? BUFIDX_ALTSCREEN : BUFIDX_PRIMARY]; if(state->mode.alt_screen) { VTermRect rect = {0, 0, 0, 0}; rect.end_row = state->rows; diff --git a/src/libvterm/src/vterm_internal.h b/src/libvterm/src/vterm_internal.h --- a/src/libvterm/src/vterm_internal.h +++ b/src/libvterm/src/vterm_internal.h @@ -32,6 +32,9 @@ #define CSI_ARGS_MAX 16 #define CSI_LEADER_MAX 16 +#define BUFIDX_PRIMARY 0 +#define BUFIDX_ALTSCREEN 1 + typedef struct VTermEncoding VTermEncoding; typedef struct { @@ -92,6 +95,10 @@ struct VTermState // Bitvector of tab stops unsigned char *tabstops; + /* Primary and Altscreen; lineinfos[1] is lazily allocated as needed */ + VTermLineInfo *lineinfos[2]; + + /* lineinfo will == lineinfos[0] or lineinfos[1], depending on altscreen */ VTermLineInfo *lineinfo; #define ROWWIDTH(state,row) ((state)->lineinfo[(row)].doublewidth ? ((state)->cols / 2) : (state)->cols) #define THISROWWIDTH(state) ROWWIDTH(state, (state)->pos.row) diff --git a/src/libvterm/t/67screen_dbl_wh.test b/src/libvterm/t/67screen_dbl_wh.test --- a/src/libvterm/t/67screen_dbl_wh.test +++ b/src/libvterm/t/67screen_dbl_wh.test @@ -30,3 +30,9 @@ PUSH "abcde" ?screen_cell 0,0 = {0x61} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0) PUSH "\e#6" ?screen_cell 0,0 = {0x61} width=1 attrs={} dwl fg=rgb(240,240,240) bg=rgb(0,0,0) + +!DWL doesn't spill over on scroll +RESET +PUSH "\e[25H\e#6Final\r\n" + ?screen_cell 23,0 = {0x46} width=1 attrs={} dwl fg=rgb(240,240,240) bg=rgb(0,0,0) + ?screen_cell 24,0 = {} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0) diff --git a/src/libvterm/t/run-test.pl b/src/libvterm/t/run-test.pl --- a/src/libvterm/t/run-test.pl +++ b/src/libvterm/t/run-test.pl @@ -140,14 +140,14 @@ sub do_line } } # Assertions start with '?' - elsif( $line =~ s/^\?([a-z]+.*?=)\s+// ) { + elsif( $line =~ s/^\?([a-z]+.*?=)\s*// ) { do_onetest if defined $command; my ( $assertion ) = $1 =~ m/^(.*)\s+=/; $hin->print( "\?$assertion\n" ); my $response = <$hout>; defined $response or wait, die "Test harness failed - $?\n"; - chomp $response; + chomp $response; $response =~ s/^\s+|\s+$//g; if( $response ne $line ) { print "# Assert $assertion failed:\n" . diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 794, +/**/ 793, /**/ 792,