diff --git a/src/terminal/scrollbar.c b/src/terminal/scrollbar.c index 18cf9958..f75f9d43 100644 --- a/src/terminal/scrollbar.c +++ b/src/terminal/scrollbar.c @@ -25,17 +25,52 @@ #include #include +#include +#include #include guac_terminal_scrollbar* guac_terminal_scrollbar_alloc(guac_client* client, - guac_layer* parent, int parent_width, int parent_height) { - /* STUB */ - return NULL; + const guac_layer* parent, int parent_width, int parent_height) { + + /* Allocate scrollbar */ + guac_terminal_scrollbar* scrollbar = + malloc(sizeof(guac_terminal_scrollbar)); + + /* Associate client */ + scrollbar->client = client; + + /* Init default min/max and value */ + scrollbar->min = 0; + scrollbar->max = 0; + scrollbar->value = 0; + + /* Init parent data */ + scrollbar->parent = parent; + scrollbar->parent_width = 0; + scrollbar->parent_height = 0; + + /* Allocate and init layers */ + scrollbar->container = guac_client_alloc_layer(client); + scrollbar->box = guac_client_alloc_layer(client); + + /* Reposition and resize to fit parent */ + guac_terminal_scrollbar_parent_resized(scrollbar, + parent_width, parent_height); + + return scrollbar; + } void guac_terminal_scrollbar_free(guac_terminal_scrollbar* scrollbar) { - /* STUB */ + + /* Free layers */ + guac_client_free_layer(scrollbar->client, scrollbar->box); + guac_client_free_layer(scrollbar->client, scrollbar->container); + + /* Free scrollbar */ + free(scrollbar); + } void guac_terminal_scrollbar_set_bounds(guac_terminal_scrollbar* scrollbar, @@ -50,6 +85,46 @@ void guac_terminal_scrollbar_set_value(guac_terminal_scrollbar* scrollbar, void guac_terminal_scrollbar_parent_resized(guac_terminal_scrollbar* scrollbar, int parent_width, int parent_height) { - /* STUB */ + + guac_socket* socket = scrollbar->client->socket; + + /* Calculate container position and dimensions */ + int container_x = parent_width - GUAC_TERMINAL_SCROLLBAR_WIDTH; + int container_y = 0; + int container_width = GUAC_TERMINAL_SCROLLBAR_WIDTH; + int container_height = parent_height; + + /* Calculate box position and dimensions */ + int box_x = GUAC_TERMINAL_SCROLLBAR_PADDING; + int box_y = GUAC_TERMINAL_SCROLLBAR_PADDING; + int box_width = GUAC_TERMINAL_SCROLLBAR_WIDTH - GUAC_TERMINAL_SCROLLBAR_PADDING*2; + int box_height = 64; /* STUB */ + + /* Reposition container relative to parent dimensions */ + guac_protocol_send_move(socket, + scrollbar->container, scrollbar->parent, + container_x, container_y, 0); + + /* Resize to fit within parent */ + guac_protocol_send_size(socket, scrollbar->container, + container_width, container_height); + + /* Reposition box relative to container and current value */ + guac_protocol_send_move(socket, + scrollbar->box, scrollbar->container, + box_x, box_y, 0); + + /* Resize box relative to scrollable area */ + guac_protocol_send_size(socket, scrollbar->box, + box_width, box_height); + + /* Fill box with solid color */ + guac_protocol_send_rect(socket, scrollbar->box, 0, 0, box_width, box_height); + guac_protocol_send_cfill(socket, GUAC_COMP_SRC, scrollbar->box, 0xFF, 0xFF, 0xFF, 0x80); + + /* Assign new dimensions */ + scrollbar->parent_width = parent_width; + scrollbar->parent_height = parent_height; + } diff --git a/src/terminal/scrollbar.h b/src/terminal/scrollbar.h index f649a908..614a93be 100644 --- a/src/terminal/scrollbar.h +++ b/src/terminal/scrollbar.h @@ -79,7 +79,7 @@ typedef struct guac_terminal_scrollbar { * The movable box within the scrollbar, representing the current scroll * value. */ - guac_layer* layer; + guac_layer* box; /** * The minimum scroll value. @@ -123,7 +123,7 @@ typedef struct guac_terminal_scrollbar { * A newly allocated scrollbar. */ guac_terminal_scrollbar* guac_terminal_scrollbar_alloc(guac_client* client, - guac_layer* parent, int parent_width, int parent_height); + const guac_layer* parent, int parent_width, int parent_height); /** * Frees the given scrollbar. diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 0fbeca79..a1a9ebfd 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -29,6 +29,7 @@ #include "display.h" #include "ibar.h" #include "guac_clipboard.h" +#include "scrollbar.h" #include "terminal.h" #include "terminal_handlers.h" #include "types.h" @@ -159,7 +160,7 @@ void guac_terminal_reset(guac_terminal* term) { term->cursor_row = term->visible_cursor_row = term->saved_cursor_row = 0; term->cursor_col = term->visible_cursor_col = term->saved_cursor_col = 0; - /* Clear scrollback, buffer, and scoll region */ + /* Clear scrollback, buffer, and scroll region */ term->buffer->top = 0; term->buffer->length = 0; term->scroll_start = 0; @@ -268,6 +269,10 @@ guac_terminal* guac_terminal_create(guac_client* client, /* Allocate clipboard */ term->clipboard = guac_common_clipboard_alloc(GUAC_TERMINAL_CLIPBOARD_MAX_LENGTH); + /* Allocate scrollbar */ + term->scrollbar = guac_terminal_scrollbar_alloc(term->client, + GUAC_DEFAULT_LAYER, width, height); + return term; } @@ -291,6 +296,9 @@ void guac_terminal_free(guac_terminal* term) { /* Free clipboard */ guac_common_clipboard_free(term->clipboard); + /* Free scrollbar */ + guac_terminal_scrollbar_free(term->scrollbar); + /* Free cursors */ guac_terminal_cursor_free(term->client, term->ibar_cursor); guac_terminal_cursor_free(term->client, term->blank_cursor); @@ -1130,6 +1138,9 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) { /* Resize default layer to given pixel dimensions */ guac_protocol_send_size(socket, GUAC_DEFAULT_LAYER, width, height); + /* Notify scrollbar of resize */ + guac_terminal_scrollbar_parent_resized(terminal->scrollbar, width, height); + /* Resize terminal if row/column dimensions have changed */ if (columns != terminal->term_width || rows != terminal->term_height) { diff --git a/src/terminal/terminal.h b/src/terminal/terminal.h index 0c530988..5f6e7ec2 100644 --- a/src/terminal/terminal.h +++ b/src/terminal/terminal.h @@ -30,6 +30,7 @@ #include "cursor.h" #include "display.h" #include "guac_clipboard.h" +#include "scrollbar.h" #include "types.h" #include @@ -117,6 +118,11 @@ struct guac_terminal { */ int stdin_pipe_fd[2]; + /** + * Graphical representation of the current scroll state. + */ + guac_terminal_scrollbar* scrollbar; + /** * The relative offset of the display. A positive value indicates that * many rows have been scrolled into view, zero indicates that no