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 <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
@ -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) {

View File

@ -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 */

View File

@ -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; row<term->term_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,

View File

@ -32,6 +32,7 @@
#include <pango/pangocairo.h>
#include <stdbool.h>
#include <stdint.h>
/**
* 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.

View File

@ -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

View File

@ -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;

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
* 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,12 +964,14 @@ 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],
i += guac_terminal_parse_xterm256(term,
argc - i - 1, &argv[i + 1],
&term->current_attributes.background);
/* Reset background */
@ -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);
}