GUACAMOLE-279: Migrate to mutable terminal color palette.

This commit is contained in:
Michael Jumper 2017-07-10 14:08:21 -07:00
parent 6236eb8f98
commit eec3607b16
7 changed files with 149 additions and 32 deletions

View File

@ -26,6 +26,7 @@
#include "terminal/types.h" #include "terminal/types.h"
#include <math.h> #include <math.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
@ -121,7 +122,7 @@ int __guac_terminal_set_colors(guac_terminal_display* display,
if (attributes->bold && !attributes->half_bright if (attributes->bold && !attributes->half_bright
&& foreground->palette_index >= GUAC_TERMINAL_FIRST_DARK && foreground->palette_index >= GUAC_TERMINAL_FIRST_DARK
&& foreground->palette_index <= GUAC_TERMINAL_LAST_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]; + 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, void guac_terminal_display_copy_columns(guac_terminal_display* display, int row,
int start_column, int end_column, int offset) { int start_column, int end_column, int offset) {

View File

@ -20,7 +20,7 @@
#include "config.h" #include "config.h"
#include "terminal/palette.h" #include "terminal/palette.h"
const guac_terminal_color guac_terminal_palette[256] = { const guac_terminal_color GUAC_TERMINAL_INITIAL_PALETTE[256] = {
/* Normal colors */ /* Normal colors */
{0, 0x00, 0x00, 0x00}, /* Black */ {0, 0x00, 0x00, 0x00}, /* Black */

View File

@ -178,6 +178,9 @@ void guac_terminal_reset(guac_terminal* term) {
term->tab_interval = 8; term->tab_interval = 8;
memset(term->custom_tabs, 0, sizeof(term->custom_tabs)); memset(term->custom_tabs, 0, sizeof(term->custom_tabs));
/* Reset display palette */
guac_terminal_display_reset_palette(term->display);
/* Clear terminal */ /* Clear terminal */
for (row=0; row<term->term_height; row++) for (row=0; row<term->term_height; row++)
guac_terminal_set_columns(term, row, 0, term->term_width, &(term->default_char)); 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 = { guac_terminal_char default_char = {
.value = 0, .value = 0,
.attributes = { .attributes = {
.foreground = guac_terminal_palette[default_foreground], .foreground = GUAC_TERMINAL_INITIAL_PALETTE[default_foreground],
.background = guac_terminal_palette[default_background], .background = GUAC_TERMINAL_INITIAL_PALETTE[default_background],
.bold = false, .bold = false,
.half_bright = false, .half_bright = false,
.reverse = false, .reverse = false,

View File

@ -32,6 +32,7 @@
#include <pango/pangocairo.h> #include <pango/pangocairo.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
/** /**
* The maximum width of any character, in columns. * The maximum width of any character, in columns.
@ -92,7 +93,8 @@ typedef struct guac_terminal_operation {
} 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 { typedef struct guac_terminal_display {
@ -131,6 +133,11 @@ typedef struct guac_terminal_display {
*/ */
int char_height; int char_height;
/**
* The current palette.
*/
guac_terminal_color palette[256];
/** /**
* Default foreground color for all glyphs. * 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); 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 * Copies the given range of columns to a new location, offset from
* the original by the given number of columns. * the original by the given number of columns.

View File

@ -185,9 +185,11 @@ int guac_terminal_colorcmp(const guac_terminal_color* a,
const guac_terminal_color* b); 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 #endif

View File

@ -314,7 +314,8 @@ struct guac_terminal {
/** /**
* The difference between the currently-rendered screen and the current * 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; guac_terminal_display* display;

View File

@ -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 * Parses an xterm SGR sequence specifying the index of a color within the
* 256-color palette. * 256-color palette.
* *
* @param terminal
* The terminal associated with the palette.
*
* @param argc * @param argc
* The number of arguments within the argv array. * 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 * The number of arguments parsed, or zero if the palette index is
* absent. * absent.
*/ */
static int guac_terminal_parse_xterm256_index(int argc, const int* argv, static int guac_terminal_parse_xterm256_index(guac_terminal* terminal,
guac_terminal_color* color) { int argc, const int* argv, guac_terminal_color* color) {
/* 256-color palette entries require only one argument */ /* 256-color palette entries require only one argument */
if (argc < 1) if (argc < 1)
return 0; return 0;
/* Ignore if palette index is out of bounds */
int index = argv[0];
if (index < 0 || index > 255)
return 1;
/* Copy palette entry */ /* Copy palette entry */
*color = guac_terminal_palette[index]; guac_terminal_display_lookup_color(terminal->display, argv[0], color);
/* Done */ /* Done */
return 1; 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 * arguments required by these sequences varies. If a 256-color sequence is
* recognized, the number of arguments parsed is returned. * 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 * @param argc
* The number of arguments within the argv array. * 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 number of arguments parsed, or zero if argv does not point to
* the first element of an xterm 256-color SGR sequence. * the first element of an xterm 256-color SGR sequence.
*/ */
static int guac_terminal_parse_xterm256(int argc, const int* argv, static int guac_terminal_parse_xterm256(guac_terminal* terminal,
guac_terminal_color* color) { int argc, const int* argv, guac_terminal_color* color) {
/* All 256-color codes must have at least a type */ /* All 256-color codes must have at least a type */
if (argc < 1) if (argc < 1)
@ -564,7 +566,7 @@ static int guac_terminal_parse_xterm256(int argc, const int* argv,
/* Palette index */ /* Palette index */
case 5: case 5:
return guac_terminal_parse_xterm256_index( return guac_terminal_parse_xterm256_index(terminal,
argc - 1, &argv[1], color) + 1; argc - 1, &argv[1], color) + 1;
} }
@ -925,8 +927,9 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
/* Foreground */ /* Foreground */
else if (value >= 30 && value <= 37) else if (value >= 30 && value <= 37)
term->current_attributes.foreground = guac_terminal_display_lookup_color(term->display,
guac_terminal_palette[value - 30]; value - 30,
&term->current_attributes.foreground);
/* Underscore on, default foreground OR 256-color /* Underscore on, default foreground OR 256-color
* foreground */ * foreground */
@ -934,7 +937,8 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
/* Attempt to set foreground with 256-color entry */ /* Attempt to set foreground with 256-color entry */
int xterm256_length = 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); &term->current_attributes.foreground);
/* If valid 256-color entry, foreground has been set */ /* If valid 256-color entry, foreground has been set */
@ -960,12 +964,14 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
/* Background */ /* Background */
else if (value >= 40 && value <= 47) else if (value >= 40 && value <= 47)
term->current_attributes.background = guac_terminal_display_lookup_color(term->display,
guac_terminal_palette[value - 40]; value - 40,
&term->current_attributes.background);
/* 256-color background */ /* 256-color background */
else if (value == 48) else if (value == 48)
i += guac_terminal_parse_xterm256(argc - i - 1, &argv[i + 1], i += guac_terminal_parse_xterm256(term,
argc - i - 1, &argv[i + 1],
&term->current_attributes.background); &term->current_attributes.background);
/* Reset background */ /* Reset background */
@ -975,15 +981,15 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
/* Intense foreground */ /* Intense foreground */
else if (value >= 90 && value <= 97) else if (value >= 90 && value <= 97)
term->current_attributes.foreground = guac_terminal_display_lookup_color(term->display,
guac_terminal_palette[value - 90 value - 90 + GUAC_TERMINAL_FIRST_INTENSE,
+ GUAC_TERMINAL_FIRST_INTENSE]; &term->current_attributes.foreground);
/* Intense background */ /* Intense background */
else if (value >= 100 && value <= 107) else if (value >= 100 && value <= 107)
term->current_attributes.background = guac_terminal_display_lookup_color(term->display,
guac_terminal_palette[value - 100 value - 100 + GUAC_TERMINAL_FIRST_INTENSE,
+ GUAC_TERMINAL_FIRST_INTENSE]; &term->current_attributes.background);
} }