GUACAMOLE-610: Merge add support for changing scrollback buffer size.
This commit is contained in:
commit
911e60cf5c
56
bin/guacctl
56
bin/guacctl
@ -90,6 +90,18 @@ send_close_pipe_stream() {
|
|||||||
printf "\033]482203;\007"
|
printf "\033]482203;\007"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
## Sends the Guacamole-specific console code for resizing the scrollback
|
||||||
|
## buffer.
|
||||||
|
##
|
||||||
|
## @param ROWS
|
||||||
|
## The number of rows that the scrollback buffer should contain.
|
||||||
|
##
|
||||||
|
send_resize_scrollback() {
|
||||||
|
ROWS="$1"
|
||||||
|
printf "\033]482204;%s\007" "$ROWS"
|
||||||
|
}
|
||||||
|
|
||||||
##
|
##
|
||||||
## Prints the given error text to STDERR.
|
## Prints the given error text to STDERR.
|
||||||
##
|
##
|
||||||
@ -115,6 +127,8 @@ Usage: guacctl [OPTION] [FILE or NAME]...
|
|||||||
name.
|
name.
|
||||||
-c, --close-pipe close any existing pipe stream and redirect output
|
-c, --close-pipe close any existing pipe stream and redirect output
|
||||||
back to the terminal emulator.
|
back to the terminal emulator.
|
||||||
|
-S, --scrollback request that the scrollback buffer be limited to the
|
||||||
|
given number of rows.
|
||||||
END
|
END
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +257,39 @@ close_pipe_stream() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
## Resizes the scrollback buffer to the given number of rows.
|
||||||
|
##
|
||||||
|
## @param ...
|
||||||
|
## The number of rows that should be contained within the scrollback
|
||||||
|
## buffer, as provided to guacctl.
|
||||||
|
##
|
||||||
|
resize_scrollback() {
|
||||||
|
|
||||||
|
#
|
||||||
|
# Validate arguments
|
||||||
|
#
|
||||||
|
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
error "No row count specified."
|
||||||
|
return;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $# -gt 1 ]; then
|
||||||
|
error "Only one row count may be given."
|
||||||
|
return;
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Send code for resizing scrollback
|
||||||
|
#
|
||||||
|
|
||||||
|
ROWS="$1"
|
||||||
|
send_resize_scrollback "$ROWS"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get script name
|
# Get script name
|
||||||
#
|
#
|
||||||
@ -300,6 +347,15 @@ case "$1" in
|
|||||||
close_pipe_stream "$@"
|
close_pipe_stream "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Resize scrollback
|
||||||
|
#
|
||||||
|
|
||||||
|
"--scrollback"|"-S")
|
||||||
|
shift
|
||||||
|
resize_scrollback "$@"
|
||||||
|
;;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Show usage info if options are invalid
|
# Show usage info if options are invalid
|
||||||
#
|
#
|
||||||
|
@ -59,6 +59,7 @@ const char* GUAC_SSH_CLIENT_ARGS[] = {
|
|||||||
"server-alive-interval",
|
"server-alive-interval",
|
||||||
"backspace",
|
"backspace",
|
||||||
"terminal-type",
|
"terminal-type",
|
||||||
|
"scrollback",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -232,6 +233,11 @@ enum SSH_ARGS_IDX {
|
|||||||
*/
|
*/
|
||||||
IDX_TERMINAL_TYPE,
|
IDX_TERMINAL_TYPE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum size of the scrollback buffer in rows.
|
||||||
|
*/
|
||||||
|
IDX_SCROLLBACK,
|
||||||
|
|
||||||
SSH_ARGS_COUNT
|
SSH_ARGS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -274,6 +280,11 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user,
|
|||||||
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
|
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
|
||||||
IDX_PASSPHRASE, NULL);
|
IDX_PASSPHRASE, NULL);
|
||||||
|
|
||||||
|
/* Read maximum scrollback size */
|
||||||
|
settings->max_scrollback =
|
||||||
|
guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
|
||||||
|
IDX_SCROLLBACK, GUAC_SSH_DEFAULT_MAX_SCROLLBACK);
|
||||||
|
|
||||||
/* Read font name */
|
/* Read font name */
|
||||||
settings->font_name =
|
settings->font_name =
|
||||||
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
|
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
|
||||||
|
@ -58,6 +58,11 @@
|
|||||||
*/
|
*/
|
||||||
#define GUAC_SSH_DEFAULT_POLL_TIMEOUT 1000
|
#define GUAC_SSH_DEFAULT_POLL_TIMEOUT 1000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default maximum scrollback size in rows.
|
||||||
|
*/
|
||||||
|
#define GUAC_SSH_DEFAULT_MAX_SCROLLBACK 1000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings for the SSH connection. The values for this structure are parsed
|
* Settings for the SSH connection. The values for this structure are parsed
|
||||||
* from the arguments given during the Guacamole protocol handshake using the
|
* from the arguments given during the Guacamole protocol handshake using the
|
||||||
@ -115,6 +120,11 @@ typedef struct guac_ssh_settings {
|
|||||||
*/
|
*/
|
||||||
char* command;
|
char* command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum size of the scrollback buffer in rows.
|
||||||
|
*/
|
||||||
|
int max_scrollback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the font to use for display rendering.
|
* The name of the font to use for display rendering.
|
||||||
*/
|
*/
|
||||||
|
@ -207,7 +207,7 @@ void* ssh_client_thread(void* data) {
|
|||||||
|
|
||||||
/* Create terminal */
|
/* Create terminal */
|
||||||
ssh_client->term = guac_terminal_create(client, ssh_client->clipboard,
|
ssh_client->term = guac_terminal_create(client, ssh_client->clipboard,
|
||||||
settings->font_name, settings->font_size,
|
settings->max_scrollback, settings->font_name, settings->font_size,
|
||||||
settings->resolution, settings->width, settings->height,
|
settings->resolution, settings->width, settings->height,
|
||||||
settings->color_scheme, settings->backspace);
|
settings->color_scheme, settings->backspace);
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ const char* GUAC_TELNET_CLIENT_ARGS[] = {
|
|||||||
"read-only",
|
"read-only",
|
||||||
"backspace",
|
"backspace",
|
||||||
"terminal-type",
|
"terminal-type",
|
||||||
|
"scrollback",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -190,6 +191,11 @@ enum TELNET_ARGS_IDX {
|
|||||||
*/
|
*/
|
||||||
IDX_TERMINAL_TYPE,
|
IDX_TERMINAL_TYPE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum size of the scrollback buffer in rows.
|
||||||
|
*/
|
||||||
|
IDX_SCROLLBACK,
|
||||||
|
|
||||||
TELNET_ARGS_COUNT
|
TELNET_ARGS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -274,6 +280,11 @@ guac_telnet_settings* guac_telnet_parse_args(guac_user* user,
|
|||||||
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
|
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
|
||||||
IDX_READ_ONLY, false);
|
IDX_READ_ONLY, false);
|
||||||
|
|
||||||
|
/* Read maximum scrollback size */
|
||||||
|
settings->max_scrollback =
|
||||||
|
guac_user_parse_args_int(user, GUAC_TELNET_CLIENT_ARGS, argv,
|
||||||
|
IDX_SCROLLBACK, GUAC_TELNET_DEFAULT_MAX_SCROLLBACK);
|
||||||
|
|
||||||
/* Read font name */
|
/* Read font name */
|
||||||
settings->font_name =
|
settings->font_name =
|
||||||
guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv,
|
guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv,
|
||||||
|
@ -67,6 +67,11 @@
|
|||||||
*/
|
*/
|
||||||
#define GUAC_TELNET_DEFAULT_PASSWORD_REGEX "[Pp]assword:"
|
#define GUAC_TELNET_DEFAULT_PASSWORD_REGEX "[Pp]assword:"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default maximum scrollback size in rows.
|
||||||
|
*/
|
||||||
|
#define GUAC_TELNET_DEFAULT_MAX_SCROLLBACK 1000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings for the telnet connection. The values for this structure are parsed
|
* Settings for the telnet connection. The values for this structure are parsed
|
||||||
* from the arguments given during the Guacamole protocol handshake using the
|
* from the arguments given during the Guacamole protocol handshake using the
|
||||||
@ -117,6 +122,11 @@ typedef struct guac_telnet_settings {
|
|||||||
*/
|
*/
|
||||||
bool read_only;
|
bool read_only;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum size of the scrollback buffer in rows.
|
||||||
|
*/
|
||||||
|
int max_scrollback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the font to use for display rendering.
|
* The name of the font to use for display rendering.
|
||||||
*/
|
*/
|
||||||
|
@ -479,7 +479,7 @@ void* guac_telnet_client_thread(void* data) {
|
|||||||
/* Create terminal */
|
/* Create terminal */
|
||||||
telnet_client->term = guac_terminal_create(client,
|
telnet_client->term = guac_terminal_create(client,
|
||||||
telnet_client->clipboard,
|
telnet_client->clipboard,
|
||||||
settings->font_name, settings->font_size,
|
settings->max_scrollback, settings->font_name, settings->font_size,
|
||||||
settings->resolution, settings->width, settings->height,
|
settings->resolution, settings->width, settings->height,
|
||||||
settings->color_scheme, settings->backspace);
|
settings->color_scheme, settings->backspace);
|
||||||
|
|
||||||
|
@ -149,6 +149,46 @@ static void __guac_terminal_force_break(guac_terminal* terminal, int row, int ed
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of rows available within the terminal buffer, taking
|
||||||
|
* changes to the desired scrollback size into account. Regardless of the
|
||||||
|
* true buffer length, only the number of rows that should be made available
|
||||||
|
* will be returned.
|
||||||
|
*
|
||||||
|
* @param term
|
||||||
|
* The terminal whose effective buffer length should be retrieved.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The number of rows effectively available within the terminal buffer,
|
||||||
|
* taking changes to the desired scrollback size into account.
|
||||||
|
*/
|
||||||
|
static int guac_terminal_effective_buffer_length(guac_terminal* term) {
|
||||||
|
|
||||||
|
int scrollback = term->requested_scrollback;
|
||||||
|
|
||||||
|
/* Limit available scrollback to defined maximum */
|
||||||
|
if (scrollback > term->max_scrollback)
|
||||||
|
scrollback = term->max_scrollback;
|
||||||
|
|
||||||
|
/* There must always be at least enough scrollback to cover the visible
|
||||||
|
* terminal display */
|
||||||
|
else if (scrollback < term->term_height)
|
||||||
|
scrollback = term->term_height;
|
||||||
|
|
||||||
|
/* If the buffer contains more rows than requested, pretend it only
|
||||||
|
* contains the requested number of rows */
|
||||||
|
int effective_length = term->buffer->length;
|
||||||
|
if (effective_length > scrollback)
|
||||||
|
effective_length = scrollback;
|
||||||
|
|
||||||
|
return effective_length;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int guac_terminal_available_scroll(guac_terminal* term) {
|
||||||
|
return guac_terminal_effective_buffer_length(term) - term->term_height;
|
||||||
|
}
|
||||||
|
|
||||||
void guac_terminal_reset(guac_terminal* term) {
|
void guac_terminal_reset(guac_terminal* term) {
|
||||||
|
|
||||||
int row;
|
int row;
|
||||||
@ -171,7 +211,7 @@ void guac_terminal_reset(guac_terminal* term) {
|
|||||||
term->scroll_offset = 0;
|
term->scroll_offset = 0;
|
||||||
|
|
||||||
/* Reset scrollbar bounds */
|
/* Reset scrollbar bounds */
|
||||||
guac_terminal_scrollbar_set_bounds(term->scrollbar, term->term_height - term->buffer->length, 0);
|
guac_terminal_scrollbar_set_bounds(term->scrollbar, 0, 0);
|
||||||
guac_terminal_scrollbar_set_value(term->scrollbar, -term->scroll_offset);
|
guac_terminal_scrollbar_set_value(term->scrollbar, -term->scroll_offset);
|
||||||
|
|
||||||
/* Reset flags */
|
/* Reset flags */
|
||||||
@ -507,7 +547,7 @@ static void guac_terminal_parse_color_scheme(guac_client* client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
guac_terminal* guac_terminal_create(guac_client* client,
|
guac_terminal* guac_terminal_create(guac_client* client,
|
||||||
guac_common_clipboard* clipboard,
|
guac_common_clipboard* clipboard, int max_scrollback,
|
||||||
const char* font_name, int font_size, int dpi,
|
const char* font_name, int font_size, int dpi,
|
||||||
int width, int height, const char* color_scheme,
|
int width, int height, const char* color_scheme,
|
||||||
const int backspace) {
|
const int backspace) {
|
||||||
@ -565,8 +605,19 @@ guac_terminal* guac_terminal_create(guac_client* client,
|
|||||||
pthread_cond_init(&(term->modified_cond), NULL);
|
pthread_cond_init(&(term->modified_cond), NULL);
|
||||||
pthread_mutex_init(&(term->modified_lock), NULL);
|
pthread_mutex_init(&(term->modified_lock), NULL);
|
||||||
|
|
||||||
|
/* Maximum and requested scrollback are initially the same */
|
||||||
|
term->max_scrollback = max_scrollback;
|
||||||
|
term->requested_scrollback = max_scrollback;
|
||||||
|
|
||||||
|
/* Allocate enough space for maximum scrollback, bumping up internal
|
||||||
|
* storage as necessary to allow screen to be resized to maximum height */
|
||||||
|
int initial_scrollback = max_scrollback;
|
||||||
|
if (initial_scrollback < GUAC_TERMINAL_MAX_ROWS)
|
||||||
|
initial_scrollback = GUAC_TERMINAL_MAX_ROWS;
|
||||||
|
|
||||||
/* Init buffer */
|
/* Init buffer */
|
||||||
term->buffer = guac_terminal_buffer_alloc(1000, &default_char);
|
term->buffer = guac_terminal_buffer_alloc(initial_scrollback,
|
||||||
|
&default_char);
|
||||||
|
|
||||||
/* Init display */
|
/* Init display */
|
||||||
term->display = guac_terminal_display_alloc(client,
|
term->display = guac_terminal_display_alloc(client,
|
||||||
@ -590,13 +641,29 @@ guac_terminal* guac_terminal_create(guac_client* client,
|
|||||||
term->default_char = default_char;
|
term->default_char = default_char;
|
||||||
term->clipboard = clipboard;
|
term->clipboard = clipboard;
|
||||||
|
|
||||||
|
/* Calculate character size */
|
||||||
|
int rows = height / term->display->char_height;
|
||||||
|
int columns = available_width / term->display->char_width;
|
||||||
|
|
||||||
|
/* Keep height within predefined maximum */
|
||||||
|
if (rows > GUAC_TERMINAL_MAX_ROWS) {
|
||||||
|
rows = GUAC_TERMINAL_MAX_ROWS;
|
||||||
|
height = rows * term->display->char_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep width within predefined maximum */
|
||||||
|
if (columns > GUAC_TERMINAL_MAX_COLUMNS) {
|
||||||
|
columns = GUAC_TERMINAL_MAX_COLUMNS;
|
||||||
|
available_width = columns * term->display->char_width;
|
||||||
|
width = available_width + GUAC_TERMINAL_SCROLLBAR_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set pixel size */
|
/* Set pixel size */
|
||||||
term->width = width;
|
term->width = width;
|
||||||
term->height = height;
|
term->height = height;
|
||||||
|
|
||||||
/* Calculate character size */
|
term->term_width = columns;
|
||||||
term->term_width = available_width / term->display->char_width;
|
term->term_height = rows;
|
||||||
term->term_height = height / term->display->char_height;
|
|
||||||
|
|
||||||
/* Open STDIN pipe */
|
/* Open STDIN pipe */
|
||||||
if (pipe(term->stdin_pipe_fd)) {
|
if (pipe(term->stdin_pipe_fd)) {
|
||||||
@ -1015,7 +1082,8 @@ int guac_terminal_scroll_up(guac_terminal* term,
|
|||||||
term->buffer->length = term->buffer->available;
|
term->buffer->length = term->buffer->available;
|
||||||
|
|
||||||
/* Reset scrollbar bounds */
|
/* Reset scrollbar bounds */
|
||||||
guac_terminal_scrollbar_set_bounds(term->scrollbar, term->term_height - term->buffer->length, 0);
|
guac_terminal_scrollbar_set_bounds(term->scrollbar,
|
||||||
|
-guac_terminal_available_scroll(term), 0);
|
||||||
|
|
||||||
/* Update cursor location if within region */
|
/* Update cursor location if within region */
|
||||||
if (term->visible_cursor_row >= start_row &&
|
if (term->visible_cursor_row >= start_row &&
|
||||||
@ -1225,8 +1293,9 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal,
|
|||||||
int row, column;
|
int row, column;
|
||||||
|
|
||||||
/* Limit scroll amount by size of scrollback buffer */
|
/* Limit scroll amount by size of scrollback buffer */
|
||||||
if (terminal->scroll_offset + scroll_amount > terminal->buffer->length - terminal->term_height)
|
int available_scroll = guac_terminal_available_scroll(terminal);
|
||||||
scroll_amount = terminal->buffer->length - terminal->scroll_offset - terminal->term_height;
|
if (terminal->scroll_offset + scroll_amount > available_scroll)
|
||||||
|
scroll_amount = available_scroll - terminal->scroll_offset;
|
||||||
|
|
||||||
/* If not scrolling at all, don't bother trying */
|
/* If not scrolling at all, don't bother trying */
|
||||||
if (scroll_amount <= 0)
|
if (scroll_amount <= 0)
|
||||||
@ -1388,7 +1457,7 @@ static void __guac_terminal_resize(guac_terminal* term, int width, int height) {
|
|||||||
int shift_amount;
|
int shift_amount;
|
||||||
|
|
||||||
/* Get number of rows actually occupying terminal space */
|
/* Get number of rows actually occupying terminal space */
|
||||||
int used_height = term->buffer->length;
|
int used_height = guac_terminal_effective_buffer_length(term);
|
||||||
if (used_height > term->term_height)
|
if (used_height > term->term_height)
|
||||||
used_height = term->term_height;
|
used_height = term->term_height;
|
||||||
|
|
||||||
@ -1424,16 +1493,15 @@ static void __guac_terminal_resize(guac_terminal* term, int width, int height) {
|
|||||||
if (height > term->term_height) {
|
if (height > term->term_height) {
|
||||||
|
|
||||||
/* If undisplayed rows exist in the buffer, shift them into view */
|
/* If undisplayed rows exist in the buffer, shift them into view */
|
||||||
if (term->term_height < term->buffer->length) {
|
int available_scroll = guac_terminal_available_scroll(term);
|
||||||
|
if (available_scroll > 0) {
|
||||||
|
|
||||||
/* If the new terminal bottom reveals N rows, shift down N rows */
|
/* If the new terminal bottom reveals N rows, shift down N rows */
|
||||||
int shift_amount = height - term->term_height;
|
int shift_amount = height - term->term_height;
|
||||||
|
|
||||||
/* The maximum amount we can shift is the number of undisplayed rows */
|
/* The maximum amount we can shift is the number of undisplayed rows */
|
||||||
int max_shift = term->buffer->length - term->term_height;
|
if (shift_amount > available_scroll)
|
||||||
|
shift_amount = available_scroll;
|
||||||
if (shift_amount > max_shift)
|
|
||||||
shift_amount = max_shift;
|
|
||||||
|
|
||||||
/* Update buffer top and cursor row based on shift */
|
/* Update buffer top and cursor row based on shift */
|
||||||
term->buffer->top -= shift_amount;
|
term->buffer->top -= shift_amount;
|
||||||
@ -1508,6 +1576,19 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) {
|
|||||||
int rows = height / display->char_height;
|
int rows = height / display->char_height;
|
||||||
int columns = available_width / display->char_width;
|
int columns = available_width / display->char_width;
|
||||||
|
|
||||||
|
/* Keep height within predefined maximum */
|
||||||
|
if (rows > GUAC_TERMINAL_MAX_ROWS) {
|
||||||
|
rows = GUAC_TERMINAL_MAX_ROWS;
|
||||||
|
height = rows * display->char_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep width within predefined maximum */
|
||||||
|
if (columns > GUAC_TERMINAL_MAX_COLUMNS) {
|
||||||
|
columns = GUAC_TERMINAL_MAX_COLUMNS;
|
||||||
|
available_width = columns * display->char_width;
|
||||||
|
width = available_width + GUAC_TERMINAL_SCROLLBAR_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set pixel sizes */
|
/* Set pixel sizes */
|
||||||
terminal->width = width;
|
terminal->width = width;
|
||||||
terminal->height = height;
|
terminal->height = height;
|
||||||
@ -1515,10 +1596,6 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) {
|
|||||||
/* Resize default layer to given pixel dimensions */
|
/* Resize default layer to given pixel dimensions */
|
||||||
guac_terminal_repaint_default_layer(terminal, client->socket);
|
guac_terminal_repaint_default_layer(terminal, client->socket);
|
||||||
|
|
||||||
/* Notify scrollbar of resize */
|
|
||||||
guac_terminal_scrollbar_parent_resized(terminal->scrollbar, width, height, rows);
|
|
||||||
guac_terminal_scrollbar_set_bounds(terminal->scrollbar, rows - terminal->buffer->length, 0);
|
|
||||||
|
|
||||||
/* Resize terminal if row/column dimensions have changed */
|
/* Resize terminal if row/column dimensions have changed */
|
||||||
if (columns != terminal->term_width || rows != terminal->term_height) {
|
if (columns != terminal->term_width || rows != terminal->term_height) {
|
||||||
|
|
||||||
@ -1533,6 +1610,12 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Notify scrollbar of resize */
|
||||||
|
guac_terminal_scrollbar_parent_resized(terminal->scrollbar, width, height, rows);
|
||||||
|
guac_terminal_scrollbar_set_bounds(terminal->scrollbar,
|
||||||
|
-guac_terminal_available_scroll(terminal), 0);
|
||||||
|
|
||||||
|
|
||||||
/* Release terminal */
|
/* Release terminal */
|
||||||
guac_terminal_unlock(terminal);
|
guac_terminal_unlock(terminal);
|
||||||
|
|
||||||
|
@ -37,6 +37,17 @@
|
|||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/stream.h>
|
#include <guacamole/stream.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The absolute maximum number of rows to allow within the display.
|
||||||
|
*/
|
||||||
|
#define GUAC_TERMINAL_MAX_ROWS 1024
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The absolute maximum number of columns to allow within the display. This
|
||||||
|
* implicitly limits the number of columns allowed within the buffer.
|
||||||
|
*/
|
||||||
|
#define GUAC_TERMINAL_MAX_COLUMNS 1024
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum duration of a single frame, in milliseconds.
|
* The maximum duration of a single frame, in milliseconds.
|
||||||
*/
|
*/
|
||||||
@ -271,6 +282,26 @@ struct guac_terminal {
|
|||||||
*/
|
*/
|
||||||
int scroll_offset;
|
int scroll_offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of rows to allow within the terminal buffer. Note
|
||||||
|
* that while this value is traditionally referred to as the scrollback
|
||||||
|
* size, it actually encompasses both the display and the off-screen
|
||||||
|
* region. The terminal will ensure enough buffer space is allocated for
|
||||||
|
* the on-screen rows, even if this exceeds the defined maximum, however
|
||||||
|
* additional rows for off-screen data will only be available if the
|
||||||
|
* display is smaller than this value.
|
||||||
|
*/
|
||||||
|
int max_scrollback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of rows that the user has requested be avalable within the
|
||||||
|
* terminal buffer. This value may be adjusted by the user while the
|
||||||
|
* terminal is running through console codes, and will adjust the number
|
||||||
|
* of rows available within the terminal buffer, subject to the maximum
|
||||||
|
* defined at terminal creation and stored within max_scrollback.
|
||||||
|
*/
|
||||||
|
int requested_scrollback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of the terminal, in pixels.
|
* The width of the terminal, in pixels.
|
||||||
*/
|
*/
|
||||||
@ -507,6 +538,16 @@ struct guac_terminal {
|
|||||||
* clipboard instructions. This clipboard will not be automatically
|
* clipboard instructions. This clipboard will not be automatically
|
||||||
* freed when this terminal is freed.
|
* freed when this terminal is freed.
|
||||||
*
|
*
|
||||||
|
* @param max_scrollback
|
||||||
|
* The maximum number of rows to allow within the scrollback buffer. The
|
||||||
|
* user may still alter the size of the scrollback buffer using terminal
|
||||||
|
* codes, however the size can never exceed the maximum size given here.
|
||||||
|
* Note that this space is shared with the display, with the scrollable
|
||||||
|
* area actually only containing the given number of rows less the number
|
||||||
|
* of rows currently displayed, and sufficient buffer space will always be
|
||||||
|
* allocated to represent the display area of the terminal regardless of
|
||||||
|
* the value given here.
|
||||||
|
*
|
||||||
* @param font_name
|
* @param font_name
|
||||||
* The name of the font to use when rendering glyphs.
|
* The name of the font to use when rendering glyphs.
|
||||||
*
|
*
|
||||||
@ -539,7 +580,7 @@ struct guac_terminal {
|
|||||||
* which renders all text to the given client.
|
* which renders all text to the given client.
|
||||||
*/
|
*/
|
||||||
guac_terminal* guac_terminal_create(guac_client* client,
|
guac_terminal* guac_terminal_create(guac_client* client,
|
||||||
guac_common_clipboard* clipboard,
|
guac_common_clipboard* clipboard, int max_scrollback,
|
||||||
const char* font_name, int font_size, int dpi,
|
const char* font_name, int font_size, int dpi,
|
||||||
int width, int height, const char* color_scheme,
|
int width, int height, const char* color_scheme,
|
||||||
const int backspace);
|
const int backspace);
|
||||||
@ -1022,5 +1063,20 @@ void guac_terminal_pipe_stream_close(guac_terminal* term);
|
|||||||
int guac_terminal_create_typescript(guac_terminal* term, const char* path,
|
int guac_terminal_create_typescript(guac_terminal* term, const char* path,
|
||||||
const char* name, int create_path);
|
const char* name, int create_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of rows within the buffer of the given terminal which are
|
||||||
|
* not currently displayed on screen. Adjustments to the desired scrollback
|
||||||
|
* size are taken into account, and rows which are within the buffer but
|
||||||
|
* unavailable due to being outside the desired scrollback range are ignored.
|
||||||
|
*
|
||||||
|
* @param term
|
||||||
|
* The terminal whose off-screen row count should be determined.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The number of rows within the buffer which are not currently displayed
|
||||||
|
* on screen.
|
||||||
|
*/
|
||||||
|
int guac_terminal_available_scroll(guac_terminal* term);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -138,6 +138,24 @@ int guac_terminal_open_pipe_stream(guac_terminal* term, unsigned char c);
|
|||||||
*/
|
*/
|
||||||
int guac_terminal_close_pipe_stream(guac_terminal* term, unsigned char c);
|
int guac_terminal_close_pipe_stream(guac_terminal* term, unsigned char c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the remainder of the OSC sequence specific to the Guacamole terminal
|
||||||
|
* emulator which requests that the scrollback buffer size be set to the given
|
||||||
|
* number of rows. The desired scrollback buffer size will immediately be set,
|
||||||
|
* however the manner in which that size is applied (or whether the size is
|
||||||
|
* applied at all) depends on (1) whether the requested size exceeds the
|
||||||
|
* maximum size set when the terminal emulator was created and (2) whether the
|
||||||
|
* size does not reduce the scrollback below the number of rows required for
|
||||||
|
* the current display.
|
||||||
|
*
|
||||||
|
* @param term
|
||||||
|
* The terminal that received the given character of data.
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* The character that was received by the given terminal.
|
||||||
|
*/
|
||||||
|
int guac_terminal_set_scrollback(guac_terminal* term, unsigned char c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the remainder of an OSC sequence setting the window title. The
|
* Parses the remainder of an OSC sequence setting the window title. The
|
||||||
* window title is everything after the window title sequence begins, up to
|
* window title is everything after the window title sequence begins, up to
|
||||||
|
@ -1208,6 +1208,39 @@ int guac_terminal_close_pipe_stream(guac_terminal* term, unsigned char c) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int guac_terminal_set_scrollback(guac_terminal* term, unsigned char c) {
|
||||||
|
|
||||||
|
static char param[16];
|
||||||
|
static int length = 0;
|
||||||
|
|
||||||
|
/* Open pipe on ECMA-48 ST (String Terminator) */
|
||||||
|
if (c == 0x9C || c == 0x5C || c == 0x07) {
|
||||||
|
|
||||||
|
/* End parameter string */
|
||||||
|
param[length++] = '\0';
|
||||||
|
length = 0;
|
||||||
|
|
||||||
|
/* Assign scrollback size */
|
||||||
|
term->requested_scrollback = atoi(param);
|
||||||
|
|
||||||
|
/* Update scrollbar bounds */
|
||||||
|
guac_terminal_scrollbar_set_bounds(term->scrollbar,
|
||||||
|
-guac_terminal_available_scroll(term), 0);
|
||||||
|
|
||||||
|
/* Return to echo mode */
|
||||||
|
term->char_handler = guac_terminal_echo;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, store character within parameter */
|
||||||
|
else if (length < sizeof(param) - 1)
|
||||||
|
param[length++] = c;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int guac_terminal_window_title(guac_terminal* term, unsigned char c) {
|
int guac_terminal_window_title(guac_terminal* term, unsigned char c) {
|
||||||
|
|
||||||
static int position = 0;
|
static int position = 0;
|
||||||
@ -1346,6 +1379,10 @@ int guac_terminal_osc(guac_terminal* term, unsigned char c) {
|
|||||||
else if (operation == 482203)
|
else if (operation == 482203)
|
||||||
term->char_handler = guac_terminal_close_pipe_stream;
|
term->char_handler = guac_terminal_close_pipe_stream;
|
||||||
|
|
||||||
|
/* Set scrollback size OSC */
|
||||||
|
else if (operation == 482204)
|
||||||
|
term->char_handler = guac_terminal_set_scrollback;
|
||||||
|
|
||||||
/* Set window title OSC */
|
/* Set window title OSC */
|
||||||
else if (operation == 0 || operation == 2)
|
else if (operation == 0 || operation == 2)
|
||||||
term->char_handler = guac_terminal_window_title;
|
term->char_handler = guac_terminal_window_title;
|
||||||
|
Loading…
Reference in New Issue
Block a user