You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/11/11 19:04:44 UTC

[1/3] guacamole-server git commit: GUACAMOLE-630: Allow SSH/telnet font family and size to be updated.

Repository: guacamole-server
Updated Branches:
  refs/heads/master d2cb7a9ce -> 381c5d1a7


GUACAMOLE-630: Allow SSH/telnet font family and size to be updated.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/5683be0e
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/5683be0e
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/5683be0e

Branch: refs/heads/master
Commit: 5683be0ea3eb241c882e605a1990c898acf3af4c
Parents: 9e28de7
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Oct 7 23:49:12 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Sat Nov 10 14:22:23 2018 -0800

----------------------------------------------------------------------
 src/protocols/ssh/argv.c    | 112 ++++++++++++++++++++++++++++++++-------
 src/protocols/telnet/argv.c | 104 +++++++++++++++++++++++++++++-------
 2 files changed, 178 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5683be0e/src/protocols/ssh/argv.c
----------------------------------------------------------------------
diff --git a/src/protocols/ssh/argv.c b/src/protocols/ssh/argv.c
index 00a2cbb..8db2b24 100644
--- a/src/protocols/ssh/argv.c
+++ b/src/protocols/ssh/argv.c
@@ -26,16 +26,45 @@
 #include <guacamole/socket.h>
 #include <guacamole/user.h>
 
