GUAC-717: Set continuation character for wide chars as necessary.
This commit is contained in:
parent
91f1148e8f
commit
a8ef6f5c40
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user