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

This commit is contained in:
Michael Jumper 2017-04-23 12:53:47 -07:00
parent 11bf6f05c4
commit 87fba523ee

View File

@ -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) { int guac_terminal_csi(guac_terminal* term, unsigned char c) {
/* CSI function arguments */ /* CSI function arguments */
@ -783,13 +910,29 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
term->current_attributes.foreground = term->current_attributes.foreground =
guac_terminal_palette[value - 30]; guac_terminal_palette[value - 30];
/* Underscore on, default foreground */ /* Underscore on, default foreground OR 256-color
* foreground */
else if (value == 38) { else if (value == 38) {
/* 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.underscore = true;
term->current_attributes.foreground = term->current_attributes.foreground =
term->default_char.attributes.foreground; term->default_char.attributes.foreground;
} }
}
/* Underscore off, default foreground */ /* Underscore off, default foreground */
else if (value == 39) { else if (value == 39) {
term->current_attributes.underscore = false; term->current_attributes.underscore = false;
@ -802,6 +945,11 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
term->current_attributes.background = term->current_attributes.background =
guac_terminal_palette[value - 40]; 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 */ /* Reset background */
else if (value == 49) else if (value == 49)
term->current_attributes.background = term->current_attributes.background =