GUACAMOLE-278: Handle xterm 256-color SGR sequences.

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

Branch: refs/heads/master
Commit: 87fba523ee668c8f7f81d36d2df5c3c560aff8c9
Parents: 11bf6f0
Author: Michael Jumper <[email protected]>
Authored: Sun Apr 23 12:53:47 2017 -0700
Committer: Michael Jumper <[email protected]>
Committed: Sun Apr 23 13:24:13 2017 -0700

----------------------------------------------------------------------
 src/terminal/terminal_handlers.c | 156 +++++++++++++++++++++++++++++++++-
 1 file changed, 152 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/87fba523/src/terminal/terminal_handlers.c
----------------------------------------------------------------------
diff --git a/src/terminal/terminal_handlers.c b/src/terminal/terminal_handlers.c
index a4e514c..ecb60e9 100644
--- a/src/terminal/terminal_handlers.c
+++ b/src/terminal/terminal_handlers.c
@@ -435,6 +435,133 @@ static bool* __guac_terminal_get_flag(guac_terminal* 
term, int num, char private
 
 }
 
+/**
+ * Parses an xterm SGR sequence specifying the RGB values of a color.
+ *
+ * @param argc
+ *     The number of arguments within the argv array.
+ *
+ * @param argv
+ *     The SGR arguments to parse, with the first relevant argument the
+ *     red component of the RGB color.
+ *
+ * @param color
+ *     The guac_terminal_color structure which should receive the parsed
+ *     color values.
+ *
+ * @return
+ *     The number of arguments parsed, or zero if argv does not contain
+ *     enough elements to represent an RGB color.
+ */
+static int guac_terminal_parse_xterm256_rgb(int argc, const int* argv,
+        guac_terminal_color* color) {
+
+    /* RGB color palette entries require three arguments */
+    if (argc < 3)
+        return 0;
+
+    /* Store RGB components */
+    color->red   = (uint8_t) argv[0];
+    color->green = (uint8_t) argv[1];
+    color->blue  = (uint8_t) argv[2];
+
+    /* Color is not from the palette */
+    color->palette_index = -1;
+
+    /* Done */
+    return 3;
+
+}
+
+/**
+ * Parses an xterm SGR sequence specifying the index of a color within the
+ * 256-color palette.
+ *
+ * @param argc
+ *     The number of arguments within the argv array.
+ *
+ * @param argv
+ *     The SGR arguments to parse, with the first relevant argument being
+ *     the index of the color.
+ *
+ * @param color
+ *     The guac_terminal_color structure which should receive the parsed
+ *     color values.
+ *
+ * @return
+ *     The number of arguments parsed, or zero if the palette index is
+ *     out of range or absent.
+ */
+static int guac_terminal_parse_xterm256_index(int argc, const int* argv,
+        guac_terminal_color* color) {
+
+    /* 256-color palette entries require only one argument */
+    if (argc < 1)
+        return 0;
+
+    /* Verify palette index bounds */
+    int index = argv[0];
+    if (index < 0 || index > 255)
+        return 0;
+
+    /* Copy palette entry */
+    *color = guac_terminal_palette[index];
+
+    /* Done */
+    return 1;
+
+}
+
+/**
+ * Parses an xterm SGR sequence specifying the index of a color within the
+ * 256-color palette, or specfying the RGB values of a color. The number of
+ * arguments required by these sequences varies. If a 256-color sequence is
+ * recognized, the number of arguments parsed is returned.
+ *
+ * @param argc
+ *     The number of arguments within the argv array.
+ *
+ * @param argv
+ *     The SGR arguments to parse, with the first relevant argument being
+ *     the first element of the array. In the case of an xterm 256-color
+ *     SGR sequence, the first element here will be either 2, for an
+ *     RGB color, or 5, for a 256-color palette index. All other values
+ *     are invalid and will not be parsed.
+ *
+ * @param color
+ *     The guac_terminal_color structure which should receive the parsed
+ *     color values.
+ *
+ * @return
+ *     The number of arguments parsed, or zero if argv does not point to
+ *     the first element of an xterm 256-color SGR sequence.
+ */
+static int guac_terminal_parse_xterm256(int argc, const int* argv,
+        guac_terminal_color* color) {
+
+    /* All 256-color codes must have at least a type */
+    if (argc < 1)
+        return 0;
+
+    switch (argv[0]) {
+
+        /* RGB */
+        case 2:
+            return guac_terminal_parse_xterm256_rgb(
+                    argc - 1, &argv[1], color) + 1;
+
+        /* Palette index */
+        case 5:
+            return guac_terminal_parse_xterm256_index(
+                    argc - 1, &argv[1], color) + 1;
+
+    }
+
+    /* Invalid type */
+    return 0;
+
+}
+
 int guac_terminal_csi(guac_terminal* term, unsigned char c) {
 
     /* CSI function arguments */
@@ -783,11 +910,27 @@ int guac_terminal_csi(guac_terminal* term, unsigned char 
c) {
                         term->current_attributes.foreground =
                             guac_terminal_palette[value - 30];
 
-                    /* Underscore on, default foreground */
+                    /* Underscore on, default foreground OR 256-color
+                     * foreground */
                     else if (value == 38) {
-                        term->current_attributes.underscore = true;
-                        term->current_attributes.foreground =
-                            term->default_char.attributes.foreground;
+
+                        /* Attempt to set foreground with 256-color entry */
+                        int xterm256_length =
+                            guac_terminal_parse_xterm256(argc - 1, &argv[i + 
1],
+                                    &term->current_attributes.foreground);
+
+                        /* If valid 256-color entry, foreground has been set */
+                        if (xterm256_length > 0)
+                            i += xterm256_length;
+
+                        /* Otherwise interpret as underscore and default
+                         * foreground  */
+                        else {
+                            term->current_attributes.underscore = true;
+                            term->current_attributes.foreground =
+                                term->default_char.attributes.foreground;
+                        }
+
                     }
 
                     /* Underscore off, default foreground */
@@ -802,6 +945,11 @@ int guac_terminal_csi(guac_terminal* term, unsigned char 
c) {
                         term->current_attributes.background =
                             guac_terminal_palette[value - 40];
 
+                    /* 256-color background */
+                    else if (value == 48)
+                        i += guac_terminal_parse_xterm256(argc - 1, &argv[i + 
1],
+                                    &term->current_attributes.background);
+
                     /* Reset background */
                     else if (value == 49)
                         term->current_attributes.background =

Reply via email to