diff --git a/bin/guacctl b/bin/guacctl index a4898304..2d6d2637 100755 --- a/bin/guacctl +++ b/bin/guacctl @@ -90,6 +90,18 @@ send_close_pipe_stream() { 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. ## @@ -115,6 +127,8 @@ Usage: guacctl [OPTION] [FILE or NAME]... name. -c, --close-pipe close any existing pipe stream and redirect output back to the terminal emulator. + -S, --scrollback request that the scrollback buffer be limited to the + given number of rows. 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 # @@ -300,6 +347,15 @@ case "$1" in close_pipe_stream "$@" ;; + # + # Resize scrollback + # + + "--scrollback"|"-S") + shift + resize_scrollback "$@" + ;; + # # Show usage info if options are invalid # diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 1c105dcf..760e128f 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -185,20 +185,7 @@ static int guac_terminal_effective_buffer_length(guac_terminal* term) { } -/** - * 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. - */ -static int guac_terminal_available_scroll(guac_terminal* term) { +int guac_terminal_available_scroll(guac_terminal* term) { return guac_terminal_effective_buffer_length(term) - term->term_height; } diff --git a/src/terminal/terminal/terminal.h b/src/terminal/terminal/terminal.h index d68405b5..bddf8e55 100644 --- a/src/terminal/terminal/terminal.h +++ b/src/terminal/terminal/terminal.h @@ -1063,5 +1063,20 @@ void guac_terminal_pipe_stream_close(guac_terminal* term); int guac_terminal_create_typescript(guac_terminal* term, const char* 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 diff --git a/src/terminal/terminal/terminal_handlers.h b/src/terminal/terminal/terminal_handlers.h index 6130d2cf..0869b19d 100644 --- a/src/terminal/terminal/terminal_handlers.h +++ b/src/terminal/terminal/terminal_handlers.h @@ -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); +/** + * 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 * window title is everything after the window title sequence begins, up to diff --git a/src/terminal/terminal_handlers.c b/src/terminal/terminal_handlers.c index a6469ace..ec258fff 100644 --- a/src/terminal/terminal_handlers.c +++ b/src/terminal/terminal_handlers.c @@ -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) { static int position = 0; @@ -1346,6 +1379,10 @@ int guac_terminal_osc(guac_terminal* term, unsigned char c) { else if (operation == 482203) 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 */ else if (operation == 0 || operation == 2) term->char_handler = guac_terminal_window_title;