GUACAMOLE-1633: Merge add terminal support for alternate screen buffer
This commit is contained in:
commit
aa6e7ad4ea
@ -50,6 +50,11 @@
|
||||
*/
|
||||
#define GUAC_TERMINAL_OK "\x1B[0n"
|
||||
|
||||
/**
|
||||
* Alternative buffer CSI sequence.
|
||||
*/
|
||||
#define GUAC_TERMINAL_ALT_BUFFER 1049
|
||||
|
||||
/**
|
||||
* Advances the cursor to the next row, scrolling if the cursor would otherwise
|
||||
* leave the scrolling region. If the cursor is already outside the scrolling
|
||||
@ -885,6 +890,10 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
|
||||
if (flag != NULL)
|
||||
*flag = true;
|
||||
|
||||
/* Open alternate screen buffer */
|
||||
if (argv[0] == GUAC_TERMINAL_ALT_BUFFER)
|
||||
guac_terminal_switch_buffers(term, true);
|
||||
|
||||
break;
|
||||
|
||||
/* l: Reset Mode */
|
||||
@ -894,6 +903,10 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
|
||||
flag = __guac_terminal_get_flag(term, argv[0], private_mode_character);
|
||||
if (flag != NULL)
|
||||
*flag = false;
|
||||
|
||||
/* Close alternate screen buffer */
|
||||
if (argv[0] == GUAC_TERMINAL_ALT_BUFFER)
|
||||
guac_terminal_switch_buffers(term, false);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@ -482,9 +482,11 @@ guac_terminal* guac_terminal_create(guac_client* client,
|
||||
if (initial_scrollback < GUAC_TERMINAL_MAX_ROWS)
|
||||
initial_scrollback = GUAC_TERMINAL_MAX_ROWS;
|
||||
|
||||
/* Init buffer */
|
||||
/* Init current and alternate buffer */
|
||||
term->buffer = guac_terminal_buffer_alloc(initial_scrollback,
|
||||
&default_char);
|
||||
term->buffer_alt = NULL;
|
||||
term->buffer_switched = false;
|
||||
|
||||
/* Init display */
|
||||
term->display = guac_terminal_display_alloc(client,
|
||||
@ -633,8 +635,10 @@ void guac_terminal_free(guac_terminal* term) {
|
||||
/* Free display */
|
||||
guac_terminal_display_free(term->display);
|
||||
|
||||
/* Free buffer */
|
||||
/* Free buffers */
|
||||
guac_terminal_buffer_free(term->buffer);
|
||||
if (term->buffer_alt != NULL)
|
||||
guac_terminal_buffer_free(term->buffer_alt);
|
||||
|
||||
/* Free scrollbar */
|
||||
guac_terminal_scrollbar_free(term->scrollbar);
|
||||
@ -2384,3 +2388,68 @@ void guac_terminal_remove_user(guac_terminal* terminal, guac_user* user) {
|
||||
/* Remove the user from the terminal cursor */
|
||||
guac_common_cursor_remove_user(terminal->cursor, user);
|
||||
}
|
||||
|
||||
void guac_terminal_switch_buffers(guac_terminal* terminal, bool to_alt) {
|
||||
|
||||
/* Already on requested buffer */
|
||||
if (terminal->buffer_switched == to_alt)
|
||||
return;
|
||||
|
||||
/* Allocate alternate buffer */
|
||||
if (terminal->buffer_alt == NULL)
|
||||
terminal->buffer_alt = guac_terminal_buffer_alloc(
|
||||
terminal->display->height, &terminal->default_char);
|
||||
|
||||
/* Keep new buffer state */
|
||||
terminal->buffer_switched = to_alt;
|
||||
|
||||
/* Inversion of buffers pointers to switch to alternate */
|
||||
guac_terminal_buffer* temp_buffer = terminal->buffer;
|
||||
terminal->buffer = terminal->buffer_alt;
|
||||
terminal->buffer_alt = temp_buffer;
|
||||
|
||||
/* Switch to alternate buffer */
|
||||
if (to_alt) {
|
||||
|
||||
/* Backup cursor position before switching alternate buffer */
|
||||
terminal->visible_cursor_col_alt = terminal->visible_cursor_col;
|
||||
terminal->visible_cursor_row_alt = terminal->visible_cursor_row;
|
||||
terminal->cursor_col_alt = terminal->cursor_col;
|
||||
terminal->cursor_row_alt = terminal->cursor_row;
|
||||
|
||||
/* Clear screen content and selection */
|
||||
guac_terminal_reset(terminal);
|
||||
|
||||
}
|
||||
|
||||
/* Switch to normal buffer */
|
||||
else {
|
||||
|
||||
/* Restore cursor position before switching normal buffer */
|
||||
terminal->visible_cursor_col = terminal->visible_cursor_col_alt;
|
||||
terminal->visible_cursor_row = terminal->visible_cursor_row_alt;
|
||||
terminal->cursor_col = terminal->cursor_col_alt;
|
||||
terminal->cursor_row = terminal->cursor_row_alt;
|
||||
|
||||
/* Repaint and resize overall display */
|
||||
guac_terminal_repaint_default_layer(terminal, terminal->client->socket);
|
||||
__guac_terminal_redraw_rect(terminal, 0, 0,
|
||||
terminal->term_height - 1,
|
||||
terminal->term_width - 1);
|
||||
|
||||
/* Restore scrollbar state */
|
||||
guac_terminal_scrollbar_set_bounds(terminal->scrollbar,
|
||||
-guac_terminal_get_available_scroll(terminal), 0);
|
||||
|
||||
/* Clear selection */
|
||||
terminal->text_selected = false;
|
||||
terminal->selection_committed = false;
|
||||
guac_terminal_notify(terminal);
|
||||
|
||||
/* Free alternate buffer when unused */
|
||||
guac_terminal_buffer_free(terminal->buffer_alt);
|
||||
terminal->buffer_alt = NULL;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -243,6 +243,11 @@ struct guac_terminal {
|
||||
*/
|
||||
int cursor_row;
|
||||
|
||||
/**
|
||||
* Backup of cursor_row when using alternate buffer.
|
||||
*/
|
||||
int cursor_row_alt;
|
||||
|
||||
/**
|
||||
* The current column location of the cursor. Note that while most
|
||||
* terminal operations will clip the cursor location within the bounds
|
||||
@ -252,6 +257,11 @@ struct guac_terminal {
|
||||
*/
|
||||
int cursor_col;
|
||||
|
||||
/**
|
||||
* Backup of cursor_col when using alternate buffer.
|
||||
*/
|
||||
int cursor_col_alt;
|
||||
|
||||
/**
|
||||
* The desired visibility state of the cursor.
|
||||
*/
|
||||
@ -263,12 +273,22 @@ struct guac_terminal {
|
||||
*/
|
||||
int visible_cursor_row;
|
||||
|
||||
/**
|
||||
* Backup of visible_cursor_row when using alternate buffer.
|
||||
*/
|
||||
int visible_cursor_row_alt;
|
||||
|
||||
/**
|
||||
* The column of the rendered cursor.
|
||||
* Will be set to -1 if the cursor is not visible.
|
||||
*/
|
||||
int visible_cursor_col;
|
||||
|
||||
/**
|
||||
* Backup of visible_cursor_col when using alternate buffer.
|
||||
*/
|
||||
int visible_cursor_col_alt;
|
||||
|
||||
/**
|
||||
* The row of the saved cursor (ESC 7).
|
||||
*/
|
||||
@ -311,6 +331,18 @@ struct guac_terminal {
|
||||
*/
|
||||
guac_terminal_buffer* buffer;
|
||||
|
||||
/**
|
||||
* Alternate buffer.
|
||||
*/
|
||||
guac_terminal_buffer* buffer_alt;
|
||||
|
||||
/**
|
||||
* Actual state of the buffer:
|
||||
* - true if switched to alternate buffer.
|
||||
* - false if normal buffer.
|
||||
*/
|
||||
bool buffer_switched;
|
||||
|
||||
/**
|
||||
* Automatically place a tabstop every N characters. If zero, then no
|
||||
* tabstops exist automatically.
|
||||
@ -666,5 +698,18 @@ void guac_terminal_copy_rows(guac_terminal* terminal,
|
||||
*/
|
||||
void guac_terminal_flush(guac_terminal* terminal);
|
||||
|
||||
/**
|
||||
* Swith betwen normal and alternate buffer.
|
||||
*
|
||||
* @param terminal
|
||||
* Terminal on which we switch buffers.
|
||||
*
|
||||
* @param to_alt
|
||||
* Direction of buffer inversion.
|
||||
* True if normal to alternate buffer.
|
||||
* False if alternate to normal buffer.
|
||||
*/
|
||||
void guac_terminal_switch_buffers(guac_terminal* terminal, bool to_alt);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user