From eec3607b16705efe6c18e3bbc18262b4ec032dbf Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 10 Jul 2017 14:08:21 -0700 Subject: [PATCH 1/2] GUACAMOLE-279: Migrate to mutable terminal color palette. --- src/terminal/display.c | 41 ++++++++++++++++++- src/terminal/palette.c | 2 +- src/terminal/terminal.c | 7 +++- src/terminal/terminal/display.h | 68 +++++++++++++++++++++++++++++++- src/terminal/terminal/palette.h | 6 ++- src/terminal/terminal/terminal.h | 3 +- src/terminal/terminal_handlers.c | 54 ++++++++++++++----------- 7 files changed, 149 insertions(+), 32 deletions(-) diff --git a/src/terminal/display.c b/src/terminal/display.c index de2cae5a..90bc6f00 100644 --- a/src/terminal/display.c +++ b/src/terminal/display.c @@ -26,6 +26,7 @@ #include "terminal/types.h" #include +#include #include #include #include @@ -121,7 +122,7 @@ int __guac_terminal_set_colors(guac_terminal_display* display, if (attributes->bold && !attributes->half_bright && foreground->palette_index >= GUAC_TERMINAL_FIRST_DARK && foreground->palette_index <= GUAC_TERMINAL_LAST_DARK) { - foreground = &guac_terminal_palette[foreground->palette_index + foreground = &display->palette[foreground->palette_index + GUAC_TERMINAL_INTENSE_OFFSET]; } @@ -323,6 +324,44 @@ void guac_terminal_display_free(guac_terminal_display* display) { } +void guac_terminal_display_reset_palette(guac_terminal_display* display) { + + /* Reinitialize palette with default values */ + memcpy(display->palette, GUAC_TERMINAL_INITIAL_PALETTE, + sizeof(GUAC_TERMINAL_INITIAL_PALETTE)); + +} + +int guac_terminal_display_assign_color(guac_terminal_display* display, + int index, uint8_t red, uint8_t green, uint8_t blue) { + + /* Assignment fails if out-of-bounds */ + if (index < 0 || index > 255) + return 1; + + /* Copy color components */ + display->palette[index].red = red; + display->palette[index].green = green; + display->palette[index].blue = blue; + + /* Color successfully stored */ + return 0; + +} + +int guac_terminal_display_lookup_color(guac_terminal_display* display, + int index, guac_terminal_color* color) { + + /* Lookup fails if out-of-bounds */ + if (index < 0 || index > 255) + return 1; + + /* Copy color definition */ + *color = display->palette[index]; + return 0; + +} + void guac_terminal_display_copy_columns(guac_terminal_display* display, int row, int start_column, int end_column, int offset) { diff --git a/src/terminal/palette.c b/src/terminal/palette.c index 5c9c3b40..cdbe4156 100644 --- a/src/terminal/palette.c +++ b/src/terminal/palette.c @@ -20,7 +20,7 @@ #include "config.h" #include "terminal/palette.h" -const guac_terminal_color guac_terminal_palette[256] = { +const guac_terminal_color GUAC_TERMINAL_INITIAL_PALETTE[256] = { /* Normal colors */ {0, 0x00, 0x00, 0x00}, /* Black */ diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index bba95f06..18477e34 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -178,6 +178,9 @@ void guac_terminal_reset(guac_terminal* term) { term->tab_interval = 8; memset(term->custom_tabs, 0, sizeof(term->custom_tabs)); + /* Reset display palette */ + guac_terminal_display_reset_palette(term->display); + /* Clear terminal */ for (row=0; rowterm_height; row++) guac_terminal_set_columns(term, row, 0, term->term_width, &(term->default_char)); @@ -296,8 +299,8 @@ guac_terminal* guac_terminal_create(guac_client* client, guac_terminal_char default_char = { .value = 0, .attributes = { - .foreground = guac_terminal_palette[default_foreground], - .background = guac_terminal_palette[default_background], + .foreground = GUAC_TERMINAL_INITIAL_PALETTE[default_foreground], + .background = GUAC_TERMINAL_INITIAL_PALETTE[default_background], .bold = false, .half_bright = false, .reverse = false, diff --git a/src/terminal/terminal/display.h b/src/terminal/terminal/display.h index 6397fe53..c843bb88 100644 --- a/src/terminal/terminal/display.h +++ b/src/terminal/terminal/display.h @@ -32,6 +32,7 @@ #include #include +#include /** * The maximum width of any character, in columns. @@ -92,7 +93,8 @@ typedef struct guac_terminal_operation { } guac_terminal_operation; /** - * Set of all pending operations for the currently-visible screen area. + * Set of all pending operations for the currently-visible screen area, and the + * contextual information necessary to interpret and render those changes. */ typedef struct guac_terminal_display { @@ -131,6 +133,11 @@ typedef struct guac_terminal_display { */ int char_height; + /** + * The current palette. + */ + guac_terminal_color palette[256]; + /** * Default foreground color for all glyphs. */ @@ -215,6 +222,65 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client, */ void guac_terminal_display_free(guac_terminal_display* display); +/** + * Resets the palette of the given display to the initial, default color + * values, as defined by GUAC_TERMINAL_INITIAL_PALETTE. + * + * @param display + * The display to reset. + */ +void guac_terminal_display_reset_palette(guac_terminal_display* display); + +/** + * Replaces the color in the palette at the given index with a new color having + * the given RGB components. If the index is invalid, the assignment is + * ignored. + * + * @param display + * The display whose palette is being changed. + * + * @param index + * The index of the palette entry to change. + * + * @param red + * The red color component of the color to assign to the palette entry + * having the given index. + * + * @param green + * The green color component of the color to assign to the palette entry + * having the given index. + * + * @param blue + * The blue color component of the color to assign to the palette entry + * having the given index. + * + * @returns + * Zero if the assignment was successful, non-zero if the assignment + * failed. + */ +int guac_terminal_display_assign_color(guac_terminal_display* display, + int index, uint8_t red, uint8_t green, uint8_t blue); + +/** + * Retrieves the color within the palette at the given index, if such a color + * exists. If the index is invalid, no color is retrieved. + * + * @param display + * The display whose palette contains the color to be retrieved. + * + * @param index + * The index of the palette entry to retrieve. + * + * @param color + * A pointer to a guac_terminal_color structure which should receive the + * color retrieved from the palette. + * + * @returns + * Zero if the color was successfully retrieved, non-zero otherwise. + */ +int guac_terminal_display_lookup_color(guac_terminal_display* display, + int index, guac_terminal_color* color); + /** * Copies the given range of columns to a new location, offset from * the original by the given number of columns. diff --git a/src/terminal/terminal/palette.h b/src/terminal/terminal/palette.h index b18038fb..7f467258 100644 --- a/src/terminal/terminal/palette.h +++ b/src/terminal/terminal/palette.h @@ -185,9 +185,11 @@ int guac_terminal_colorcmp(const guac_terminal_color* a, const guac_terminal_color* b); /** - * The terminal color palette. + * The initial state of the terminal color palette. The color palette used by + * the terminal may modified after the terminal is created through console + * codes. */ -extern const guac_terminal_color guac_terminal_palette[256]; +extern const guac_terminal_color GUAC_TERMINAL_INITIAL_PALETTE[256]; #endif diff --git a/src/terminal/terminal/terminal.h b/src/terminal/terminal/terminal.h index f37e8705..351cb11c 100644 --- a/src/terminal/terminal/terminal.h +++ b/src/terminal/terminal/terminal.h @@ -314,7 +314,8 @@ struct guac_terminal { /** * The difference between the currently-rendered screen and the current - * state of the terminal. + * state of the terminal, and the contextual information necessary to + * interpret and render those differences. */ guac_terminal_display* display; diff --git a/src/terminal/terminal_handlers.c b/src/terminal/terminal_handlers.c index e0be18f6..6f013a21 100644 --- a/src/terminal/terminal_handlers.c +++ b/src/terminal/terminal_handlers.c @@ -489,6 +489,9 @@ static int guac_terminal_parse_xterm256_rgb(int argc, const int* argv, * Parses an xterm SGR sequence specifying the index of a color within the * 256-color palette. * + * @param terminal + * The terminal associated with the palette. + * * @param argc * The number of arguments within the argv array. * @@ -504,20 +507,15 @@ static int guac_terminal_parse_xterm256_rgb(int argc, const int* argv, * The number of arguments parsed, or zero if the palette index is * absent. */ -static int guac_terminal_parse_xterm256_index(int argc, const int* argv, - guac_terminal_color* color) { +static int guac_terminal_parse_xterm256_index(guac_terminal* terminal, + int argc, const int* argv, guac_terminal_color* color) { /* 256-color palette entries require only one argument */ if (argc < 1) return 0; - /* Ignore if palette index is out of bounds */ - int index = argv[0]; - if (index < 0 || index > 255) - return 1; - /* Copy palette entry */ - *color = guac_terminal_palette[index]; + guac_terminal_display_lookup_color(terminal->display, argv[0], color); /* Done */ return 1; @@ -530,6 +528,10 @@ static int guac_terminal_parse_xterm256_index(int argc, const int* argv, * arguments required by these sequences varies. If a 256-color sequence is * recognized, the number of arguments parsed is returned. * + * @param terminal + * The terminal whose palette state should be used when parsing the xterm + * 256-color SGR sequence. + * * @param argc * The number of arguments within the argv array. * @@ -548,8 +550,8 @@ static int guac_terminal_parse_xterm256_index(int argc, const int* argv, * 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) { +static int guac_terminal_parse_xterm256(guac_terminal* terminal, + int argc, const int* argv, guac_terminal_color* color) { /* All 256-color codes must have at least a type */ if (argc < 1) @@ -564,7 +566,7 @@ static int guac_terminal_parse_xterm256(int argc, const int* argv, /* Palette index */ case 5: - return guac_terminal_parse_xterm256_index( + return guac_terminal_parse_xterm256_index(terminal, argc - 1, &argv[1], color) + 1; } @@ -925,8 +927,9 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) { /* Foreground */ else if (value >= 30 && value <= 37) - term->current_attributes.foreground = - guac_terminal_palette[value - 30]; + guac_terminal_display_lookup_color(term->display, + value - 30, + &term->current_attributes.foreground); /* Underscore on, default foreground OR 256-color * foreground */ @@ -934,7 +937,8 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) { /* Attempt to set foreground with 256-color entry */ int xterm256_length = - guac_terminal_parse_xterm256(argc - i - 1, &argv[i + 1], + guac_terminal_parse_xterm256(term, + argc - i - 1, &argv[i + 1], &term->current_attributes.foreground); /* If valid 256-color entry, foreground has been set */ @@ -960,13 +964,15 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) { /* Background */ else if (value >= 40 && value <= 47) - term->current_attributes.background = - guac_terminal_palette[value - 40]; + guac_terminal_display_lookup_color(term->display, + value - 40, + &term->current_attributes.background); /* 256-color background */ else if (value == 48) - i += guac_terminal_parse_xterm256(argc - i - 1, &argv[i + 1], - &term->current_attributes.background); + i += guac_terminal_parse_xterm256(term, + argc - i - 1, &argv[i + 1], + &term->current_attributes.background); /* Reset background */ else if (value == 49) @@ -975,15 +981,15 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) { /* Intense foreground */ else if (value >= 90 && value <= 97) - term->current_attributes.foreground = - guac_terminal_palette[value - 90 - + GUAC_TERMINAL_FIRST_INTENSE]; + guac_terminal_display_lookup_color(term->display, + value - 90 + GUAC_TERMINAL_FIRST_INTENSE, + &term->current_attributes.foreground); /* Intense background */ else if (value >= 100 && value <= 107) - term->current_attributes.background = - guac_terminal_palette[value - 100 - + GUAC_TERMINAL_FIRST_INTENSE]; + guac_terminal_display_lookup_color(term->display, + value - 100 + GUAC_TERMINAL_FIRST_INTENSE, + &term->current_attributes.background); } From c53575b18c0e2fcd8e03fcd26ec5be20fbc73a49 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 10 Jul 2017 21:13:23 -0700 Subject: [PATCH 2/2] GUACAMOLE-279: Use guac_terminal_color for color palette assignments. --- src/terminal/display.c | 9 ++++----- src/terminal/terminal/display.h | 20 +++++--------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/terminal/display.c b/src/terminal/display.c index 90bc6f00..fff61d18 100644 --- a/src/terminal/display.c +++ b/src/terminal/display.c @@ -26,7 +26,6 @@ #include "terminal/types.h" #include -#include #include #include #include @@ -333,16 +332,16 @@ void guac_terminal_display_reset_palette(guac_terminal_display* display) { } int guac_terminal_display_assign_color(guac_terminal_display* display, - int index, uint8_t red, uint8_t green, uint8_t blue) { + int index, const guac_terminal_color* color) { /* Assignment fails if out-of-bounds */ if (index < 0 || index > 255) return 1; /* Copy color components */ - display->palette[index].red = red; - display->palette[index].green = green; - display->palette[index].blue = blue; + display->palette[index].red = color->red; + display->palette[index].green = color->green; + display->palette[index].blue = color->blue; /* Color successfully stored */ return 0; diff --git a/src/terminal/terminal/display.h b/src/terminal/terminal/display.h index c843bb88..e51b07fd 100644 --- a/src/terminal/terminal/display.h +++ b/src/terminal/terminal/display.h @@ -232,9 +232,8 @@ void guac_terminal_display_free(guac_terminal_display* display); void guac_terminal_display_reset_palette(guac_terminal_display* display); /** - * Replaces the color in the palette at the given index with a new color having - * the given RGB components. If the index is invalid, the assignment is - * ignored. + * Replaces the color in the palette at the given index with the given color. + * If the index is invalid, the assignment is ignored. * * @param display * The display whose palette is being changed. @@ -242,24 +241,15 @@ void guac_terminal_display_reset_palette(guac_terminal_display* display); * @param index * The index of the palette entry to change. * - * @param red - * The red color component of the color to assign to the palette entry - * having the given index. - * - * @param green - * The green color component of the color to assign to the palette entry - * having the given index. - * - * @param blue - * The blue color component of the color to assign to the palette entry - * having the given index. + * @param color + * The color to assign to the palette entry having the given index. * * @returns * Zero if the assignment was successful, non-zero if the assignment * failed. */ int guac_terminal_display_assign_color(guac_terminal_display* display, - int index, uint8_t red, uint8_t green, uint8_t blue); + int index, const guac_terminal_color* color); /** * Retrieves the color within the palette at the given index, if such a color