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 "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) {
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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,
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user