Improve cursor rendering, ensure display not affected if cursor does not move. Repurpose unused "selected" attribute for marking the cursor.

This commit is contained in:
Michael Jumper 2013-05-15 12:46:26 -07:00
parent 337d79721e
commit 9b0a210c12
5 changed files with 58 additions and 27 deletions

View File

@ -112,6 +112,16 @@ struct guac_terminal {
*/ */
int cursor_col; int cursor_col;
/**
* The row of the rendered cursor.
*/
int visible_cursor_row;
/**
* The column of the rendered cursor.
*/
int visible_cursor_col;
/** /**
* The attributes which will be applied to future characters. * The attributes which will be applied to future characters.
*/ */
@ -219,9 +229,10 @@ int guac_terminal_scroll_down(guac_terminal* term,
int start_row, int end_row, int amount); int start_row, int end_row, int amount);
/** /**
* Toggles the reverse attribute of the character at the given location. * Commits the current cursor location, updating the visible cursor
* on the screen.
*/ */
int guac_terminal_toggle_reverse(guac_terminal* term, int row, int col); void guac_terminal_commit_cursor(guac_terminal* term);
/** /**
* Scroll down the display by the given amount, replacing the new space with * Scroll down the display by the given amount, replacing the new space with

View File

@ -79,9 +79,9 @@ typedef struct guac_terminal_attributes {
bool reverse; bool reverse;
/** /**
* Whether the associated character is selected. * Whether the associated character is highlighted by the cursor.
*/ */
bool selected; bool cursor;
/** /**
* Whether to render the character with underscore. * Whether to render the character with underscore.

View File

@ -250,7 +250,7 @@ int __guac_terminal_set_colors(guac_terminal_display* display,
int background, foreground; int background, foreground;
/* Handle reverse video */ /* Handle reverse video */
if (attributes->reverse != attributes->selected) { if (attributes->reverse != attributes->cursor) {
background = attributes->foreground; background = attributes->foreground;
foreground = attributes->background; foreground = attributes->background;
} }
@ -758,7 +758,7 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
/* Color of the rectangle to draw */ /* Color of the rectangle to draw */
int color; int color;
if (current->character.attributes.reverse != current->character.attributes.selected) if (current->character.attributes.reverse != current->character.attributes.cursor)
color = current->character.attributes.foreground; color = current->character.attributes.foreground;
else else
color = current->character.attributes.background; color = current->character.attributes.background;
@ -824,7 +824,7 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
for (rect_col=0; rect_col<rect_width; rect_col++) { for (rect_col=0; rect_col<rect_width; rect_col++) {
int joining_color; int joining_color;
if (rect_current->character.attributes.reverse) if (rect_current->character.attributes.reverse != rect_current->character.attributes.cursor)
joining_color = current->character.attributes.foreground; joining_color = current->character.attributes.foreground;
else else
joining_color = current->character.attributes.background; joining_color = current->character.attributes.background;

View File

@ -90,11 +90,6 @@ int ssh_guac_client_handle_messages(guac_client* client) {
/* Lock terminal access */ /* Lock terminal access */
pthread_mutex_lock(&(client_data->term->lock)); pthread_mutex_lock(&(client_data->term->lock));
/* Clear cursor */
guac_terminal_toggle_reverse(client_data->term,
client_data->term->cursor_row,
client_data->term->cursor_col);
/* While data available, write to terminal */ /* While data available, write to terminal */
while (channel_is_open(client_data->term_channel) while (channel_is_open(client_data->term_channel)
&& !channel_is_eof(client_data->term_channel) && !channel_is_eof(client_data->term_channel)
@ -113,10 +108,8 @@ int ssh_guac_client_handle_messages(guac_client* client) {
return 1; return 1;
} }
/* Draw cursor */ /* Update cursor */
guac_terminal_toggle_reverse(client_data->term, guac_terminal_commit_cursor(client_data->term);
client_data->term->cursor_row,
client_data->term->cursor_col);
/* Flush terminal display */ /* Flush terminal display */
guac_terminal_display_flush(client_data->term->display); guac_terminal_display_flush(client_data->term->display);

View File

@ -83,8 +83,8 @@ guac_terminal* guac_terminal_create(guac_client* client,
term->current_attributes = default_char.attributes; term->current_attributes = default_char.attributes;
term->default_char = default_char; term->default_char = default_char;
term->cursor_row = 0; term->cursor_row = term->visible_cursor_row = 0;
term->cursor_col = 0; term->cursor_col = term->visible_cursor_col = 0;
term->term_width = width / term->display->char_width; term->term_width = width / term->display->char_width;
term->term_height = height / term->display->char_height; term->term_height = height / term->display->char_height;
@ -129,21 +129,37 @@ int guac_terminal_set(guac_terminal* term, int row, int col, int codepoint) {
} }
int guac_terminal_toggle_reverse(guac_terminal* term, int row, int col) { void guac_terminal_commit_cursor(guac_terminal* term) {
guac_terminal_char* guac_char; guac_terminal_char* guac_char;
/* Get character from buffer */ guac_terminal_buffer_row* old_row;
guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(term->buffer, row, col+1); guac_terminal_buffer_row* new_row;
/* Toggle reverse */ /* If no change, done */
guac_char = &(buffer_row->characters[col]); if (term->visible_cursor_row == term->cursor_row && term->visible_cursor_col == term->cursor_col)
guac_char->attributes.reverse = !(guac_char->attributes.reverse); return;
/* Set display */ /* Get old and new rows with cursor */
guac_terminal_display_set_columns(term->display, row + term->scroll_offset, col, col, guac_char); new_row = guac_terminal_buffer_get_row(term->buffer, term->cursor_row, term->cursor_col+1);
old_row = guac_terminal_buffer_get_row(term->buffer, term->visible_cursor_row, term->visible_cursor_col+1);
return 0; /* Clear cursor */
guac_char = &(old_row->characters[term->visible_cursor_col]);
guac_char->attributes.cursor = false;
guac_terminal_display_set_columns(term->display, term->visible_cursor_row + term->scroll_offset,
term->visible_cursor_col, term->visible_cursor_col, guac_char);
/* Set cursor */
guac_char = &(new_row->characters[term->cursor_col]);
guac_char->attributes.cursor = true;
guac_terminal_display_set_columns(term->display, term->cursor_row + term->scroll_offset,
term->cursor_col, term->cursor_col, guac_char);
term->visible_cursor_row = term->cursor_row;
term->visible_cursor_col = term->cursor_col;
return;
} }
@ -506,6 +522,12 @@ void guac_terminal_copy_columns(guac_terminal* terminal, int row,
guac_terminal_buffer_copy_columns(terminal->buffer, row, guac_terminal_buffer_copy_columns(terminal->buffer, row,
start_column, end_column, offset); start_column, end_column, offset);
/* Update cursor location if within region */
if (row == terminal->visible_cursor_row &&
terminal->visible_cursor_col >= start_column &&
terminal->visible_cursor_col <= end_column)
terminal->visible_cursor_col += offset;
} }
void guac_terminal_copy_rows(guac_terminal* terminal, void guac_terminal_copy_rows(guac_terminal* terminal,
@ -517,6 +539,11 @@ void guac_terminal_copy_rows(guac_terminal* terminal,
guac_terminal_buffer_copy_rows(terminal->buffer, guac_terminal_buffer_copy_rows(terminal->buffer,
start_row, end_row, offset); start_row, end_row, offset);
/* Update cursor location if within region */
if (terminal->visible_cursor_row >= start_row &&
terminal->visible_cursor_row <= end_row)
terminal->visible_cursor_row += offset;
} }
void guac_terminal_set_columns(guac_terminal* terminal, int row, void guac_terminal_set_columns(guac_terminal* terminal, int row,