1
0
forked from aniani/vim

patch 8.2.0794: libvterm code lags behind the upstream version

Problem:    Libvterm code lags behind the upstream version.
Solution:   Include revisions 743 - 747.
This commit is contained in:
Bram Moolenaar
2020-05-18 21:12:59 +02:00
parent 1e1d2e89fa
commit d098b824c1
7 changed files with 88 additions and 45 deletions

View File

@@ -268,6 +268,15 @@ void *vterm_parser_get_cbdata(VTerm *vt);
// State layer // 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 { typedef struct {
int (*putglyph)(VTermGlyphInfo *info, VTermPos pos, void *user); int (*putglyph)(VTermGlyphInfo *info, VTermPos pos, void *user);
int (*movecursor)(VTermPos pos, VTermPos oldpos, int visible, void *user); int (*movecursor)(VTermPos pos, VTermPos oldpos, int visible, void *user);
@@ -280,7 +289,7 @@ typedef struct {
// was accepted, 0 otherwise. // was accepted, 0 otherwise.
int (*settermprop)(VTermProp prop, VTermValue *val, void *user); int (*settermprop)(VTermProp prop, VTermValue *val, void *user);
int (*bell)(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); int (*setlineinfo)(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user);
} VTermStateCallbacks; } VTermStateCallbacks;

View File

@@ -56,8 +56,6 @@ struct VTermScreen
int global_reverse; int global_reverse;
// Primary and Altscreen. buffers[1] is lazily allocated as needed // Primary and Altscreen. buffers[1] is lazily allocated as needed
#define BUFIDX_PRIMARY 0
#define BUFIDX_ALTSCREEN 1
ScreenCell *buffers[2]; ScreenCell *buffers[2];
// buffer will == buffers[0] or buffers[1], depending on altscreen // buffer will == buffers[0] or buffers[1], depending on altscreen
@@ -481,7 +479,7 @@ static int bell(void *user)
return 0; 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_rows = screen->rows;
int old_cols = screen->cols; int old_cols = screen->cols;
@@ -524,8 +522,8 @@ found_oldrow:
int row; int row;
for(row = 0; row <= old_row; row++) for(row = 0; row <= old_row; row++)
sb_pushline_from_row(screen, row); sb_pushline_from_row(screen, row);
if(delta) if(active)
delta->row -= (old_row + 1); statefields->pos.row -= (old_row + 1);
} }
if(new_row >= 0 && bufidx == BUFIDX_PRIMARY && if(new_row >= 0 && bufidx == BUFIDX_PRIMARY &&
screen->callbacks && screen->callbacks->sb_popline) { screen->callbacks && screen->callbacks->sb_popline) {
@@ -563,8 +561,8 @@ found_oldrow:
} }
new_row--; new_row--;
if(delta) if(active)
delta->row++; 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; VTermScreen *screen = user;
@@ -606,9 +604,9 @@ static int resize(int new_rows, int new_cols, VTermPos *delta, void *user)
screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * new_cols); 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]) 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]; screen->buffer = altscreen_active ? screen->buffers[BUFIDX_ALTSCREEN] : screen->buffers[BUFIDX_PRIMARY];

View File

