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;
/**
* 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.
*/
@ -219,9 +229,10 @@ int guac_terminal_scroll_down(guac_terminal* term,
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

View File

@ -79,9 +79,9 @@ typedef struct guac_terminal_attributes {
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.

View File

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

View File

@ -90,11 +90,6 @@ int ssh_guac_client_handle_messages(guac_client* client) {
/* Lock terminal access */
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 (channel_is_open(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;
}
/* Draw cursor */
guac_terminal_toggle_reverse(client_data->term,
client_data->term->cursor_row,
client_data->term->cursor_col);
/* Update cursor */
guac_terminal_commit_cursor(client_data->term);
/* Flush terminal 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->default_char = default_char;
term->cursor_row = 0;
term->cursor_col = 0;
term->cursor_row = term->visible_cursor_row = 0;
term->cursor_col = term->visible_cursor_col = 0;
term->term_width = width / term->display->char_width;
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;
/* Get character from buffer */
guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(term->buffer, row, col+1);
guac_terminal_buffer_row* old_row;
guac_terminal_buffer_row* new_row;
/* Toggle reverse */
guac_char = &(buffer_row->characters[col]);
guac_char->attributes.reverse = !(guac_char->attributes.reverse);
/* If no change, done */
if (term->visible_cursor_row == term->cursor_row && term->visible_cursor_col == term->cursor_col)
return;
/* Set display */
guac_terminal_display_set_columns(term->display, row + term->scroll_offset, col, col, guac_char);
/* Get old and new rows with cursor */
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,
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,
@ -517,6 +539,11 @@ void guac_terminal_copy_rows(guac_terminal* terminal,
guac_terminal_buffer_copy_rows(terminal->buffer,
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,