diff --git a/src/terminal/buffer.c b/src/terminal/buffer.c index 7e886be4..98bd029c 100644 --- a/src/terminal/buffer.c +++ b/src/terminal/buffer.c @@ -182,17 +182,29 @@ void guac_terminal_buffer_copy_rows(guac_terminal_buffer* buffer, void guac_terminal_buffer_set_columns(guac_terminal_buffer* buffer, int row, int start_column, int end_column, guac_terminal_char* character) { - int i; + int i, j; guac_terminal_char* current; + /* Build continuation char (for multicolumn characters) */ + guac_terminal_char continuation_char; + continuation_char.value = GUAC_CHAR_CONTINUATION; + continuation_char.attributes = character->attributes; + /* Get and expand row */ guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(buffer, row, end_column+1); /* Set values */ current = &(buffer_row->characters[start_column]); - for (i=start_column; i<=end_column; i++) + for (i=start_column; i<=end_column; i++) { + *(current++) = *character; + /* Store any required continuation characters */ + for (j=1; jwidth; j++) + *(current++) = continuation_char; + + } + /* Update length depending on row written */ if (character->value != 0 && row >= buffer->length) buffer->length = row+1; diff --git a/src/terminal/display.c b/src/terminal/display.c index df3ecebf..8aa7534c 100644 --- a/src/terminal/display.c +++ b/src/terminal/display.c @@ -557,14 +557,15 @@ void guac_terminal_display_set_columns(guac_terminal_display* display, int row, current = &(display->operations[row * display->width + start_column]); /* For each column in range */ - for (i=start_column; i<=end_column; i++) { + for (i = start_column; i <= end_column; i += character->width) { /* Set operation */ current->type = GUAC_CHAR_SET; current->character = *character; - /* Next column */ - current++; + /* Next character */ + current += character->width; + } /* If selection visible and committed, clear if update touches selection */ diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 46b3efc2..eddec52e 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -335,12 +336,20 @@ void guac_terminal_prompt(guac_terminal* terminal, const char* title, char* str, int guac_terminal_set(guac_terminal* term, int row, int col, int codepoint) { + int width; + /* Build character with current attributes */ guac_terminal_char guac_char; guac_char.value = codepoint; guac_char.attributes = term->current_attributes; - guac_terminal_set_columns(term, row, col, col, &guac_char); + width = wcwidth(codepoint); + if (width < 0) + width = 1; + + guac_char.width = width; + + guac_terminal_set_columns(term, row, col, col + width - 1, &guac_char); return 0; @@ -448,6 +457,7 @@ int guac_terminal_clear_columns(guac_terminal* term, guac_terminal_char blank; blank.value = 0; blank.attributes = term->current_attributes; + blank.width = 1; /* Clear */ guac_terminal_set_columns(term, @@ -542,9 +552,15 @@ void guac_terminal_scroll_display_down(guac_terminal* terminal, /* Draw row */ guac_terminal_char* current = buffer_row->characters; - for (column=0; columnlength; column++) - guac_terminal_display_set_columns(terminal->display, - dest_row, column, column, current++); + for (column=0; columnlength; column++) { + + /* Only draw if not blank */ + if (guac_terminal_has_glyph(current->value)) + guac_terminal_display_set_columns(terminal->display, dest_row, column, column, current); + + current++; + + } /* Next row */ dest_row++; @@ -600,9 +616,15 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal, /* Draw row */ guac_terminal_char* current = buffer_row->characters; - for (column=0; columnlength; column++) - guac_terminal_display_set_columns(terminal->display, - dest_row, column, column, current++); + for (column=0; columnlength; column++) { + + /* Only draw if not blank */ + if (guac_terminal_has_glyph(current->value)) + guac_terminal_display_set_columns(terminal->display, dest_row, column, column, current); + + current++; + + } /* Next row */ dest_row++; @@ -660,7 +682,7 @@ int __guac_terminal_buffer_string(guac_terminal_buffer_row* row, int start, int int codepoint = row->characters[i].value; /* If not null (blank), add to string */ - if (codepoint != 0) { + if (codepoint != 0 && codepoint != GUAC_CHAR_CONTINUATION) { int bytes = guac_terminal_encode_utf8(codepoint, string); string += bytes; length += bytes; @@ -814,9 +836,14 @@ static void __guac_terminal_redraw_rect(guac_terminal* term, int start_row, int row, start_col, end_col, &(term->default_char)); /* Copy characters */ - for (col=start_col; col <= end_col && col < buffer_row->length; col++) - guac_terminal_display_set_columns(term->display, row, col, col, - &(buffer_row->characters[col])); + for (col=start_col; col <= end_col && col < buffer_row->length; col++) { + + /* Only redraw if not blank */ + guac_terminal_char* c = &(buffer_row->characters[col]); + if (guac_terminal_has_glyph(c->value)) + guac_terminal_display_set_columns(term->display, row, col, col, c); + + } }