@@ -73,13 +73,27 @@ static VTermState *vterm_state_new(VTerm *vt)
state->bold_is_highbright = 0; 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; return state;
} }
INTERNAL void vterm_state_free(VTermState *state) INTERNAL void vterm_state_free(VTermState *state)
{ {
vterm_allocator_free(state->vt, state->tabstops); 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->combine_chars);
vterm_allocator_free(state->vt, state); vterm_allocator_free(state->vt, state);
} }
@@ -106,15 +120,22 @@ static void scroll(VTermState *state, VTermRect rect, int downward, int rightwar
// Update lineinfo if full line // Update lineinfo if full line
if(rect.start_col == 0 && rect.end_col == state->cols && rightward == 0) { if(rect.start_col == 0 && rect.end_col == state->cols && rightward == 0) {
int height = rect.end_row - rect.start_row - abs(downward); int height = rect.end_row - rect.start_row - abs(downward);
int row;
if(downward > 0) if(downward > 0) {
memmove(state->lineinfo + rect.start_row, memmove(state->lineinfo + rect.start_row,
state->lineinfo + rect.start_row + downward, state->lineinfo + rect.start_row + downward,
height * sizeof(state->lineinfo[0])); 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, memmove(state->lineinfo + rect.start_row - downward,
state->lineinfo + rect.start_row, state->lineinfo + rect.start_row,
height * sizeof(state->lineinfo[0])); 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) if(state->callbacks && state->callbacks->scrollrect)
@@ -1701,7 +1722,7 @@ static int on_resize(int rows, int cols, void *user)
{ {
VTermState *state = user; VTermState *state = user;
VTermPos oldpos = state->pos; VTermPos oldpos = state->pos;
VTermPos delta = { 0, 0 }; VTermStateFields fields;
if(cols != state->cols) { if(cols != state->cols) {
int col; int col;
@@ -1731,22 +1752,29 @@ static int on_resize(int rows, int cols, void *user)
} }
if(rows != state->rows) { if(rows != state->rows) {
int row; for(int bufidx = BUFIDX_PRIMARY; bufidx <= BUFIDX_ALTSCREEN; bufidx++) {
VTermLineInfo *newlineinfo = vterm_allocator_malloc(state->vt, rows * sizeof(VTermLineInfo)); int row;
if (newlineinfo == NULL) VTermLineInfo *oldlineinfo = state->lineinfos[bufidx];
return 0; if(!oldlineinfo)
continue;
for(row = 0; row < state->rows && row < rows; row++) { VTermLineInfo *newlineinfo = vterm_allocator_malloc(state->vt, rows * sizeof(VTermLineInfo));
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++) { state->lineinfo = state->lineinfos[state->mode.alt_screen ? BUFIDX_ALTSCREEN : BUFIDX_PRIMARY];
newlineinfo[row].doublewidth = 0;
newlineinfo[row].doubleheight = 0;
}
vterm_allocator_free(state->vt, state->lineinfo);
state->lineinfo = newlineinfo;
} }
state->rows = rows; state->rows = rows;
@@ -1757,17 +1785,18 @@ static int on_resize(int rows, int cols, void *user)
if(state->scrollregion_right > -1) if(state->scrollregion_right > -1)
UBOUND(state->scrollregion_right, state->cols); UBOUND(state->scrollregion_right, state->cols);
fields.pos = state->pos;
if(state->callbacks && state->callbacks->resize) 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) { if(state->at_phantom && state->pos.col < cols-1) {
state->at_phantom = 0; state->at_phantom = 0;
state->pos.col++; state->pos.col++;
} }
state->pos.row += delta.row;
state->pos.col += delta.col;
if(state->pos.row >= rows) if(state->pos.row >= rows)
state->pos.row = rows - 1; state->pos.row = rows - 1;
if(state->pos.col >= cols) if(state->pos.col >= cols)
@@ -1803,17 +1832,6 @@ VTermState *vterm_obtain_state(VTerm *vt)
return NULL; return NULL;
vt->state = state; 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); vterm_parser_set_callbacks(vt, &parser_callbacks, state);
return state; return state;
@@ -1976,6 +1994,9 @@ int vterm_state_set_termprop(VTermState *state, VTermProp prop, VTermValue *val)
return 1; return 1;
case VTERM_PROP_ALTSCREEN: case VTERM_PROP_ALTSCREEN:
state->mode.alt_screen = val->boolean; 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) { if(state->mode.alt_screen) {
VTermRect rect = {0, 0, 0, 0}; VTermRect rect = {0, 0, 0, 0};
rect.end_row = state->rows; rect.end_row = state->rows;

View File

@@ -32,6 +32,9 @@
#define CSI_ARGS_MAX 16 #define CSI_ARGS_MAX 16
#define CSI_LEADER_MAX 16 #define CSI_LEADER_MAX 16
#define BUFIDX_PRIMARY 0
#define BUFIDX_ALTSCREEN 1
typedef struct VTermEncoding VTermEncoding; typedef struct VTermEncoding VTermEncoding;
typedef struct { typedef struct {
@@ -92,6 +95,10 @@ struct VTermState
// Bitvector of tab stops // Bitvector of tab stops
unsigned char *tabstops; 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; VTermLineInfo *lineinfo;
#define ROWWIDTH(state,row) ((state)->lineinfo[(row)].doublewidth ? ((state)->cols / 2) : (state)->cols) #define ROWWIDTH(state,row) ((state)->lineinfo[(row)].doublewidth ? ((state)->cols / 2) : (state)->cols)
#define THISROWWIDTH(state) ROWWIDTH(state, (state)->pos.row) #define THISROWWIDTH(state) ROWWIDTH(state, (state)->pos.row)

View File

@@ -30,3 +30,9 @@ PUSH "abcde"
?screen_cell 0,0 = {0x61} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0) ?screen_cell 0,0 = {0x61} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
PUSH "\e#6" PUSH "\e#6"
?screen_cell 0,0 = {0x61} width=1 attrs={} dwl fg=rgb(240,240,240) bg=rgb(0,0,0) ?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)

View File

@@ -140,14 +140,14 @@ sub do_line
} }
} }
# Assertions start with '?' # Assertions start with '?'
elsif( $line =~ s/^\?([a-z]+.*?=)\s+// ) { elsif( $line =~ s/^\?([a-z]+.*?=)\s*// ) {
do_onetest if defined $command; do_onetest if defined $command;
my ( $assertion ) = $1 =~ m/^(.*)\s+=/; my ( $assertion ) = $1 =~ m/^(.*)\s+=/;
$hin->print( "\?$assertion\n" ); $hin->print( "\?$assertion\n" );
my $response = <$hout>; defined $response or wait, die "Test harness failed - $?\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 ) { if( $response ne $line ) {
print "# Assert $assertion failed:\n" . print "# Assert $assertion failed:\n" .

View File

@@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
794,
/**/ /**/
793, 793,
/**/ /**/