libvterm: C89 backport.
* As a separate commit so next time the update will be easier...
This commit is contained in:
@@ -28,7 +28,7 @@ typedef enum {
|
|||||||
VTERM_KEY_PAGEUP,
|
VTERM_KEY_PAGEUP,
|
||||||
VTERM_KEY_PAGEDOWN,
|
VTERM_KEY_PAGEDOWN,
|
||||||
|
|
||||||
VTERM_KEY_FUNCTION_0 = 256,,
|
VTERM_KEY_FUNCTION_0 = 256,
|
||||||
VTERM_KEY_FUNCTION_MAX = VTERM_KEY_FUNCTION_0 + 255,
|
VTERM_KEY_FUNCTION_MAX = VTERM_KEY_FUNCTION_0 + 255,
|
||||||
|
|
||||||
VTERM_KEY_KP_0,
|
VTERM_KEY_KP_0,
|
||||||
|
|||||||
@@ -215,7 +215,8 @@ encodings[] = {
|
|||||||
/* This ought to be INTERNAL but isn't because it's used by unit testing */
|
/* This ought to be INTERNAL but isn't because it's used by unit testing */
|
||||||
VTermEncoding *vterm_lookup_encoding(VTermEncodingType type, char designation)
|
VTermEncoding *vterm_lookup_encoding(VTermEncodingType type, char designation)
|
||||||
{
|
{
|
||||||
for(int i = 0; encodings[i].designation; i++)
|
int i;
|
||||||
|
for(i = 0; encodings[i].designation; i++)
|
||||||
if(encodings[i].type == type && encodings[i].designation == designation)
|
if(encodings[i].type == type && encodings[i].designation == designation)
|
||||||
return encodings[i].enc;
|
return encodings[i].enc;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
static const struct StaticTableEncoding encoding_DECdrawing = {
|
||||||
|
{ .decode = &decode_table },
|
||||||
|
{
|
||||||
|
[0x60] = 0x25C6,
|
||||||
|
[0x61] = 0x2592,
|
||||||
|
[0x62] = 0x2409,
|
||||||
|
[0x63] = 0x240C,
|
||||||
|
[0x64] = 0x240D,
|
||||||
|
[0x65] = 0x240A,
|
||||||
|
[0x66] = 0x00B0,
|
||||||
|
[0x67] = 0x00B1,
|
||||||
|
[0x68] = 0x2424,
|
||||||
|
[0x69] = 0x240B,
|
||||||
|
[0x6a] = 0x2518,
|
||||||
|
[0x6b] = 0x2510,
|
||||||
|
[0x6c] = 0x250C,
|
||||||
|
[0x6d] = 0x2514,
|
||||||
|
[0x6e] = 0x253C,
|
||||||
|
[0x6f] = 0x23BA,
|
||||||
|
[0x70] = 0x23BB,
|
||||||
|
[0x71] = 0x2500,
|
||||||
|
[0x72] = 0x23BC,
|
||||||
|
[0x73] = 0x23BD,
|
||||||
|
[0x74] = 0x251C,
|
||||||
|
[0x75] = 0x2524,
|
||||||
|
[0x76] = 0x2534,
|
||||||
|
[0x77] = 0x252C,
|
||||||
|
[0x78] = 0x2502,
|
||||||
|
[0x79] = 0x2A7D,
|
||||||
|
[0x7a] = 0x2A7E,
|
||||||
|
[0x7b] = 0x03C0,
|
||||||
|
[0x7c] = 0x2260,
|
||||||
|
[0x7d] = 0x00A3,
|
||||||
|
[0x7e] = 0x00B7,
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
6/0 = U+25C6 # BLACK DIAMOND
|
|
||||||
6/1 = U+2592 # MEDIUM SHADE (checkerboard)
|
|
||||||
6/2 = U+2409 # SYMBOL FOR HORIZONTAL TAB
|
|
||||||
6/3 = U+240C # SYMBOL FOR FORM FEED
|
|
||||||
6/4 = U+240D # SYMBOL FOR CARRIAGE RETURN
|
|
||||||
6/5 = U+240A # SYMBOL FOR LINE FEED
|
|
||||||
6/6 = U+00B0 # DEGREE SIGN
|
|
||||||
6/7 = U+00B1 # PLUS-MINUS SIGN (plus or minus)
|
|
||||||
6/8 = U+2424 # SYMBOL FOR NEW LINE
|
|
||||||
6/9 = U+240B # SYMBOL FOR VERTICAL TAB
|
|
||||||
6/10 = U+2518 # BOX DRAWINGS LIGHT UP AND LEFT (bottom-right corner)
|
|
||||||
6/11 = U+2510 # BOX DRAWINGS LIGHT DOWN AND LEFT (top-right corner)
|
|
||||||
6/12 = U+250C # BOX DRAWINGS LIGHT DOWN AND RIGHT (top-left corner)
|
|
||||||
6/13 = U+2514 # BOX DRAWINGS LIGHT UP AND RIGHT (bottom-left corner)
|
|
||||||
6/14 = U+253C # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL (crossing lines)
|
|
||||||
6/15 = U+23BA # HORIZONTAL SCAN LINE-1
|
|
||||||
7/0 = U+23BB # HORIZONTAL SCAN LINE-3
|
|
||||||
7/1 = U+2500 # BOX DRAWINGS LIGHT HORIZONTAL
|
|
||||||
7/2 = U+23BC # HORIZONTAL SCAN LINE-7
|
|
||||||
7/3 = U+23BD # HORIZONTAL SCAN LINE-9
|
|
||||||
7/4 = U+251C # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
|
|
||||||
7/5 = U+2524 # BOX DRAWINGS LIGHT VERTICAL AND LEFT
|
|
||||||
7/6 = U+2534 # BOX DRAWINGS LIGHT UP AND HORIZONTAL
|
|
||||||
7/7 = U+252C # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
|
|
||||||
7/8 = U+2502 # BOX DRAWINGS LIGHT VERTICAL
|
|
||||||
7/9 = U+2A7D # LESS-THAN OR SLANTED EQUAL-TO
|
|
||||||
7/10 = U+2A7E # GREATER-THAN OR SLANTED EQUAL-TO
|
|
||||||
7/11 = U+03C0 # GREEK SMALL LETTER PI
|
|
||||||
7/12 = U+2260 # NOT EQUAL TO
|
|
||||||
7/13 = U+00A3 # POUND SIGN
|
|
||||||
7/14 = U+00B7 # MIDDLE DOT
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
static const struct StaticTableEncoding encoding_uk = {
|
||||||
|
{ .decode = &decode_table },
|
||||||
|
{
|
||||||
|
[0x23] = 0x00a3,
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1 +0,0 @@
|
|||||||
2/3 = "£"
|
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
void vterm_input_push_char(VTerm *vt, VTermModifier mod, uint32_t c)
|
void vterm_input_push_char(VTerm *vt, VTermModifier mod, uint32_t c)
|
||||||
{
|
{
|
||||||
|
int needs_CSIu;
|
||||||
|
|
||||||
/* The shift modifier is never important for Unicode characters
|
/* The shift modifier is never important for Unicode characters
|
||||||
* apart from Space
|
* apart from Space
|
||||||
*/
|
*/
|
||||||
@@ -20,7 +22,6 @@ void vterm_input_push_char(VTerm *vt, VTermModifier mod, uint32_t c)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int needs_CSIu;
|
|
||||||
switch(c) {
|
switch(c) {
|
||||||
/* Special Ctrl- letters that can't be represented elsewise */
|
/* Special Ctrl- letters that can't be represented elsewise */
|
||||||
case 'h': case 'i': case 'j': case 'm': case '[':
|
case 'h': case 'i': case 'j': case 'm': case '[':
|
||||||
@@ -123,10 +124,10 @@ static keycodes_s keycodes_kp[] = {
|
|||||||
|
|
||||||
void vterm_input_push_key(VTerm *vt, VTermModifier mod, VTermKey key)
|
void vterm_input_push_key(VTerm *vt, VTermModifier mod, VTermKey key)
|
||||||
{
|
{
|
||||||
|
keycodes_s k;
|
||||||
if(key == VTERM_KEY_NONE)
|
if(key == VTERM_KEY_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
keycodes_s k;
|
|
||||||
if(key < VTERM_KEY_FUNCTION_0) {
|
if(key < VTERM_KEY_FUNCTION_0) {
|
||||||
if(key >= sizeof(keycodes)/sizeof(keycodes[0]))
|
if(key >= sizeof(keycodes)/sizeof(keycodes[0]))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -18,11 +18,18 @@ static void do_control(VTerm *vt, unsigned char control)
|
|||||||
|
|
||||||
static void do_string_csi(VTerm *vt, const char *args, size_t arglen, char command)
|
static void do_string_csi(VTerm *vt, const char *args, size_t arglen, char command)
|
||||||
{
|
{
|
||||||
int i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
int leaderlen = 0;
|
int leaderlen = 0;
|
||||||
char leader[CSI_LEADER_MAX];
|
char leader[CSI_LEADER_MAX];
|
||||||
|
|
||||||
|
int argcount = 1; // Always at least 1 arg
|
||||||
|
long csi_args[CSI_ARGS_MAX];
|
||||||
|
int argi;
|
||||||
|
|
||||||
|
int intermedlen = 0;
|
||||||
|
char intermed[CSI_INTERMED_MAX];
|
||||||
|
|
||||||
// Extract leader bytes 0x3c to 0x3f
|
// Extract leader bytes 0x3c to 0x3f
|
||||||
for( ; i < arglen; i++) {
|
for( ; i < arglen; i++) {
|
||||||
if(args[i] < 0x3c || args[i] > 0x3f)
|
if(args[i] < 0x3c || args[i] > 0x3f)
|
||||||
@@ -33,18 +40,14 @@ static void do_string_csi(VTerm *vt, const char *args, size_t arglen, char comma
|
|||||||
|
|
||||||
leader[leaderlen] = 0;
|
leader[leaderlen] = 0;
|
||||||
|
|
||||||
int argcount = 1; // Always at least 1 arg
|
|
||||||
|
|
||||||
for( ; i < arglen; i++)
|
for( ; i < arglen; i++)
|
||||||
if(args[i] == 0x3b || args[i] == 0x3a) // ; or :
|
if(args[i] == 0x3b || args[i] == 0x3a) // ; or :
|
||||||
argcount++;
|
argcount++;
|
||||||
|
|
||||||
/* TODO: Consider if these buffers should live in the VTerm struct itself */
|
/* TODO: Consider if these buffers should live in the VTerm struct itself */
|
||||||
long csi_args[CSI_ARGS_MAX];
|
|
||||||
if(argcount > CSI_ARGS_MAX)
|
if(argcount > CSI_ARGS_MAX)
|
||||||
argcount = CSI_ARGS_MAX;
|
argcount = CSI_ARGS_MAX;
|
||||||
|
|
||||||
int argi;
|
|
||||||
for(argi = 0; argi < argcount; argi++)
|
for(argi = 0; argi < argcount; argi++)
|
||||||
csi_args[argi] = CSI_ARG_MISSING;
|
csi_args[argi] = CSI_ARG_MISSING;
|
||||||
|
|
||||||
@@ -70,9 +73,6 @@ static void do_string_csi(VTerm *vt, const char *args, size_t arglen, char comma
|
|||||||
}
|
}
|
||||||
done_leader: ;
|
done_leader: ;
|
||||||
|
|
||||||
int intermedlen = 0;
|
|
||||||
char intermed[CSI_INTERMED_MAX];
|
|
||||||
|
|
||||||
for( ; i < arglen; i++) {
|
for( ; i < arglen; i++) {
|
||||||
if((args[i] & 0xf0) != 0x20)
|
if((args[i] & 0xf0) != 0x20)
|
||||||
break;
|
break;
|
||||||
@@ -118,6 +118,8 @@ static void append_strbuffer(VTerm *vt, const char *str, size_t len)
|
|||||||
|
|
||||||
static size_t do_string(VTerm *vt, const char *str_frag, size_t len)
|
static size_t do_string(VTerm *vt, const char *str_frag, size_t len)
|
||||||
{
|
{
|
||||||
|
size_t eaten;
|
||||||
|
|
||||||
if(vt->strbuffer_cur) {
|
if(vt->strbuffer_cur) {
|
||||||
if(str_frag)
|
if(str_frag)
|
||||||
append_strbuffer(vt, str_frag, len);
|
append_strbuffer(vt, str_frag, len);
|
||||||
@@ -132,8 +134,6 @@ static size_t do_string(VTerm *vt, const char *str_frag, size_t len)
|
|||||||
|
|
||||||
vt->strbuffer_cur = 0;
|
vt->strbuffer_cur = 0;
|
||||||
|
|
||||||
size_t eaten;
|
|
||||||
|
|
||||||
switch(vt->parser_state) {
|
switch(vt->parser_state) {
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
if(vt->parser_callbacks && vt->parser_callbacks->text)
|
if(vt->parser_callbacks && vt->parser_callbacks->text)
|
||||||
@@ -190,7 +190,7 @@ static size_t do_string(VTerm *vt, const char *str_frag, size_t len)
|
|||||||
void vterm_push_bytes(VTerm *vt, const char *bytes, size_t len)
|
void vterm_push_bytes(VTerm *vt, const char *bytes, size_t len)
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
const char *string_start;
|
const char *string_start = NULL;
|
||||||
|
|
||||||
switch(vt->parser_state) {
|
switch(vt->parser_state) {
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
|
|||||||
@@ -135,11 +135,12 @@ static void set_pen_col_ansi(VTermState *state, VTermAttr attr, long col)
|
|||||||
|
|
||||||
INTERNAL void vterm_state_newpen(VTermState *state)
|
INTERNAL void vterm_state_newpen(VTermState *state)
|
||||||
{
|
{
|
||||||
|
int col;
|
||||||
// 90% grey so that pure white is brighter
|
// 90% grey so that pure white is brighter
|
||||||
state->default_fg.red = state->default_fg.green = state->default_fg.blue = 240;
|
state->default_fg.red = state->default_fg.green = state->default_fg.blue = 240;
|
||||||
state->default_bg.red = state->default_bg.green = state->default_bg.blue = 0;
|
state->default_bg.red = state->default_bg.green = state->default_bg.blue = 0;
|
||||||
|
|
||||||
for(int col = 0; col < 16; col++)
|
for(col = 0; col < 16; col++)
|
||||||
state->colors[col] = ansi_colors[col];
|
state->colors[col] = ansi_colors[col];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,9 +80,10 @@ static inline ScreenCell *getcell(const VTermScreen *screen, int row, int col)
|
|||||||
static ScreenCell *realloc_buffer(VTermScreen *screen, ScreenCell *buffer, int new_rows, int new_cols)
|
static ScreenCell *realloc_buffer(VTermScreen *screen, ScreenCell *buffer, int new_rows, int new_cols)
|
||||||
{
|
{
|
||||||
ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, sizeof(ScreenCell) * new_rows * new_cols);
|
ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, sizeof(ScreenCell) * new_rows * new_cols);
|
||||||
|
int row, col;
|
||||||
|
|
||||||
for(int row = 0; row < new_rows; row++) {
|
for(row = 0; row < new_rows; row++) {
|
||||||
for(int col = 0; col < new_cols; col++) {
|
for(col = 0; col < new_cols; col++) {
|
||||||
ScreenCell *new_cell = new_buffer + row*new_cols + col;
|
ScreenCell *new_cell = new_buffer + row*new_cols + col;
|
||||||
|
|
||||||
if(buffer && row < screen->rows && col < screen->cols)
|
if(buffer && row < screen->rows && col < screen->cols)
|
||||||
@@ -173,11 +174,12 @@ static int putglyph(VTermGlyphInfo *info, VTermPos pos, void *user)
|
|||||||
{
|
{
|
||||||
VTermScreen *screen = user;
|
VTermScreen *screen = user;
|
||||||
ScreenCell *cell = getcell(screen, pos.row, pos.col);
|
ScreenCell *cell = getcell(screen, pos.row, pos.col);
|
||||||
|
int i, col;
|
||||||
|
VTermRect rect;
|
||||||
|
|
||||||
if(!cell)
|
if(!cell)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < VTERM_MAX_CHARS_PER_CELL && info->chars[i]; i++) {
|
for(i = 0; i < VTERM_MAX_CHARS_PER_CELL && info->chars[i]; i++) {
|
||||||
cell->chars[i] = info->chars[i];
|
cell->chars[i] = info->chars[i];
|
||||||
cell->pen = screen->pen;
|
cell->pen = screen->pen;
|
||||||
@@ -185,15 +187,13 @@ static int putglyph(VTermGlyphInfo *info, VTermPos pos, void *user)
|
|||||||
if(i < VTERM_MAX_CHARS_PER_CELL)
|
if(i < VTERM_MAX_CHARS_PER_CELL)
|
||||||
cell->chars[i] = 0;
|
cell->chars[i] = 0;
|
||||||
|
|
||||||
for(int col = 1; col < info->width; col++)
|
for(col = 1; col < info->width; col++)
|
||||||
getcell(screen, pos.row, pos.col + col)->chars[0] = (uint32_t)-1;
|
getcell(screen, pos.row, pos.col + col)->chars[0] = (uint32_t)-1;
|
||||||
|
|
||||||
VTermRect rect = {
|
rect.start_row = pos.row;
|
||||||
.start_row = pos.row,
|
rect.end_row = pos.row+1;
|
||||||
.end_row = pos.row+1,
|
rect.start_col = pos.col;
|
||||||
.start_col = pos.col,
|
rect.end_col = pos.col+info->width;
|
||||||
.end_col = pos.col+info->width,
|
|
||||||
};
|
|
||||||
|
|
||||||
cell->pen.protected_cell = info->protected_cell;
|
cell->pen.protected_cell = info->protected_cell;
|
||||||
cell->pen.dwl = info->dwl;
|
cell->pen.dwl = info->dwl;
|
||||||
@@ -207,6 +207,8 @@ static int putglyph(VTermGlyphInfo *info, VTermPos pos, void *user)
|
|||||||
static int moverect_internal(VTermRect dest, VTermRect src, void *user)
|
static int moverect_internal(VTermRect dest, VTermRect src, void *user)
|
||||||
{
|
{
|
||||||
VTermScreen *screen = user;
|
VTermScreen *screen = user;
|
||||||
|
int cols, downward, row;
|
||||||
|
int init_row, test_row, inc_row;
|
||||||
|
|
||||||
if(screen->callbacks && screen->callbacks->sb_pushline &&
|
if(screen->callbacks && screen->callbacks->sb_pushline &&
|
||||||
dest.start_row == 0 && dest.start_col == 0 && // starts top-left corner
|
dest.start_row == 0 && dest.start_col == 0 && // starts top-left corner
|
||||||
@@ -221,10 +223,9 @@ static int moverect_internal(VTermRect dest, VTermRect src, void *user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cols = src.end_col - src.start_col;
|
cols = src.end_col - src.start_col;
|
||||||
int downward = src.start_row - dest.start_row;
|
downward = src.start_row - dest.start_row;
|
||||||
|
|
||||||
int init_row, test_row, inc_row;
|
|
||||||
if(downward < 0) {
|
if(downward < 0) {
|
||||||
init_row = dest.end_row - 1;
|
init_row = dest.end_row - 1;
|
||||||
test_row = dest.start_row - 1;
|
test_row = dest.start_row - 1;
|
||||||
@@ -236,7 +237,7 @@ static int moverect_internal(VTermRect dest, VTermRect src, void *user)
|
|||||||
inc_row = +1;
|
inc_row = +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int row = init_row; row != test_row; row += inc_row)
|
for(row = init_row; row != test_row; row += inc_row)
|
||||||
memmove(getcell(screen, row, dest.start_col),
|
memmove(getcell(screen, row, dest.start_col),
|
||||||
getcell(screen, row + downward, src.start_col),
|
getcell(screen, row + downward, src.start_col),
|
||||||
cols * sizeof(ScreenCell));
|
cols * sizeof(ScreenCell));
|
||||||
@@ -265,11 +266,12 @@ static int moverect_user(VTermRect dest, VTermRect src, void *user)
|
|||||||
static int erase_internal(VTermRect rect, int selective, void *user)
|
static int erase_internal(VTermRect rect, int selective, void *user)
|
||||||
{
|
{
|
||||||
VTermScreen *screen = user;
|
VTermScreen *screen = user;
|
||||||
|
int row, col;
|
||||||
|
|
||||||
for(int row = rect.start_row; row < rect.end_row; row++) {
|
for(row = rect.start_row; row < rect.end_row; row++) {
|
||||||
const VTermLineInfo *info = vterm_state_get_lineinfo(screen->state, row);
|
const VTermLineInfo *info = vterm_state_get_lineinfo(screen->state, row);
|
||||||
|
|
||||||
for(int col = rect.start_col; col < rect.end_col; col++) {
|
for(col = rect.start_col; col < rect.end_col; col++) {
|
||||||
ScreenCell *cell = getcell(screen, row, col);
|
ScreenCell *cell = getcell(screen, row, col);
|
||||||
|
|
||||||
if(selective && cell->pen.protected_cell)
|
if(selective && cell->pen.protected_cell)
|
||||||
@@ -485,6 +487,8 @@ static int resize(int new_rows, int new_cols, VTermPos *delta, void *user)
|
|||||||
|
|
||||||
int old_rows = screen->rows;
|
int old_rows = screen->rows;
|
||||||
int old_cols = screen->cols;
|
int old_cols = screen->cols;
|
||||||
|
int first_blank_row;
|
||||||
|
VTermRect rect;
|
||||||
|
|
||||||
if(!is_altscreen && new_rows < old_rows) {
|
if(!is_altscreen && new_rows < old_rows) {
|
||||||
// Fewer rows - determine if we're going to scroll at all, and if so, push
|
// Fewer rows - determine if we're going to scroll at all, and if so, push
|
||||||
@@ -494,7 +498,7 @@ static int resize(int new_rows, int new_cols, VTermPos *delta, void *user)
|
|||||||
if(!vterm_screen_is_eol(screen, pos))
|
if(!vterm_screen_is_eol(screen, pos))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int first_blank_row = pos.row + 1;
|
first_blank_row = pos.row + 1;
|
||||||
if(first_blank_row > new_rows) {
|
if(first_blank_row > new_rows) {
|
||||||
VTermRect rect = {
|
VTermRect rect = {
|
||||||
.start_row = 0,
|
.start_row = 0,
|
||||||
@@ -537,18 +541,19 @@ static int resize(int new_rows, int new_cols, VTermPos *delta, void *user)
|
|||||||
if(!is_altscreen && screen->callbacks && screen->callbacks->sb_popline) {
|
if(!is_altscreen && screen->callbacks && screen->callbacks->sb_popline) {
|
||||||
int rows = new_rows - old_rows;
|
int rows = new_rows - old_rows;
|
||||||
while(rows) {
|
while(rows) {
|
||||||
if(!(screen->callbacks->sb_popline(screen->cols, screen->sb_buffer, screen->cbdata)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
VTermRect rect = {
|
VTermRect rect = {
|
||||||
.start_row = 0,
|
.start_row = 0,
|
||||||
.end_row = screen->rows,
|
.end_row = screen->rows,
|
||||||
.start_col = 0,
|
.start_col = 0,
|
||||||
.end_col = screen->cols,
|
.end_col = screen->cols,
|
||||||
};
|
};
|
||||||
|
VTermPos pos = { 0, 0 };
|
||||||
|
|
||||||
|
if(!(screen->callbacks->sb_popline(screen->cols, screen->sb_buffer, screen->cbdata)))
|
||||||
|
break;
|
||||||
|
|
||||||
scrollrect(rect, -1, 0, user);
|
scrollrect(rect, -1, 0, user);
|
||||||
|
|
||||||
VTermPos pos = { 0, 0 };
|
|
||||||
for(pos.col = 0; pos.col < screen->cols; pos.col += screen->sb_buffer[pos.col].width)
|
for(pos.col = 0; pos.col < screen->cols; pos.col += screen->sb_buffer[pos.col].width)
|
||||||
vterm_screen_set_cell(screen, pos, screen->sb_buffer + pos.col);
|
vterm_screen_set_cell(screen, pos, screen->sb_buffer + pos.col);
|
||||||
|
|
||||||
@@ -562,12 +567,10 @@ static int resize(int new_rows, int new_cols, VTermPos *delta, void *user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VTermRect rect = {
|
rect.start_row = old_rows;
|
||||||
.start_row = old_rows,
|
rect.end_row = new_rows;
|
||||||
.end_row = new_rows,
|
rect.start_col = 0;
|
||||||
.start_col = 0,
|
rect.end_col = new_cols;
|
||||||
.end_col = new_cols,
|
|
||||||
};
|
|
||||||
damagerect(screen, rect);
|
damagerect(screen, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,18 +586,18 @@ static int setlineinfo(int row, const VTermLineInfo *newinfo, const VTermLineInf
|
|||||||
|
|
||||||
if(newinfo->doublewidth != oldinfo->doublewidth ||
|
if(newinfo->doublewidth != oldinfo->doublewidth ||
|
||||||
newinfo->doubleheight != oldinfo->doubleheight) {
|
newinfo->doubleheight != oldinfo->doubleheight) {
|
||||||
for(int col = 0; col < screen->cols; col++) {
|
VTermRect rect;
|
||||||
|
int col;
|
||||||
|
for(col = 0; col < screen->cols; col++) {
|
||||||
ScreenCell *cell = getcell(screen, row, col);
|
ScreenCell *cell = getcell(screen, row, col);
|
||||||
cell->pen.dwl = newinfo->doublewidth;
|
cell->pen.dwl = newinfo->doublewidth;
|
||||||
cell->pen.dhl = newinfo->doubleheight;
|
cell->pen.dhl = newinfo->doubleheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
VTermRect rect = {
|
rect.start_row = row;
|
||||||
.start_row = row,
|
rect.end_row = row + 1;
|
||||||
.end_row = row + 1,
|
rect.start_col = 0;
|
||||||
.start_col = 0,
|
rect.end_col = newinfo->doublewidth ? screen->cols / 2 : screen->cols;
|
||||||
.end_col = newinfo->doublewidth ? screen->cols / 2 : screen->cols,
|
|
||||||
};
|
|
||||||
damagerect(screen, rect);
|
damagerect(screen, rect);
|
||||||
|
|
||||||
if(newinfo->doublewidth) {
|
if(newinfo->doublewidth) {
|
||||||
@@ -624,11 +627,13 @@ static VTermStateCallbacks state_cbs = {
|
|||||||
static VTermScreen *screen_new(VTerm *vt)
|
static VTermScreen *screen_new(VTerm *vt)
|
||||||
{
|
{
|
||||||
VTermState *state = vterm_obtain_state(vt);
|
VTermState *state = vterm_obtain_state(vt);
|
||||||
|
int rows, cols;
|
||||||
|
VTermScreen *screen;
|
||||||
|
|
||||||
if(!state)
|
if(!state)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
VTermScreen *screen = vterm_allocator_malloc(vt, sizeof(VTermScreen));
|
screen = vterm_allocator_malloc(vt, sizeof(VTermScreen));
|
||||||
int rows, cols;
|
|
||||||
|
|
||||||
vterm_get_size(vt, &rows, &cols);
|
vterm_get_size(vt, &rows, &cols);
|
||||||
|
|
||||||
@@ -676,6 +681,7 @@ static size_t _get_chars(const VTermScreen *screen, const int utf8, void *buffer
|
|||||||
{
|
{
|
||||||
size_t outpos = 0;
|
size_t outpos = 0;
|
||||||
int padding = 0;
|
int padding = 0;
|
||||||
|
int row, col;
|
||||||
|
|
||||||
#define PUT(c) \
|
#define PUT(c) \
|
||||||
if(utf8) { \
|
if(utf8) { \
|
||||||
@@ -692,8 +698,8 @@ static size_t _get_chars(const VTermScreen *screen, const int utf8, void *buffer
|
|||||||
outpos++; \
|
outpos++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int row = rect.start_row; row < rect.end_row; row++) {
|
for(row = rect.start_row; row < rect.end_row; row++) {
|
||||||
for(int col = rect.start_col; col < rect.end_col; col++) {
|
for(col = rect.start_col; col < rect.end_col; col++) {
|
||||||
ScreenCell *cell = getcell(screen, row, col);
|
ScreenCell *cell = getcell(screen, row, col);
|
||||||
|
|
||||||
if(cell->chars[0] == 0)
|
if(cell->chars[0] == 0)
|
||||||
@@ -703,11 +709,12 @@ static size_t _get_chars(const VTermScreen *screen, const int utf8, void *buffer
|
|||||||
// Gap behind a double-width char, do nothing
|
// Gap behind a double-width char, do nothing
|
||||||
;
|
;
|
||||||
else {
|
else {
|
||||||
|
int i;
|
||||||
while(padding) {
|
while(padding) {
|
||||||
PUT(UNICODE_SPACE);
|
PUT(UNICODE_SPACE);
|
||||||
padding--;
|
padding--;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < VTERM_MAX_CHARS_PER_CELL && cell->chars[i]; i++) {
|
for(i = 0; i < VTERM_MAX_CHARS_PER_CELL && cell->chars[i]; i++) {
|
||||||
PUT(cell->chars[i]);
|
PUT(cell->chars[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -736,10 +743,11 @@ size_t vterm_screen_get_text(const VTermScreen *screen, char *str, size_t len, c
|
|||||||
int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCell *cell)
|
int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCell *cell)
|
||||||
{
|
{
|
||||||
ScreenCell *intcell = getcell(screen, pos.row, pos.col);
|
ScreenCell *intcell = getcell(screen, pos.row, pos.col);
|
||||||
|
int i;
|
||||||
if(!intcell)
|
if(!intcell)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for(int i = 0; ; i++) {
|
for(i = 0; ; i++) {
|
||||||
cell->chars[i] = intcell->chars[i];
|
cell->chars[i] = intcell->chars[i];
|
||||||
if(!intcell->chars[i])
|
if(!intcell->chars[i])
|
||||||
break;
|
break;
|
||||||
@@ -773,10 +781,12 @@ int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCe
|
|||||||
static int vterm_screen_set_cell(VTermScreen *screen, VTermPos pos, const VTermScreenCell *cell)
|
static int vterm_screen_set_cell(VTermScreen *screen, VTermPos pos, const VTermScreenCell *cell)
|
||||||
{
|
{
|
||||||
ScreenCell *intcell = getcell(screen, pos.row, pos.col);
|
ScreenCell *intcell = getcell(screen, pos.row, pos.col);
|
||||||
|
int i;
|
||||||
|
|
||||||
if(!intcell)
|
if(!intcell)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for(int i = 0; ; i++) {
|
for(i = 0; ; i++) {
|
||||||
intcell->chars[i] = cell->chars[i];
|
intcell->chars[i] = cell->chars[i];
|
||||||
if(!cell->chars[i])
|
if(!cell->chars[i])
|
||||||
break;
|
break;
|
||||||
@@ -813,10 +823,11 @@ int vterm_screen_is_eol(const VTermScreen *screen, VTermPos pos)
|
|||||||
|
|
||||||
VTermScreen *vterm_obtain_screen(VTerm *vt)
|
VTermScreen *vterm_obtain_screen(VTerm *vt)
|
||||||
{
|
{
|
||||||
|
VTermScreen *screen;
|
||||||
if(vt->screen)
|
if(vt->screen)
|
||||||
return vt->screen;
|
return vt->screen;
|
||||||
|
|
||||||
VTermScreen *screen = screen_new(vt);
|
screen = screen_new(vt);
|
||||||
vt->screen = screen;
|
vt->screen = screen;
|
||||||
|
|
||||||
return screen;
|
return screen;
|
||||||
@@ -890,6 +901,8 @@ int vterm_screen_get_attrs_extent(const VTermScreen *screen, VTermRect *extent,
|
|||||||
{
|
{
|
||||||
ScreenCell *target = getcell(screen, pos.row, pos.col);
|
ScreenCell *target = getcell(screen, pos.row, pos.col);
|
||||||
|
|
||||||
|
int col;
|
||||||
|
|
||||||
// TODO: bounds check
|
// TODO: bounds check
|
||||||
extent->start_row = pos.row;
|
extent->start_row = pos.row;
|
||||||
extent->end_row = pos.row + 1;
|
extent->end_row = pos.row + 1;
|
||||||
@@ -899,8 +912,6 @@ int vterm_screen_get_attrs_extent(const VTermScreen *screen, VTermRect *extent,
|
|||||||
if(extent->end_col < 0)
|
if(extent->end_col < 0)
|
||||||
extent->end_col = screen->cols;
|
extent->end_col = screen->cols;
|
||||||
|
|
||||||
int col;
|
|
||||||
|
|
||||||
for(col = pos.col - 1; col >= extent->start_col; col--)
|
for(col = pos.col - 1; col >= extent->start_col; col--)
|
||||||
if(attrs_differ(attrs, target, getcell(screen, pos.row, col)))
|
if(attrs_differ(attrs, target, getcell(screen, pos.row, col)))
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ static int on_text(const char bytes[], size_t len, void *user)
|
|||||||
uint32_t codepoints[len];
|
uint32_t codepoints[len];
|
||||||
int npoints = 0;
|
int npoints = 0;
|
||||||
size_t eaten = 0;
|
size_t eaten = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
VTermEncodingInstance *encoding =
|
VTermEncodingInstance *encoding =
|
||||||
state->gsingle_set ? &state->encoding[state->gsingle_set] :
|
state->gsingle_set ? &state->encoding[state->gsingle_set] :
|
||||||
@@ -222,8 +223,6 @@ static int on_text(const char bytes[], size_t len, void *user)
|
|||||||
if(state->gsingle_set && npoints)
|
if(state->gsingle_set && npoints)
|
||||||
state->gsingle_set = 0;
|
state->gsingle_set = 0;
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
/* This is a combining char. that needs to be merged with the previous
|
/* This is a combining char. that needs to be merged with the previous
|
||||||
* glyph output */
|
* glyph output */
|
||||||
if(vterm_unicode_is_combining(codepoints[i])) {
|
if(vterm_unicode_is_combining(codepoints[i])) {
|
||||||
@@ -238,7 +237,7 @@ static int on_text(const char bytes[], size_t len, void *user)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find where we need to append these combining chars */
|
/* Find where we need to append these combining chars */
|
||||||
int saved_i = 0;
|
unsigned saved_i = 0;
|
||||||
while(state->combine_chars[saved_i])
|
while(state->combine_chars[saved_i])
|
||||||
saved_i++;
|
saved_i++;
|
||||||
|
|
||||||
@@ -270,13 +269,14 @@ static int on_text(const char bytes[], size_t len, void *user)
|
|||||||
// Try to find combining characters following this
|
// Try to find combining characters following this
|
||||||
int glyph_starts = i;
|
int glyph_starts = i;
|
||||||
int glyph_ends;
|
int glyph_ends;
|
||||||
|
int width = 0;
|
||||||
|
uint32_t* chars;
|
||||||
|
|
||||||
for(glyph_ends = i + 1; glyph_ends < npoints; glyph_ends++)
|
for(glyph_ends = i + 1; glyph_ends < npoints; glyph_ends++)
|
||||||
if(!vterm_unicode_is_combining(codepoints[glyph_ends]))
|
if(!vterm_unicode_is_combining(codepoints[glyph_ends]))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int width = 0;
|
chars = alloca(glyph_ends - glyph_starts + 1);
|
||||||
|
|
||||||
uint32_t chars[glyph_ends - glyph_starts + 1];
|
|
||||||
|
|
||||||
for( ; i < glyph_ends; i++) {
|
for( ; i < glyph_ends; i++) {
|
||||||
chars[i - glyph_starts] = codepoints[i];
|
chars[i - glyph_starts] = codepoints[i];
|
||||||
@@ -319,7 +319,7 @@ static int on_text(const char bytes[], size_t len, void *user)
|
|||||||
if(i == npoints - 1) {
|
if(i == npoints - 1) {
|
||||||
/* End of the buffer. Save the chars in case we have to combine with
|
/* End of the buffer. Save the chars in case we have to combine with
|
||||||
* more on the next call */
|
* more on the next call */
|
||||||
int save_i;
|
unsigned save_i;
|
||||||
for(save_i = 0; chars[save_i]; save_i++) {
|
for(save_i = 0; chars[save_i]; save_i++) {
|
||||||
if(save_i >= state->combine_chars_size)
|
if(save_i >= state->combine_chars_size)
|
||||||
grow_combine_buffer(state);
|
grow_combine_buffer(state);
|
||||||
@@ -537,10 +537,11 @@ static int settermprop_int(VTermState *state, VTermProp prop, int v)
|
|||||||
static int settermprop_string(VTermState *state, VTermProp prop, const char *str, size_t len)
|
static int settermprop_string(VTermState *state, VTermProp prop, const char *str, size_t len)
|
||||||
{
|
{
|
||||||
char strvalue[len+1];
|
char strvalue[len+1];
|
||||||
|
VTermValue val = { .string = strvalue };
|
||||||
|
|
||||||
strncpy(strvalue, str, len);
|
strncpy(strvalue, str, len);
|
||||||
strvalue[len] = 0;
|
strvalue[len] = 0;
|
||||||
|
|
||||||
VTermValue val = { .string = strvalue };
|
|
||||||
return vterm_state_set_termprop(state, prop, &val);
|
return vterm_state_set_termprop(state, prop, &val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,8 +765,9 @@ static void set_dec_mode(VTermState *state, int num, int val)
|
|||||||
// DECLRMM - left/right margin mode
|
// DECLRMM - left/right margin mode
|
||||||
state->mode.leftrightmargin = val;
|
state->mode.leftrightmargin = val;
|
||||||
if(val) {
|
if(val) {
|
||||||
|
int row;
|
||||||
// Setting DECVSSM must clear doublewidth/doubleheight state of every line
|
// Setting DECVSSM must clear doublewidth/doubleheight state of every line
|
||||||
for(int row = 0; row < state->rows; row++)
|
for(row = 0; row < state->rows; row++)
|
||||||
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -899,9 +901,16 @@ static void request_dec_mode(VTermState *state, int num)
|
|||||||
static int on_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user)
|
static int on_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user)
|
||||||
{
|
{
|
||||||
VTermState *state = user;
|
VTermState *state = user;
|
||||||
|
VTermPos oldpos;
|
||||||
int leader_byte = 0;
|
int leader_byte = 0;
|
||||||
int intermed_byte = 0;
|
int intermed_byte = 0;
|
||||||
|
|
||||||
|
// Some temporaries for later code
|
||||||
|
int count, val;
|
||||||
|
int row, col;
|
||||||
|
VTermRect rect;
|
||||||
|
int selective;
|
||||||
|
|
||||||
if(leader && leader[0]) {
|
if(leader && leader[0]) {
|
||||||
if(leader[1]) // longer than 1 char
|
if(leader[1]) // longer than 1 char
|
||||||
return 0;
|
return 0;
|
||||||
@@ -932,13 +941,7 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VTermPos oldpos = state->pos;
|
oldpos = state->pos;
|
||||||
|
|
||||||
// Some temporaries for later code
|
|
||||||
int count, val;
|
|
||||||
int row, col;
|
|
||||||
VTermRect rect;
|
|
||||||
int selective;
|
|
||||||
|
|
||||||
#define LBOUND(v,min) if((v) < (min)) (v) = (min)
|
#define LBOUND(v,min) if((v) < (min)) (v) = (min)
|
||||||
#define UBOUND(v,max) if((v) > (max)) (v) = (max)
|
#define UBOUND(v,max) if((v) > (max)) (v) = (max)
|
||||||
@@ -1037,7 +1040,7 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
|
|||||||
|
|
||||||
rect.start_row = state->pos.row + 1; rect.end_row = state->rows;
|
rect.start_row = state->pos.row + 1; rect.end_row = state->rows;
|
||||||
rect.start_col = 0;
|
rect.start_col = 0;
|
||||||
for(int row = rect.start_row; row < rect.end_row; row++)
|
for(row = rect.start_row; row < rect.end_row; row++)
|
||||||
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
||||||
if(rect.end_row > rect.start_row)
|
if(rect.end_row > rect.start_row)
|
||||||
erase(state, rect, selective);
|
erase(state, rect, selective);
|
||||||
@@ -1046,7 +1049,7 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
|
|||||||
case 1:
|
case 1:
|
||||||
rect.start_row = 0; rect.end_row = state->pos.row;
|
rect.start_row = 0; rect.end_row = state->pos.row;
|
||||||
rect.start_col = 0; rect.end_col = state->cols;
|
rect.start_col = 0; rect.end_col = state->cols;
|
||||||
for(int row = rect.start_row; row < rect.end_row; row++)
|
for(row = rect.start_row; row < rect.end_row; row++)
|
||||||
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
||||||
if(rect.end_col > rect.start_col)
|
if(rect.end_col > rect.start_col)
|
||||||
erase(state, rect, selective);
|
erase(state, rect, selective);
|
||||||
@@ -1060,7 +1063,7 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
|
|||||||
case 2:
|
case 2:
|
||||||
rect.start_row = 0; rect.end_row = state->rows;
|
rect.start_row = 0; rect.end_row = state->rows;
|
||||||
rect.start_col = 0; rect.end_col = state->cols;
|
rect.start_col = 0; rect.end_col = state->cols;
|
||||||
for(int row = rect.start_row; row < rect.end_row; row++)
|
for(row = rect.start_row; row < rect.end_row; row++)
|
||||||
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
||||||
erase(state, rect, selective);
|
erase(state, rect, selective);
|
||||||
break;
|
break;
|
||||||
@@ -1459,8 +1462,9 @@ static void request_status_string(VTermState *state, const char *command, size_t
|
|||||||
{
|
{
|
||||||
long args[20];
|
long args[20];
|
||||||
int argc = vterm_state_getpen(state, args, sizeof(args)/sizeof(args[0]));
|
int argc = vterm_state_getpen(state, args, sizeof(args)/sizeof(args[0]));
|
||||||
|
int argi;
|
||||||
vterm_push_output_sprintf_ctrl(state->vt, C1_DCS, "1$r");
|
vterm_push_output_sprintf_ctrl(state->vt, C1_DCS, "1$r");
|
||||||
for(int argi = 0; argi < argc; argi++)
|
for(argi = 0; argi < argc; argi++)
|
||||||
vterm_push_output_sprintf(state->vt,
|
vterm_push_output_sprintf(state->vt,
|
||||||
argi == argc - 1 ? "%d" :
|
argi == argc - 1 ? "%d" :
|
||||||
CSI_ARG_HAS_MORE(args[argi]) ? "%d:" :
|
CSI_ARG_HAS_MORE(args[argi]) ? "%d:" :
|
||||||
@@ -1480,7 +1484,7 @@ static void request_status_string(VTermState *state, const char *command, size_t
|
|||||||
|
|
||||||
if(cmdlen == 2) {
|
if(cmdlen == 2) {
|
||||||
if(strneq(command, " q", 2)) {
|
if(strneq(command, " q", 2)) {
|
||||||
int reply;
|
int reply = 0;
|
||||||
switch(state->mode.cursor_shape) {
|
switch(state->mode.cursor_shape) {
|
||||||
case VTERM_PROP_CURSORSHAPE_BLOCK: reply = 2; break;
|
case VTERM_PROP_CURSORSHAPE_BLOCK: reply = 2; break;
|
||||||
case VTERM_PROP_CURSORSHAPE_UNDERLINE: reply = 4; break;
|
case VTERM_PROP_CURSORSHAPE_UNDERLINE: reply = 4; break;
|
||||||
@@ -1516,6 +1520,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 };
|
||||||
|
|
||||||
if(cols != state->cols) {
|
if(cols != state->cols) {
|
||||||
unsigned char *newtabstops = vterm_allocator_malloc(state->vt, (cols + 7) / 8);
|
unsigned char *newtabstops = vterm_allocator_malloc(state->vt, (cols + 7) / 8);
|
||||||
@@ -1563,8 +1568,6 @@ static int on_resize(int rows, int cols, void *user)
|
|||||||
state->rows = rows;
|
state->rows = rows;
|
||||||
state->cols = cols;
|
state->cols = cols;
|
||||||
|
|
||||||
VTermPos delta = { 0, 0 };
|
|
||||||
|
|
||||||
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, &delta, state->cbdata);
|
||||||
|
|
||||||
@@ -1598,10 +1601,11 @@ static const VTermParserCallbacks parser_callbacks = {
|
|||||||
|
|
||||||
VTermState *vterm_obtain_state(VTerm *vt)
|
VTermState *vterm_obtain_state(VTerm *vt)
|
||||||
{
|
{
|
||||||
|
VTermState *state;
|
||||||
if(vt->state)
|
if(vt->state)
|
||||||
return vt->state;
|
return vt->state;
|
||||||
|
|
||||||
VTermState *state = vterm_state_new(vt);
|
state = vterm_state_new(vt);
|
||||||
vt->state = state;
|
vt->state = state;
|
||||||
|
|
||||||
state->combine_chars_size = 16;
|
state->combine_chars_size = 16;
|
||||||
@@ -1622,6 +1626,9 @@ VTermState *vterm_obtain_state(VTerm *vt)
|
|||||||
|
|
||||||
void vterm_state_reset(VTermState *state, int hard)
|
void vterm_state_reset(VTermState *state, int hard)
|
||||||
{
|
{
|
||||||
|
int col, i, row;
|
||||||
|
VTermEncoding *default_enc;
|
||||||
|
|
||||||
state->scrollregion_top = 0;
|
state->scrollregion_top = 0;
|
||||||
state->scrollregion_bottom = -1;
|
state->scrollregion_bottom = -1;
|
||||||
state->scrollregion_left = 0;
|
state->scrollregion_left = 0;
|
||||||
@@ -1638,13 +1645,13 @@ void vterm_state_reset(VTermState *state, int hard)
|
|||||||
|
|
||||||
state->vt->mode.ctrl8bit = 0;
|
state->vt->mode.ctrl8bit = 0;
|
||||||
|
|
||||||
for(int col = 0; col < state->cols; col++)
|
for(col = 0; col < state->cols; col++)
|
||||||
if(col % 8 == 0)
|
if(col % 8 == 0)
|
||||||
set_col_tabstop(state, col);
|
set_col_tabstop(state, col);
|
||||||
else
|
else
|
||||||
clear_col_tabstop(state, col);
|
clear_col_tabstop(state, col);
|
||||||
|
|
||||||
for(int row = 0; row < state->rows; row++)
|
for(row = 0; row < state->rows; row++)
|
||||||
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
set_lineinfo(state, row, FORCE, DWL_OFF, DHL_OFF);
|
||||||
|
|
||||||
if(state->callbacks && state->callbacks->initpen)
|
if(state->callbacks && state->callbacks->initpen)
|
||||||
@@ -1652,11 +1659,11 @@ void vterm_state_reset(VTermState *state, int hard)
|
|||||||
|
|
||||||
vterm_state_resetpen(state);
|
vterm_state_resetpen(state);
|
||||||
|
|
||||||
VTermEncoding *default_enc = state->vt->mode.utf8 ?
|
default_enc = state->vt->mode.utf8 ?
|
||||||
vterm_lookup_encoding(ENC_UTF8, 'u') :
|
vterm_lookup_encoding(ENC_UTF8, 'u') :
|
||||||
vterm_lookup_encoding(ENC_SINGLE_94, 'B');
|
vterm_lookup_encoding(ENC_SINGLE_94, 'B');
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++) {
|
for(i = 0; i < 4; i++) {
|
||||||
state->encoding[i].enc = default_enc;
|
state->encoding[i].enc = default_enc;
|
||||||
if(default_enc->init)
|
if(default_enc->init)
|
||||||
(*default_enc->init)(default_enc, state->encoding[i].data);
|
(*default_enc->init)(default_enc, state->encoding[i].data);
|
||||||
@@ -1674,11 +1681,11 @@ void vterm_state_reset(VTermState *state, int hard)
|
|||||||
settermprop_int (state, VTERM_PROP_CURSORSHAPE, VTERM_PROP_CURSORSHAPE_BLOCK);
|
settermprop_int (state, VTERM_PROP_CURSORSHAPE, VTERM_PROP_CURSORSHAPE_BLOCK);
|
||||||
|
|
||||||
if(hard) {
|
if(hard) {
|
||||||
|
VTermRect rect = { 0, state->rows, 0, state->cols };
|
||||||
state->pos.row = 0;
|
state->pos.row = 0;
|
||||||
state->pos.col = 0;
|
state->pos.col = 0;
|
||||||
state->at_phantom = 0;
|
state->at_phantom = 0;
|
||||||
|
|
||||||
VTermRect rect = { 0, state->rows, 0, state->cols };
|
|
||||||
erase(state, rect, 0);
|
erase(state, rect, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ static int mk_wcwidth(wchar_t ucs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
static int mk_wcswidth(const wchar_t *pwcs, size_t n)
|
static int mk_wcswidth(const wchar_t *pwcs, size_t n)
|
||||||
{
|
{
|
||||||
int w, width = 0;
|
int w, width = 0;
|
||||||
@@ -304,7 +305,6 @@ static int mk_wcwidth_cjk(wchar_t ucs)
|
|||||||
return mk_wcwidth(ucs);
|
return mk_wcwidth(ucs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
|
static int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
|
||||||
{
|
{
|
||||||
int w, width = 0;
|
int w, width = 0;
|
||||||
@@ -317,6 +317,7 @@ static int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
|
|||||||
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// ################################
|
// ################################
|
||||||
// ### The rest added by Paul Evans
|
// ### The rest added by Paul Evans
|
||||||
|
|||||||
@@ -137,12 +137,13 @@ INTERNAL void vterm_push_output_sprintf(VTerm *vt, const char *format, ...)
|
|||||||
|
|
||||||
INTERNAL void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...)
|
INTERNAL void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
if(ctrl >= 0x80 && !vt->mode.ctrl8bit)
|
if(ctrl >= 0x80 && !vt->mode.ctrl8bit)
|
||||||
vterm_push_output_sprintf(vt, "\e%c", ctrl - 0x40);
|
vterm_push_output_sprintf(vt, "\e%c", ctrl - 0x40);
|
||||||
else
|
else
|
||||||
vterm_push_output_sprintf(vt, "%c", ctrl);
|
vterm_push_output_sprintf(vt, "%c", ctrl);
|
||||||
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vterm_push_output_vsprintf(vt, fmt, args);
|
vterm_push_output_vsprintf(vt, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
@@ -150,12 +151,13 @@ INTERNAL void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, cons
|
|||||||
|
|
||||||
INTERNAL void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...)
|
INTERNAL void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
if(!vt->mode.ctrl8bit)
|
if(!vt->mode.ctrl8bit)
|
||||||
vterm_push_output_sprintf(vt, "\e%c", C1_DCS - 0x40);
|
vterm_push_output_sprintf(vt, "\e%c", C1_DCS - 0x40);
|
||||||
else
|
else
|
||||||
vterm_push_output_sprintf(vt, "%c", C1_DCS);
|
vterm_push_output_sprintf(vt, "%c", C1_DCS);
|
||||||
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vterm_push_output_vsprintf(vt, fmt, args);
|
vterm_push_output_vsprintf(vt, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
@@ -308,6 +310,8 @@ void vterm_copy_cells(VTermRect dest,
|
|||||||
int init_row, test_row, init_col, test_col;
|
int init_row, test_row, init_col, test_col;
|
||||||
int inc_row, inc_col;
|
int inc_row, inc_col;
|
||||||
|
|
||||||
|
VTermPos pos;
|
||||||
|
|
||||||
if(downward < 0) {
|
if(downward < 0) {
|
||||||
init_row = dest.end_row - 1;
|
init_row = dest.end_row - 1;
|
||||||
test_row = dest.start_row - 1;
|
test_row = dest.start_row - 1;
|
||||||
@@ -330,7 +334,6 @@ void vterm_copy_cells(VTermRect dest,
|
|||||||
inc_col = +1;
|
inc_col = +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VTermPos pos;
|
|
||||||
for(pos.row = init_row; pos.row != test_row; pos.row += inc_row)
|
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) {
|
for(pos.col = init_col; pos.col != test_col; pos.col += inc_col) {
|
||||||
VTermPos srcpos = { pos.row + downward, pos.col + rightward };
|
VTermPos srcpos = { pos.row + downward, pos.col + rightward };
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__) && __GNUC__ > 2
|
||||||
# define INTERNAL __attribute__((visibility("internal")))
|
# define INTERNAL __attribute__((visibility("internal")))
|
||||||
#else
|
#else
|
||||||
# define INTERNAL
|
# define INTERNAL
|
||||||
|
|||||||
Reference in New Issue
Block a user