GUAC-717: Clear up to character end when setting characters. Handle character overwrite as part of copy.

This commit is contained in:
Michael Jumper 2014-06-04 15:52:50 -07:00
parent 8b8b351966
commit b54e750a31
2 changed files with 89 additions and 39 deletions

View File

@ -195,12 +195,12 @@ void guac_terminal_buffer_set_columns(guac_terminal_buffer* buffer, int row,
/* Set values */
current = &(buffer_row->characters[start_column]);
for (i=start_column; i<=end_column; i++) {
for (i = start_column; i <= end_column; i += character->width) {
*(current++) = *character;
/* Store any required continuation characters */
for (j=1; j<character->width; j++)
for (j=1; j < character->width; j++)
*(current++) = continuation_char;
}

View File

@ -48,6 +48,88 @@
#include <guacamole/socket.h>
#include <pango/pangocairo.h>
/**
* Sets the given range of columns to the given character.
*/
static void __guac_terminal_set_columns(guac_terminal* terminal, int row,
int start_column, int end_column, guac_terminal_char* character) {
guac_terminal_display_set_columns(terminal->display, row + terminal->scroll_offset,
start_column, end_column, character);
guac_terminal_buffer_set_columns(terminal->buffer, row,
start_column, end_column, character);
}
/**
* Declares that the given range of columns within the given row is about to be
* overwritten, and should be updated as necessary.
*/
static void __guac_terminal_overwrite_columns(guac_terminal* terminal, int row, int start_column, int end_column) {
guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(terminal->buffer, row, 0);
/* Clear out initial character */
if (start_column > 0) {
int aligned_start_column = start_column;
guac_terminal_char* start_char = &(buffer_row->characters[aligned_start_column]);
/* Determine nearest aligned boundary */
while (aligned_start_column > 0 && start_char->value == GUAC_CHAR_CONTINUATION) {
start_char--;
aligned_start_column--;
}
/* Clear up to character start */
if (aligned_start_column != start_column) {
guac_terminal_char cleared_char;
cleared_char.value = ' ';
cleared_char.attributes = start_char->attributes;
cleared_char.width = 1;
__guac_terminal_set_columns(terminal, row, aligned_start_column, start_column-1, &cleared_char);
}
}
/* Clear out final character */
if (end_column >= 0 && end_column < buffer_row->length) {
int aligned_end_column = end_column;
guac_terminal_char* end_char = &(buffer_row->characters[aligned_end_column]);
/* If we're lucky enough to end on the beginning of a character, just use its defined width */
if (end_char->value != GUAC_CHAR_CONTINUATION)
aligned_end_column += end_char->width - 1;
/* Otherwise, search for nearest aligned boundary */
else {
while (aligned_end_column+1 < buffer_row->length && (end_char+1)->value == GUAC_CHAR_CONTINUATION) {
end_char++;
aligned_end_column++;
}
}
/* Clear up to true character end */
if (aligned_end_column != end_column) {
guac_terminal_char cleared_char;
cleared_char.value = ' ';
cleared_char.attributes = end_char->attributes;
cleared_char.width = 1;
__guac_terminal_set_columns(terminal, row, end_column+1, aligned_end_column, &cleared_char);
}
}
}
void guac_terminal_reset(guac_terminal* term) {
int row;
@ -763,6 +845,8 @@ void guac_terminal_select_end(guac_terminal* terminal, char* string) {
void guac_terminal_copy_columns(guac_terminal* terminal, int row,
int start_column, int end_column, int offset) {
__guac_terminal_overwrite_columns(terminal, row, start_column + offset, end_column + offset);
guac_terminal_display_copy_columns(terminal->display, row + terminal->scroll_offset,
start_column, end_column, offset);
@ -796,39 +880,8 @@ void guac_terminal_copy_rows(guac_terminal* terminal,
void guac_terminal_set_columns(guac_terminal* terminal, int row,
int start_column, int end_column, guac_terminal_char* character) {
guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(terminal->buffer, row, end_column+1);
/* Reset initial character, if starting on non-char boundary */
if (start_column > 0) {
int aligned_start_column = start_column;
guac_terminal_char* start_char = &(buffer_row->characters[aligned_start_column]);
/* Determine nearest aligned boundary */
while (aligned_start_column > 0 && start_char->value == GUAC_CHAR_CONTINUATION) {
start_char--;
aligned_start_column--;
}
/* Clear up to character start */
if (aligned_start_column != start_column) {
guac_terminal_char cleared_char;
cleared_char.value = ' ';
cleared_char.attributes = start_char->attributes;
cleared_char.width = 1;
guac_terminal_set_columns(terminal, row, aligned_start_column, start_column-1, &cleared_char);
}
}
guac_terminal_display_set_columns(terminal->display, row + terminal->scroll_offset,
start_column, end_column, character);
guac_terminal_buffer_set_columns(terminal->buffer, row,
start_column, end_column, character);
__guac_terminal_overwrite_columns(terminal, row, start_column, end_column);
__guac_terminal_set_columns(terminal, row, start_column, end_column, character);
/* If visible cursor in current row, preserve state */
if (row == terminal->visible_cursor_row
@ -839,10 +892,7 @@ void guac_terminal_set_columns(guac_terminal* terminal, int row,
guac_terminal_char cursor_character = *character;
cursor_character.attributes.cursor = true;
guac_terminal_display_set_columns(terminal->display, row + terminal->scroll_offset,
terminal->visible_cursor_col, terminal->visible_cursor_col, &cursor_character);
guac_terminal_buffer_set_columns(terminal->buffer, row,
__guac_terminal_set_columns(terminal, row,
terminal->visible_cursor_col, terminal->visible_cursor_col, &cursor_character);
}