GUAC-717: Set continuation character for wide chars as necessary.

This commit is contained in:
Michael Jumper 2014-06-04 13:49:35 -07:00
parent 91f1148e8f
commit a8ef6f5c40
3 changed files with 56 additions and 16 deletions

View File

@ -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, void guac_terminal_buffer_set_columns(guac_terminal_buffer* buffer, int row,
int start_column, int end_column, guac_terminal_char* character) { int start_column, int end_column, guac_terminal_char* character) {
int i; int i, j;
guac_terminal_char* current; 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 */ /* Get and expand row */
guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(buffer, row, end_column+1); guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(buffer, row, end_column+1);
/* Set values */ /* Set values */
current = &(buffer_row->characters[start_column]); current = &(buffer_row->characters[start_column]);
for (i=start_column; i<=end_column; i++) for (i=start_column; i<=end_column; i++) {
*(current++) = *character; *(current++) = *character;
/* Store any required continuation characters */
for (j=1; j<character->width; j++)
*(current++) = continuation_char;
}
/* Update length depending on row written */ /* Update length depending on row written */
if (character->value != 0 && row >= buffer->length) if (character->value != 0 && row >= buffer->length)
buffer->length = row+1; buffer->length = row+1;

View File

@ -557,14 +557,15 @@ void guac_terminal_display_set_columns(guac_terminal_display* display, int row,
current = &(display->operations[row * display->width + start_column]); current = &(display->operations[row * display->width + start_column]);
/* For each column in range */ /* 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 */ /* Set operation */
current->type = GUAC_CHAR_SET; current->type = GUAC_CHAR_SET;
current->character = *character; current->character = *character;
/* Next column */ /* Next character */
current++; current += character->width;
} }
/* If selection visible and committed, clear if update touches selection */ /* If selection visible and committed, clear if update touches selection */

View File

@ -39,6 +39,7 @@
#include <string.h> #include <string.h>
#include <sys/select.h> #include <sys/select.h>
#include <unistd.h> #include <unistd.h>
#include <wchar.h>
#include <cairo/cairo.h> #include <cairo/cairo.h>
#include <guacamole/client.h> #include <guacamole/client.h>
@ -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 guac_terminal_set(guac_terminal* term, int row, int col, int codepoint) {
int width;
/* Build character with current attributes */ /* Build character with current attributes */
guac_terminal_char guac_char; guac_terminal_char guac_char;
guac_char.value = codepoint; guac_char.value = codepoint;
guac_char.attributes = term->current_attributes; 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; return 0;
@ -448,6 +457,7 @@ int guac_terminal_clear_columns(guac_terminal* term,
guac_terminal_char blank; guac_terminal_char blank;
blank.value = 0; blank.value = 0;
blank.attributes = term->current_attributes; blank.attributes = term->current_attributes;
blank.width = 1;
/* Clear */ /* Clear */
guac_terminal_set_columns(term, guac_terminal_set_columns(term,
@ -542,9 +552,15 @@ void guac_terminal_scroll_display_down(guac_terminal* terminal,
/* Draw row */ /* Draw row */
guac_terminal_char* current = buffer_row->characters; guac_terminal_char* current = buffer_row->characters;
for (column=0; column<buffer_row->length; column++) for (column=0; column<buffer_row->length; column++) {
guac_terminal_display_set_columns(terminal->display,
dest_row, column, column, current++); /* 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 */ /* Next row */
dest_row++; dest_row++;
@ -600,9 +616,15 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal,
/* Draw row */ /* Draw row */
guac_terminal_char* current = buffer_row->characters; guac_terminal_char* current = buffer_row->characters;
for (column=0; column<buffer_row->length; column++) for (column=0; column<buffer_row->length; column++) {
guac_terminal_display_set_columns(terminal->display,
dest_row, column, column, current++); /* 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 */ /* Next row */
dest_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; int codepoint = row->characters[i].value;
/* If not null (blank), add to string */ /* 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); int bytes = guac_terminal_encode_utf8(codepoint, string);
string += bytes; string += bytes;
length += 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)); row, start_col, end_col, &(term->default_char));
/* Copy characters */ /* Copy characters */
for (col=start_col; col <= end_col && col < buffer_row->length; col++) 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])); /* 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);
}
} }