GUACAMOLE-279: Migrate to mutable terminal color palette.
This commit is contained in:
parent
6236eb8f98
commit
eec3607b16
@ -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) {
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user