+#include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
 
 /**
+ * All SSH connection settings which may be updated by unprivileged users
+ * through "argv" streams.
+ */
+typedef enum guac_ssh_argv_setting {
+
+    /**
+     * The color scheme of the terminal.
+     */
+    GUAC_SSH_ARGV_SETTING_COLOR_SCHEME,
+
+    /**
+     * The name of the font family used by the terminal.
+     */
+    GUAC_SSH_ARGV_SETTING_FONT_NAME,
+
+    /**
+     * The size of the font used by the terminal, in points.
+     */
+    GUAC_SSH_ARGV_SETTING_FONT_SIZE
+
+} guac_ssh_argv_setting;
+
+/**
  * The value or current status of a connection parameter received over an
  * "argv" stream.
  */
 typedef struct guac_ssh_argv {
 
     /**
+     * The specific setting being updated.
+     */
+    guac_ssh_argv_setting setting;
+
+    /**
      * Buffer space for containing the received argument value.
      */
     char buffer[GUAC_SSH_ARGV_MAX_LENGTH];
@@ -81,16 +110,51 @@ static int guac_ssh_argv_blob_handler(guac_user* user,
 static int guac_ssh_argv_end_handler(guac_user* user,
         guac_stream* stream) {
 
+    int size;
+
     guac_client* client = user->client;
-    guac_ssh_client* telnet_client = (guac_ssh_client*) client->data;
-    guac_terminal* terminal = telnet_client->term;
+    guac_ssh_client* ssh_client = (guac_ssh_client*) client->data;
+    guac_terminal* terminal = ssh_client->term;
 
     /* Append null terminator to value */
     guac_ssh_argv* argv = (guac_ssh_argv*) stream->data;
     argv->buffer[argv->length] = '\0';
 
-    /* Update color scheme */
-    guac_terminal_apply_color_scheme(terminal, argv->buffer);
+    /* Apply changes to chosen setting */
+    switch (argv->setting) {
+
+        /* Update color scheme */
+        case GUAC_SSH_ARGV_SETTING_COLOR_SCHEME:
+            guac_terminal_apply_color_scheme(terminal, argv->buffer);
+            break;
+
+        /* Update font name */
+        case GUAC_SSH_ARGV_SETTING_FONT_NAME:
+            guac_terminal_apply_font(terminal, argv->buffer, -1, 0);
+            break;
+
+        /* Update font size */
+        case GUAC_SSH_ARGV_SETTING_FONT_SIZE:
+
+            /* Update only if font size is sane */
+            size = atoi(argv->buffer);
+            if (size > 0) {
+                guac_terminal_apply_font(terminal, NULL, size,
+                        ssh_client->settings->resolution);
+            }
+
+            break;
+
+    }
+
+    /* Update SSH pty size if connected */
+    if (ssh_client->term_channel != NULL) {
+        pthread_mutex_lock(&(ssh_client->term_channel_lock));
+        libssh2_channel_request_pty_size(ssh_client->term_channel,
+                terminal->term_width, terminal->term_height);
+        pthread_mutex_unlock(&(ssh_client->term_channel_lock));
+    }
+
     free(argv);
     return 0;
 
@@ -99,28 +163,36 @@ static int guac_ssh_argv_end_handler(guac_user* user,
 int guac_ssh_argv_handler(guac_user* user, guac_stream* stream,
         char* mimetype, char* name) {
 
-    /* Allow users to update the color scheme */
-    if (strcmp(name, "color-scheme") == 0) {
+    guac_ssh_argv_setting setting;
 
-        guac_ssh_argv* argv = malloc(sizeof(guac_ssh_argv));
-        argv->length = 0;
+    /* Allow users to update the color scheme and font details */
+    if (strcmp(name, "color-scheme") == 0)
+        setting = GUAC_SSH_ARGV_SETTING_COLOR_SCHEME;
+    else if (strcmp(name, "font-name") == 0)
+        setting = GUAC_SSH_ARGV_SETTING_FONT_NAME;
+    else if (strcmp(name, "font-size") == 0)
+        setting = GUAC_SSH_ARGV_SETTING_FONT_SIZE;
 
-        /* Prepare stream to receive argument value */
-        stream->blob_handler = guac_ssh_argv_blob_handler;
-        stream->end_handler = guac_ssh_argv_end_handler;
-        stream->data = argv;
-
-        /* Signal stream is ready */
-        guac_protocol_send_ack(user->socket, stream, "Ready for color "
-                "scheme.", GUAC_PROTOCOL_STATUS_SUCCESS);
+    /* No other connection parameters may be updated */
+    else {
+        guac_protocol_send_ack(user->socket, stream, "Not allowed.",
+                GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
         guac_socket_flush(user->socket);
         return 0;
-
     }
 
-    /* No other connection parameters may be updated */
-    guac_protocol_send_ack(user->socket, stream, "Not allowed.",
-            GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
+    guac_ssh_argv* argv = malloc(sizeof(guac_ssh_argv));
+    argv->setting = setting;
+    argv->length = 0;
+
+    /* Prepare stream to receive argument value */
+    stream->blob_handler = guac_ssh_argv_blob_handler;
+    stream->end_handler = guac_ssh_argv_end_handler;
+    stream->data = argv;
+
+    /* Signal stream is ready */
+    guac_protocol_send_ack(user->socket, stream, "Ready for updated "
+            "parameter.", GUAC_PROTOCOL_STATUS_SUCCESS);
     guac_socket_flush(user->socket);
     return 0;
 

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5683be0e/src/protocols/telnet/argv.c
----------------------------------------------------------------------
diff --git a/src/protocols/telnet/argv.c b/src/protocols/telnet/argv.c
index 0735928..450c7f3 100644
--- a/src/protocols/telnet/argv.c
+++ b/src/protocols/telnet/argv.c
@@ -30,12 +30,40 @@
 #include <string.h>
 
 /**
+ * All telnet connection settings which may be updated by unprivileged users
+ * through "argv" streams.
+ */
+typedef enum guac_telnet_argv_setting {
+
+    /**
+     * The color scheme of the terminal.
+     */
+    GUAC_TELNET_ARGV_SETTING_COLOR_SCHEME,
+
+    /**
+     * The name of the font family used by the terminal.
+     */
+    GUAC_TELNET_ARGV_SETTING_FONT_NAME,
+
+    /**
+     * The size of the font used by the terminal, in points.
+     */
+    GUAC_TELNET_ARGV_SETTING_FONT_SIZE
+
+} guac_telnet_argv_setting;
+
+/**
  * The value or current status of a connection parameter received over an
  * "argv" stream.
  */
 typedef struct guac_telnet_argv {
 
     /**
+     * The specific setting being updated.
+     */
+    guac_telnet_argv_setting setting;
+
+    /**
      * Buffer space for containing the received argument value.
      */
     char buffer[GUAC_TELNET_ARGV_MAX_LENGTH];
@@ -81,6 +109,8 @@ static int guac_telnet_argv_blob_handler(guac_user* user,
 static int guac_telnet_argv_end_handler(guac_user* user,
         guac_stream* stream) {
 
+    int size;
+
     guac_client* client = user->client;
     guac_telnet_client* telnet_client = (guac_telnet_client*) client->data;
     guac_terminal* terminal = telnet_client->term;
@@ -89,8 +119,38 @@ static int guac_telnet_argv_end_handler(guac_user* user,
     guac_telnet_argv* argv = (guac_telnet_argv*) stream->data;
     argv->buffer[argv->length] = '\0';
 
-    /* Update color scheme */
-    guac_terminal_apply_color_scheme(terminal, argv->buffer);
+    /* Apply changes to chosen setting */
+    switch (argv->setting) {
+
+        /* Update color scheme */
+        case GUAC_TELNET_ARGV_SETTING_COLOR_SCHEME:
+            guac_terminal_apply_color_scheme(terminal, argv->buffer);
+            break;
+
+        /* Update font name */
+        case GUAC_TELNET_ARGV_SETTING_FONT_NAME:
+            guac_terminal_apply_font(terminal, argv->buffer, -1, 0);
+            break;
+
+        /* Update font size */
+        case GUAC_TELNET_ARGV_SETTING_FONT_SIZE:
+
+            /* Update only if font size is sane */
+            size = atoi(argv->buffer);
+            if (size > 0) {
+                guac_terminal_apply_font(terminal, NULL, size,
+                        telnet_client->settings->resolution);
+            }
+
+            break;
+
+    }
+
+    /* Update terminal window size if connected */
+    if (telnet_client->telnet != NULL && telnet_client->naws_enabled)
+        guac_telnet_send_naws(telnet_client->telnet, terminal->term_width,
+                terminal->term_height);
+
     free(argv);
     return 0;
 
@@ -99,28 +159,36 @@ static int guac_telnet_argv_end_handler(guac_user* user,
 int guac_telnet_argv_handler(guac_user* user, guac_stream* stream,
         char* mimetype, char* name) {
 
-    /* Allow users to update the color scheme */
-    if (strcmp(name, "color-scheme") == 0) {
+    guac_telnet_argv_setting setting;
 
-        guac_telnet_argv* argv = malloc(sizeof(guac_telnet_argv));
-        argv->length = 0;
+    /* Allow users to update the color scheme and font details */
+    if (strcmp(name, "color-scheme") == 0)
+        setting = GUAC_TELNET_ARGV_SETTING_COLOR_SCHEME;
+    else if (strcmp(name, "font-name") == 0)
+        setting = GUAC_TELNET_ARGV_SETTING_FONT_NAME;
+    else if (strcmp(name, "font-size") == 0)
+        setting = GUAC_TELNET_ARGV_SETTING_FONT_SIZE;
 
-        /* Prepare stream to receive argument value */
-        stream->blob_handler = guac_telnet_argv_blob_handler;
-        stream->end_handler = guac_telnet_argv_end_handler;
-        stream->data = argv;
-
-        /* Signal stream is ready */
-        guac_protocol_send_ack(user->socket, stream, "Ready for color "
-                "scheme.", GUAC_PROTOCOL_STATUS_SUCCESS);
+    /* No other connection parameters may be updated */
+    else {
+        guac_protocol_send_ack(user->socket, stream, "Not allowed.",
+                GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
         guac_socket_flush(user->socket);
         return 0;
-
     }
 
-    /* No other connection parameters may be updated */
-    guac_protocol_send_ack(user->socket, stream, "Not allowed.",
-            GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN);
+    guac_telnet_argv* argv = malloc(sizeof(guac_telnet_argv));
+    argv->setting = setting;
+    argv->length = 0;
+
+    /* Prepare stream to receive argument value */
+    stream->blob_handler = guac_telnet_argv_blob_handler;
+    stream->end_handler = guac_telnet_argv_end_handler;
+    stream->data = argv;
+
+    /* Signal stream is ready */
+    guac_protocol_send_ack(user->socket, stream, "Ready for updated "
+            "parameter.", GUAC_PROTOCOL_STATUS_SUCCESS);
     guac_socket_flush(user->socket);
     return 0;
 


[3/3] guacamole-server git commit: GUACAMOLE-630: Merge allow font parameters of active terminal session to be changed.

Posted by vn...@apache.org.
GUACAMOLE-630: Merge allow font parameters of active terminal session to be changed.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/381c5d1a
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/381c5d1a
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/381c5d1a

Branch: refs/heads/master
Commit: 381c5d1a76637f51be4a4c190ad1cb0da8e4426d
Parents: d2cb7a9 5683be0
Author: Nick Couchman <vn...@apache.org>
Authored: Sun Nov 11 14:03:58 2018 -0500
Committer: Nick Couchman <vn...@apache.org>
Committed: Sun Nov 11 14:03:58 2018 -0500

----------------------------------------------------------------------
 src/protocols/ssh/argv.c         | 112 ++++++++++++++++++++++++------
 src/protocols/telnet/argv.c      | 104 +++++++++++++++++++++++-----
 src/terminal/display.c           | 127 ++++++++++++++++++++++++----------
 src/terminal/terminal.c          |  32 +++++++++
 src/terminal/terminal/display.h  |  30 ++++++++
 src/terminal/terminal/terminal.h |  38 ++++++++++
 6 files changed, 368 insertions(+), 75 deletions(-)
----------------------------------------------------------------------



[2/3] guacamole-server git commit: GUACAMOLE-630: Separate setting of font family/size from terminal display initialization.

Posted by vn...@apache.org.
GUACAMOLE-630: Separate setting of font family/size from terminal display initialization.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/9e28de70
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/9e28de70
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/9e28de70

Branch: refs/heads/master
Commit: 9e28de70ec43e6a260177242fa5de9347cfbd66b
Parents: 0cf2421
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Oct 7 23:38:03 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Sat Nov 10 14:22:23 2018 -0800

----------------------------------------------------------------------
 src/terminal/display.c           | 127 ++++++++++++++++++++++++----------
 src/terminal/terminal.c          |  32 +++++++++
 src/terminal/terminal/display.h  |  30 ++++++++
 src/terminal/terminal/terminal.h |  38 ++++++++++
 4 files changed, 190 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/9e28de70/src/terminal/display.c
----------------------------------------------------------------------
diff --git a/src/terminal/display.c b/src/terminal/display.c
index 1c803b4..d148b41 100644
--- a/src/terminal/display.c
+++ b/src/terminal/display.c
@@ -206,15 +206,15 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
         guac_terminal_color* foreground, guac_terminal_color* background,
         guac_terminal_color (*palette)[256]) {
 
-    PangoFontMap* font_map;
-    PangoFont* font;
-    PangoFontMetrics* metrics;
-    PangoContext* context;
-
     /* Allocate display */
     guac_terminal_display* display = malloc(sizeof(guac_terminal_display));
     display->client = client;
 
+    /* Initially no font loaded */
+    display->font_desc = NULL;
+    display->char_width = 0;
+    display->char_height = 0;
+
     /* Create default surface */
     display->display_layer = guac_client_alloc_layer(client);
     display->select_layer = guac_client_alloc_layer(client);
@@ -225,42 +225,10 @@ 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);
 
-    /* Get font */
-    display->font_desc = pango_font_description_new();
-    pango_font_description_set_family(display->font_desc, font_name);
-    pango_font_description_set_weight(display->font_desc, PANGO_WEIGHT_NORMAL);
-    pango_font_description_set_size(display->font_desc,
-            font_size * PANGO_SCALE * dpi / 96);
-
-    font_map = pango_cairo_font_map_get_default();
-    context = pango_font_map_create_context(font_map);
-
-    font = pango_font_map_load_font(font_map, context, display->font_desc);
-    if (font == NULL) {
-        guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to get font \"%s\"", font_name);
-        free(display);
-        return NULL;
-    }
-
-    metrics = pango_font_get_metrics(font, NULL);
-    if (metrics == NULL) {
-        guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
-                "Unable to get font metrics for font \"%s\"", font_name);
-        free(display);
-        return NULL;
-    }
-
     display->default_foreground = display->glyph_foreground = *foreground;
     display->default_background = display->glyph_background = *background;
     display->default_palette = palette;
 
-    /* Calculate character dimensions */
-    display->char_width =
-        pango_font_metrics_get_approximate_digit_width(metrics) / PANGO_SCALE;
-    display->char_height =
-        (pango_font_metrics_get_descent(metrics)
-            + pango_font_metrics_get_ascent(metrics)) / PANGO_SCALE;
-
     /* Initially empty */
     display->width = 0;
     display->height = 0;
@@ -269,12 +237,23 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
     /* Initially nothing selected */
     display->text_selected = false;
 
+    /* Attempt to load font */
+    if (guac_terminal_display_set_font(display, font_name, font_size, dpi)) {
+        guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+                "Unable to set initial font \"%s\"", font_name);
+        free(display);
+        return NULL;
+    }
+
     return display;
 
 }
 
 void guac_terminal_display_free(guac_terminal_display* display) {
 
+    /* Free font description */
+    pango_font_description_free(display->font_desc);
+
     /* Free default palette. */
     free(display->default_palette);
 
@@ -966,4 +945,78 @@ void guac_terminal_display_clear_select(guac_terminal_display* display) {
 
 }
 
+int guac_terminal_display_set_font(guac_terminal_display* display,
+        const char* font_name, int font_size, int dpi) {
+
+    PangoFontDescription* font_desc;
+
+    /* Build off existing font description if possible */
+    if (display->font_desc != NULL)
+        font_desc = pango_font_description_copy(display->font_desc);
+
+    /* Create new font description if there is nothing to copy */
+    else {
+        font_desc = pango_font_description_new();
+        pango_font_description_set_weight(font_desc, PANGO_WEIGHT_NORMAL);
+    }
+
+    /* Optionally update font name */
+    if (font_name != NULL)
+        pango_font_description_set_family(font_desc, font_name);
+
+    /* Optionally update size */
+    if (font_size != -1) {
+        pango_font_description_set_size(font_desc,
+                font_size * PANGO_SCALE * dpi / 96);
+    }
+
+    PangoFontMap* font_map = pango_cairo_font_map_get_default();
+    PangoContext* context = pango_font_map_create_context(font_map);
+
+    /* Load font from font map */
+    PangoFont* font = pango_font_map_load_font(font_map, context, font_desc);
+    if (font == NULL) {
+        guac_client_log(display->client, GUAC_LOG_INFO, "Unable to load "
+                "font \"%s\"", pango_font_description_get_family(font_desc));
+        pango_font_description_free(font_desc);
+        return 1;
+    }
+
+    /* Get metrics from loaded font */
+    PangoFontMetrics* metrics = pango_font_get_metrics(font, NULL);
+    if (metrics == NULL) {
+        guac_client_log(display->client, GUAC_LOG_INFO, "Unable to get font "
+                "metrics for font \"%s\"",
+                pango_font_description_get_family(font_desc));
+        pango_font_description_free(font_desc);
+        return 1;
+    }
+
+    /* Save effective size of current display */
+    int pixel_width = display->width * display->char_width;
+    int pixel_height = display->height * display->char_height;
+
+    /* Calculate character dimensions using metrics */
+    display->char_width =
+        pango_font_metrics_get_approximate_digit_width(metrics) / PANGO_SCALE;
+    display->char_height =
+        (pango_font_metrics_get_descent(metrics)
+            + pango_font_metrics_get_ascent(metrics)) / PANGO_SCALE;
+
+    /* Atomically replace old font description */
+    PangoFontDescription* old_font_desc = display->font_desc;
+    display->font_desc = font_desc;
+    pango_font_description_free(old_font_desc);
+
+    /* Recalculate dimensions which will fit within current surface */
+    int new_width = pixel_width / display->char_width;
+    int new_height = pixel_height / display->char_height;
+
+    /* Resize display if dimensions have changed */
+    if (new_width != display->width || new_height != display->height)
+        guac_terminal_display_resize(display, new_width, new_height);
+
+    return 0;
+
+}
 

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/9e28de70/src/terminal/terminal.c
----------------------------------------------------------------------
diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c
index 1984185..cf70f92 100644
--- a/src/terminal/terminal.c
+++ b/src/terminal/terminal.c
@@ -360,6 +360,10 @@ guac_terminal* guac_terminal_create(guac_client* client,
     term->upload_path_handler = NULL;
     term->file_download_handler = NULL;
 
+    /* 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);
@@ -1338,6 +1342,10 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) {
     /* Acquire exclusive access to terminal */
     guac_terminal_lock(terminal);
 
+    /* Set size of available screen area */
+    terminal->outer_width = width;
+    terminal->outer_height = height;
+
     /* Calculate available display area */
     int available_width = width - GUAC_TERMINAL_SCROLLBAR_WIDTH;
     if (available_width < 0)
@@ -1968,3 +1976,27 @@ void guac_terminal_apply_color_scheme(guac_terminal* terminal,
 
 }
 
+void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
+        int font_size, int dpi) {
+
+    guac_client* client = terminal->client;
+    guac_terminal_display* display = terminal->display;
+
+    if (guac_terminal_display_set_font(display, font_name, font_size, dpi))
+        return;
+
+    /* Resize terminal to fit available region, now that font metrics may be
+     * different */
+    guac_terminal_resize(terminal, terminal->outer_width,
+            terminal->outer_height);
+
+    /* Redraw terminal text and background */
+    guac_terminal_repaint_default_layer(terminal, client->socket);
+    __guac_terminal_redraw_rect(terminal, 0, 0,
+            terminal->term_height - 1,
+            terminal->term_width - 1);
+
+    guac_terminal_notify(terminal);
+
+}
+

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/9e28de70/src/terminal/terminal/display.h
----------------------------------------------------------------------
diff --git a/src/terminal/terminal/display.h b/src/terminal/terminal/display.h
index b127423..5377cb1 100644
--- a/src/terminal/terminal/display.h
+++ b/src/terminal/terminal/display.h
@@ -334,5 +334,35 @@ void guac_terminal_display_select(guac_terminal_display* display,
  */
 void guac_terminal_display_clear_select(guac_terminal_display* display);
 
+/**
+ * Alters the font of the terminal display. The available display area and the
+ * regular grid of character cells will be resized as necessary to compensate
+ * for any changes in font metrics.
+ *
+ * If successful, the terminal itself MUST be manually resized to take into
+ * account the new character dimensions, and MUST be manually redrawn. Failing
+ * to do so will result in graphical artifacts.
+ *
+ * @param display
+ *     The display whose font family and/or size are being changed.
+ *
+ * @param font_name
+ *     The name of the new font family, or NULL if the font family should
+ *     remain unchanged.
+ *
+ * @param font_size
+ *     The new font size, in points, or -1 if the font size should remain
+ *     unchanged.
+ *
+ * @param dpi
+ *     The resolution of the display in DPI. If the font size will not be
+ *     changed (the font size given is -1), this value is ignored.
+ *
+ * @return
+ *     Zero if the font was successfully changed, non-zero otherwise.
+ */
+int guac_terminal_display_set_font(guac_terminal_display* display,
+        const char* font_name, int font_size, int dpi);
+
 #endif
 

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/9e28de70/src/terminal/terminal/terminal.h
----------------------------------------------------------------------
diff --git a/src/terminal/terminal/terminal.h b/src/terminal/terminal/terminal.h
index 28085f6..ac1217e 100644
--- a/src/terminal/terminal/terminal.h
+++ b/src/terminal/terminal/terminal.h
@@ -278,6 +278,20 @@ struct guac_terminal {
     int requested_scrollback;
 
     /**
+     * The width of the space available to all components of the terminal, in
+     * pixels. This may include space which will not actually be used for
+     * character rendering.
+     */
+    int outer_width;
+
+    /**
+     * The height of the space available to all components of the terminal, in
+     * pixels. This may include space which will not actually be used for
+     * character rendering.
+     */
+    int outer_height;
+
+    /**
      * The width of the terminal, in pixels.
      */
     int width;
@@ -1086,5 +1100,29 @@ int guac_terminal_available_scroll(guac_terminal* term);
 void guac_terminal_apply_color_scheme(guac_terminal* terminal,
         const char* color_scheme);
 
+/**
+ * Alters the font of the terminal. The terminal will automatically be redrawn
+ * and resized as necessary. If the terminal size changes, the remote side of
+ * the terminal session must be manually informed of that change or graphical
+ * artifacts may result.
+ *
+ * @param terminal
+ *     The terminal whose font family and/or size are being changed.
+ *
+ * @param font_name
+ *     The name of the new font family, or NULL if the font family should
+ *     remain unchanged.
+ *
+ * @param font_size
+ *     The new font size, in points, or -1 if the font size should remain
+ *     unchanged.
+ *
+ * @param dpi
+ *     The resolution of the display in DPI. If the font size will not be
+ *     changed (the font size given is -1), this value is ignored.
+ */
+void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
+        int font_size, int dpi);
+
 #endif