diff --git a/src/terminal/display.c b/src/terminal/display.c index a9d671f6..d4493252 100644 --- a/src/terminal/display.c +++ b/src/terminal/display.c @@ -202,6 +202,19 @@ int __guac_terminal_set(guac_terminal_display* display, int row, int col, int co } +/** + * Calculate the size of margins around the terminal based on DPI. + * + * @param dpi + * The resolution of the display in DPI. + * + * @return + * Calculated size of margin in pixels. + */ +static int get_margin_by_dpi(int dpi) { + return dpi * GUAC_TERMINAL_MARGINS / GUAC_TERMINAL_MM_PER_INCH; +} + guac_terminal_display* guac_terminal_display_alloc(guac_client* client, const char* font_name, int font_size, int dpi, guac_terminal_color* foreground, guac_terminal_color* background, @@ -229,6 +242,13 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client, guac_protocol_send_move(client->socket, display->select_layer, display->display_layer, 0, 0, 0); + /* Calculate margin size by DPI */ + display->margin = get_margin_by_dpi(dpi); + + /* Offset the Default Layer to make margins even on all sides */ + guac_protocol_send_move(client->socket, display->display_layer, + GUAC_DEFAULT_LAYER, display->margin, display->margin, 0); + display->default_foreground = display->glyph_foreground = *foreground; display->default_background = display->glyph_background = *background; display->default_palette = palette; @@ -447,6 +467,10 @@ void guac_terminal_display_set_columns(guac_terminal_display* display, int row, void guac_terminal_display_resize(guac_terminal_display* display, int width, int height) { + /* Resize display only if dimensions have changed */ + if (width == display->width && height == display->height) + return; + guac_terminal_operation* current; int x, y; @@ -828,6 +852,10 @@ void guac_terminal_display_dup(guac_terminal_display* display, guac_user* user, guac_protocol_send_move(socket, display->select_layer, display->display_layer, 0, 0, 0); + /* Offset the Default Layer to make margins even on all sides */ + guac_protocol_send_move(socket, display->display_layer, + GUAC_DEFAULT_LAYER, display->margin, display->margin, 0); + /* Send select layer size */ guac_protocol_send_size(socket, display->select_layer, display->char_width * display->width, @@ -1020,7 +1048,7 @@ int guac_terminal_display_set_font(guac_terminal_display* display, if (new_width != display->width || new_height != display->height) guac_terminal_display_resize(display, new_width, new_height); + return 0; -} - +} \ No newline at end of file diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 434c7d4d..02e18bca 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -335,6 +335,65 @@ guac_terminal_options* guac_terminal_options_create( return options; } +/** + * Calculate the available height and width in pixels within the terminal + * and set those values on the terminal struct. + * Then use the pixel height and width to calculate the available height and + * width in characters and store the results in the pointer arguments. + * + * @param terminal + * The terminal provides character width and height for calculations. + * This function requires outer_width, outer_height, + * display->margin, display->char_height, and display->char_width + * to be set on terminal in order to calculate available dimensions. + * + * @param columns + * Set with the available width for text of the terminal, by column count. + * + * @param rows + * Set with the available height for text of the terminal, by row count. + */ +static void calculate_and_save_available_dimensions(guac_terminal* term, + int* columns, int* rows) { + + int margin = term->display->margin; + int width = term->outer_width; + int height = term->outer_height; + int char_width = term->display->char_width; + int char_height = term->display->char_height; + + /* Calculate available display area */ + int available_width = width - GUAC_TERMINAL_SCROLLBAR_WIDTH - 2 * margin; + if (available_width < 0) + available_width = 0; + + int available_height = height - 2 * margin; + if (available_height < 0) + available_height = 0; + + /* Calculate dimensions */ + *rows = available_height / char_height; + *columns = available_width / char_width; + + /* Keep height within predefined maximum */ + if (*rows > GUAC_TERMINAL_MAX_ROWS) { + *rows = GUAC_TERMINAL_MAX_ROWS; + available_height = *rows * char_height; + height = available_height + 2 * margin; + } + + /* Keep width within predefined maximum */ + if (*columns > GUAC_TERMINAL_MAX_COLUMNS) { + *columns = GUAC_TERMINAL_MAX_COLUMNS; + available_width = *columns * char_width; + width = available_width + GUAC_TERMINAL_SCROLLBAR_WIDTH + 2 * margin; + } + + /* Set pixel size */ + term->width = width; + term->height = height; +} + guac_terminal* guac_terminal_create(guac_client* client, guac_terminal_options* options) { @@ -363,11 +422,6 @@ guac_terminal* guac_terminal_create(guac_client* client, &default_char.attributes.background, default_palette); - /* Calculate available display area */ - int available_width = width - GUAC_TERMINAL_SCROLLBAR_WIDTH; - if (available_width < 0) - available_width = 0; - guac_terminal* term = malloc(sizeof(guac_terminal)); term->started = false; term->client = client; @@ -379,10 +433,6 @@ guac_terminal* guac_terminal_create(guac_client* client, term->font_name = strdup(options->font_name); term->font_size = options->font_size; - /* Set size of available screen area */ - term->outer_width = width; - term->outer_height = height; - /* Init modified flag and conditional */ term->modified = 0; pthread_cond_init(&(term->modified_cond), NULL); @@ -425,27 +475,15 @@ guac_terminal* guac_terminal_create(guac_client* client, term->clipboard = guac_common_clipboard_alloc(); term->disable_copy = options->disable_copy; - /* Calculate character size */ - int rows = height / term->display->char_height; - int columns = available_width / term->display->char_width; + /* Set size of available screen area */ + term->outer_width = width; + term->outer_height = height; - /* 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 */ - term->width = width; - term->height = height; + /* Set available screen area on the terminal */ + int rows, columns; + calculate_and_save_available_dimensions(term, &columns, &rows); + /* Set rows and columns size */ term->term_width = columns; term->term_height = rows; @@ -476,7 +514,7 @@ guac_terminal* guac_terminal_create(guac_client* client, /* Allocate scrollbar */ term->scrollbar = guac_terminal_scrollbar_alloc(term->client, GUAC_DEFAULT_LAYER, - width, height, term->term_height); + term->outer_width, term->outer_height, term->term_height); /* Associate scrollbar with this terminal */ term->scrollbar->data = term; @@ -1303,7 +1341,7 @@ static void __guac_terminal_resize(guac_terminal* term, int width, int height) { guac_terminal_display_flush(term->display); guac_terminal_display_resize(term->display, width, height); - /* Reraw any characters on right if widening */ + /* Redraw any characters on right if widening */ if (width > term->term_width) __guac_terminal_redraw_rect(term, 0, term->term_width-1, height-1, width-1); @@ -1390,51 +1428,25 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) { terminal->outer_width = width; terminal->outer_height = height; - /* Calculate available display area */ - int available_width = width - GUAC_TERMINAL_SCROLLBAR_WIDTH; - if (available_width < 0) - available_width = 0; - - /* Calculate dimensions */ - int rows = height / display->char_height; - 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 */ - terminal->width = width; - terminal->height = height; + /* Set available screen area on the terminal */ + int rows, columns; + calculate_and_save_available_dimensions(terminal, &columns, &rows); /* Resize default layer to given pixel dimensions */ guac_terminal_repaint_default_layer(terminal, client->socket); /* Resize terminal if row/column dimensions have changed */ if (columns != terminal->term_width || rows != terminal->term_height) { - - guac_client_log(client, GUAC_LOG_DEBUG, - "Resizing terminal to %ix%i", rows, columns); - - /* Resize terminal */ + /* Resize terminal and set the columns and rows on the terminal struct */ __guac_terminal_resize(terminal, columns, rows); /* Reset scroll region */ terminal->scroll_end = rows - 1; - } /* Notify scrollbar of resize */ - guac_terminal_scrollbar_parent_resized(terminal->scrollbar, width, height, rows); + guac_terminal_scrollbar_parent_resized(terminal->scrollbar, + terminal->outer_width, terminal->outer_height, terminal->term_height); guac_terminal_scrollbar_set_bounds(terminal->scrollbar, -guac_terminal_get_available_scroll(terminal), 0); @@ -2108,4 +2120,4 @@ 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); -} +} \ No newline at end of file diff --git a/src/terminal/terminal/display.h b/src/terminal/terminal/display.h index db85b2ac..1d746211 100644 --- a/src/terminal/terminal/display.h +++ b/src/terminal/terminal/display.h @@ -44,6 +44,17 @@ */ #define GUAC_TERMINAL_MAX_CHAR_WIDTH 2 +/** + * The size of margins between the console text and the border in mm. + */ +#define GUAC_TERMINAL_MARGINS 2 + +/** + * 1 inch is 25.4 millimeters, and we can therefore use the following + * to create a mm to px formula: (mm × dpi) ÷ 25.4 = px. + */ +#define GUAC_TERMINAL_MM_PER_INCH 25.4 + /** * All available terminal operations which affect character cells. */ @@ -123,6 +134,11 @@ typedef struct guac_terminal_display { */ int height; + /** + * The size of margins between the console text and the border in pixels. + */ + int margin; + /** * The description of the font to use for rendering. */