GUACAMOLE-278: Copy terminal color values rather than referencing only by palette index.
This commit is contained in:
parent
69caa9936b
commit
48fc4afc5b
@ -105,3 +105,23 @@ int guac_terminal_write_all(int fd, const char* buffer, int size) {
|
||||
|
||||
}
|
||||
|
||||
int guac_terminal_colorcmp(const guac_terminal_color* a,
|
||||
const guac_terminal_color* b) {
|
||||
|
||||
/* Consider red component highest order ... */
|
||||
if (a->red != b->red)
|
||||
return a->red - b->red;
|
||||
|
||||
/* ... followed by green ... */
|
||||
if (a->green != b->green)
|
||||
return a->green - b->green;
|
||||
|
||||
/* ... followed by blue */
|
||||
if (a->blue != b->blue)
|
||||
return a->blue - b->blue;
|
||||
|
||||
/* If all components match, colors are equal */
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -39,24 +39,24 @@
|
||||
const guac_terminal_color guac_terminal_palette[16] = {
|
||||
|
||||
/* Normal colors */
|
||||
{0x00, 0x00, 0x00}, /* Black */
|
||||
{0x99, 0x3E, 0x3E}, /* Red */
|
||||
{0x3E, 0x99, 0x3E}, /* Green */
|
||||
{0x99, 0x99, 0x3E}, /* Brown */
|
||||
{0x3E, 0x3E, 0x99}, /* Blue */
|
||||
{0x99, 0x3E, 0x99}, /* Magenta */
|
||||
{0x3E, 0x99, 0x99}, /* Cyan */
|
||||
{0x99, 0x99, 0x99}, /* White */
|
||||
{0, 0x00, 0x00, 0x00}, /* Black */
|
||||
{1, 0x99, 0x3E, 0x3E}, /* Red */
|
||||
{2, 0x3E, 0x99, 0x3E}, /* Green */
|
||||
{3, 0x99, 0x99, 0x3E}, /* Brown */
|
||||
{4, 0x3E, 0x3E, 0x99}, /* Blue */
|
||||
{5, 0x99, 0x3E, 0x99}, /* Magenta */
|
||||
{6, 0x3E, 0x99, 0x99}, /* Cyan */
|
||||
{7, 0x99, 0x99, 0x99}, /* White */
|
||||
|
||||
/* Intense colors */
|
||||
{0x3E, 0x3E, 0x3E}, /* Black */
|
||||
{0xFF, 0x67, 0x67}, /* Red */
|
||||
{0x67, 0xFF, 0x67}, /* Green */
|
||||
{0xFF, 0xFF, 0x67}, /* Brown */
|
||||
{0x67, 0x67, 0xFF}, /* Blue */
|
||||
{0xFF, 0x67, 0xFF}, /* Magenta */
|
||||
{0x67, 0xFF, 0xFF}, /* Cyan */
|
||||
{0xFF, 0xFF, 0xFF}, /* White */
|
||||
{8, 0x3E, 0x3E, 0x3E}, /* Black */
|
||||
{9, 0xFF, 0x67, 0x67}, /* Red */
|
||||
{10, 0x67, 0xFF, 0x67}, /* Green */
|
||||
{11, 0xFF, 0xFF, 0x67}, /* Brown */
|
||||
{12, 0x67, 0x67, 0xFF}, /* Blue */
|
||||
{13, 0xFF, 0x67, 0xFF}, /* Magenta */
|
||||
{14, 0x67, 0xFF, 0xFF}, /* Cyan */
|
||||
{15, 0xFF, 0xFF, 0xFF}, /* White */
|
||||
|
||||
};
|
||||
|
||||
@ -127,24 +127,27 @@ int __guac_terminal_hash_codepoint(int codepoint) {
|
||||
int __guac_terminal_set_colors(guac_terminal_display* display,
|
||||
guac_terminal_attributes* attributes) {
|
||||
|
||||
int background, foreground;
|
||||
const guac_terminal_color* background;
|
||||
const guac_terminal_color* foreground;
|
||||
|
||||
/* Handle reverse video */
|
||||
if (attributes->reverse != attributes->cursor) {
|
||||
background = attributes->foreground;
|
||||
foreground = attributes->background;
|
||||
background = &attributes->foreground;
|
||||
foreground = &attributes->background;
|
||||
}
|
||||
else {
|
||||
foreground = attributes->foreground;
|
||||
background = attributes->background;
|
||||
foreground = &attributes->foreground;
|
||||
background = &attributes->background;
|
||||
}
|
||||
|
||||
/* Handle bold */
|
||||
if (attributes->bold && foreground <= 7)
|
||||
foreground += 8;
|
||||
if (attributes->bold && foreground->palette_index >= 0
|
||||
&& foreground->palette_index <= 7) {
|
||||
foreground = &guac_terminal_palette[foreground->palette_index + 8];
|
||||
}
|
||||
|
||||
display->glyph_foreground = foreground;
|
||||
display->glyph_background = background;
|
||||
display->glyph_foreground = *foreground;
|
||||
display->glyph_background = *background;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -163,12 +166,10 @@ int __guac_terminal_set(guac_terminal_display* display, int row, int col, int co
|
||||
char utf8[4];
|
||||
|
||||
/* Use foreground color */
|
||||
const guac_terminal_color* color =
|
||||
&guac_terminal_palette[display->glyph_foreground];
|
||||
const guac_terminal_color* color = &display->glyph_foreground;
|
||||
|
||||
/* Use background color */
|
||||
const guac_terminal_color* background =
|
||||
&guac_terminal_palette[display->glyph_background];
|
||||
const guac_terminal_color* background = &display->glyph_background;
|
||||
|
||||
cairo_surface_t* surface;
|
||||
cairo_t* cairo;
|
||||
@ -259,7 +260,7 @@ int __guac_terminal_set(guac_terminal_display* display, int row, int col, int co
|
||||
|
||||
guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
|
||||
const char* font_name, int font_size, int dpi,
|
||||
int foreground, int background) {
|
||||
guac_terminal_color* foreground, guac_terminal_color* background) {
|
||||
|
||||
PangoFontMap* font_map;
|
||||
PangoFont* font;
|
||||
@ -303,8 +304,8 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
display->default_foreground = display->glyph_foreground = foreground;
|
||||
display->default_background = display->glyph_background = background;
|
||||
display->default_foreground = display->glyph_foreground = *foreground;
|
||||
display->default_background = display->glyph_background = *background;
|
||||
|
||||
/* Calculate character dimensions */
|
||||
display->char_width =
|
||||
@ -688,14 +689,11 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
|
||||
int rect_width, rect_height;
|
||||
|
||||
/* Color of the rectangle to draw */
|
||||
int color;
|
||||
const guac_terminal_color* color;
|
||||
if (current->character.attributes.reverse != current->character.attributes.cursor)
|
||||
color = current->character.attributes.foreground;
|
||||
color = ¤t->character.attributes.foreground;
|
||||
else
|
||||
color = current->character.attributes.background;
|
||||
|
||||
const guac_terminal_color* guac_color =
|
||||
&guac_terminal_palette[color];
|
||||
color = ¤t->character.attributes.background;
|
||||
|
||||
/* Current row within a subrect */
|
||||
guac_terminal_operation* rect_current_row;
|
||||
@ -709,16 +707,16 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
|
||||
/* Find width */
|
||||
for (rect_col=col; rect_col<display->width; rect_col++) {
|
||||
|
||||
int joining_color;
|
||||
const guac_terminal_color* joining_color;
|
||||
if (rect_current->character.attributes.reverse != rect_current->character.attributes.cursor)
|
||||
joining_color = rect_current->character.attributes.foreground;
|
||||
joining_color = &rect_current->character.attributes.foreground;
|
||||
else
|
||||
joining_color = rect_current->character.attributes.background;
|
||||
joining_color = &rect_current->character.attributes.background;
|
||||
|
||||
/* If not identical operation, stop */
|
||||
if (rect_current->type != GUAC_CHAR_SET
|
||||
|| guac_terminal_has_glyph(rect_current->character.value)
|
||||
|| joining_color != color)
|
||||
|| guac_terminal_colorcmp(joining_color, color) != 0)
|
||||
break;
|
||||
|
||||
/* Next column */
|
||||
@ -754,16 +752,16 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
|
||||
|
||||
for (rect_col=0; rect_col<rect_width; rect_col++) {
|
||||
|
||||
int joining_color;
|
||||
const guac_terminal_color* joining_color;
|
||||
if (rect_current->character.attributes.reverse != rect_current->character.attributes.cursor)
|
||||
joining_color = rect_current->character.attributes.foreground;
|
||||
joining_color = &rect_current->character.attributes.foreground;
|
||||
else
|
||||
joining_color = rect_current->character.attributes.background;
|
||||
joining_color = &rect_current->character.attributes.background;
|
||||
|
||||
/* Mark clear operations as NOP */
|
||||
if (rect_current->type == GUAC_CHAR_SET
|
||||
&& !guac_terminal_has_glyph(rect_current->character.value)
|
||||
&& joining_color == color)
|
||||
&& guac_terminal_colorcmp(joining_color, color) == 0)
|
||||
rect_current->type = GUAC_CHAR_NOP;
|
||||
|
||||
/* Next column */
|
||||
@ -783,7 +781,7 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
|
||||
row * display->char_height,
|
||||
rect_width * display->char_width,
|
||||
rect_height * display->char_height,
|
||||
guac_color->red, guac_color->green, guac_color->blue,
|
||||
color->red, color->green, color->blue,
|
||||
0xFF);
|
||||
|
||||
} /* end if clear operation */
|
||||
|
@ -205,8 +205,7 @@ static void guac_terminal_repaint_default_layer(guac_terminal* terminal,
|
||||
guac_terminal_display* display = terminal->display;
|
||||
|
||||
/* Get background color */
|
||||
const guac_terminal_color* color =
|
||||
&guac_terminal_palette[display->default_background];
|
||||
const guac_terminal_color* color = &display->default_background;
|
||||
|
||||
/* Reset size */
|
||||
guac_protocol_send_size(socket, GUAC_DEFAULT_LAYER, width, height);
|
||||
@ -296,8 +295,8 @@ guac_terminal* guac_terminal_create(guac_client* client,
|
||||
guac_terminal_char default_char = {
|
||||
.value = 0,
|
||||
.attributes = {
|
||||
.foreground = default_foreground,
|
||||
.background = default_background,
|
||||
.foreground = guac_terminal_palette[default_foreground],
|
||||
.background = guac_terminal_palette[default_background],
|
||||
.bold = false,
|
||||
.reverse = false,
|
||||
.underscore = false
|
||||
@ -326,8 +325,8 @@ guac_terminal* guac_terminal_create(guac_client* client,
|
||||
/* Init display */
|
||||
term->display = guac_terminal_display_alloc(client,
|
||||
font_name, font_size, dpi,
|
||||
default_char.attributes.foreground,
|
||||
default_char.attributes.background);
|
||||
&default_char.attributes.foreground,
|
||||
&default_char.attributes.background);
|
||||
|
||||
/* Fail if display init failed */
|
||||
if (term->display == NULL) {
|
||||
@ -875,17 +874,18 @@ static bool guac_terminal_is_visible(guac_terminal* term,
|
||||
if (guac_terminal_has_glyph(c->value))
|
||||
return true;
|
||||
|
||||
int background;
|
||||
const guac_terminal_color* background;
|
||||
|
||||
/* Determine actual background color of character */
|
||||
if (c->attributes.reverse != c->attributes.cursor)
|
||||
background = c->attributes.foreground;
|
||||
background = &c->attributes.foreground;
|
||||
else
|
||||
background = c->attributes.background;
|
||||
background = &c->attributes.background;
|
||||
|
||||
/* Blank characters are visible if their background color differs from that
|
||||
* of the terminal */
|
||||
return background != term->default_char.attributes.background;
|
||||
return guac_terminal_colorcmp(background,
|
||||
&term->default_char.attributes.background) != 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define _GUAC_TERMINAL_COMMON_H
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
@ -49,5 +50,26 @@ bool guac_terminal_has_glyph(int codepoint);
|
||||
*/
|
||||
int guac_terminal_write_all(int fd, const char* buffer, int size);
|
||||
|
||||
/**
|
||||
* Compares two colors, returning a negative value if the first color is less
|
||||
* than the second, a positive value if the first color is greater than the
|
||||
* second, and zero if the colors are identical. Only the color components are
|
||||
* compared (not the palette index). The red component is considered the
|
||||
* highest order component, followed by green, followed by blue.
|
||||
*
|
||||
* @param a
|
||||
* The first color to compare.
|
||||
*
|
||||
* @param b
|
||||
* The second color to compare.
|
||||
*
|
||||
* @return
|
||||
* A negative value if the first color is less than the second, a positive
|
||||
* value if the first color is greater than the second, and zero if the
|
||||
* colors are identical.
|
||||
*/
|
||||
int guac_terminal_colorcmp(const guac_terminal_color* a,
|
||||
const guac_terminal_color* b);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -220,22 +220,24 @@ typedef struct guac_terminal_display {
|
||||
/**
|
||||
* Default foreground color for all glyphs.
|
||||
*/
|
||||
int default_foreground;
|
||||
guac_terminal_color default_foreground;
|
||||
|
||||
/**
|
||||
* Default background color for all glyphs and the terminal itself.
|
||||
*/
|
||||
int default_background;
|
||||
guac_terminal_color default_background;
|
||||
|
||||
/**
|
||||
* Color of glyphs in copy buffer
|
||||
* The foreground color to be used for the next glyph rendered to the
|
||||
* terminal.
|
||||
*/
|
||||
int glyph_foreground;
|
||||
guac_terminal_color glyph_foreground;
|
||||
|
||||
/**
|
||||
* Color of glyphs in copy buffer
|
||||
* The background color to be used for the next glyph rendered to the
|
||||
* terminal.
|
||||
*/
|
||||
int glyph_background;
|
||||
guac_terminal_color glyph_background;
|
||||
|
||||
/**
|
||||
* The surface containing the actual terminal.
|
||||
@ -292,7 +294,7 @@ typedef struct guac_terminal_display {
|
||||
*/
|
||||
guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
|
||||
const char* font_name, int font_size, int dpi,
|
||||
int foreground, int background);
|
||||
guac_terminal_color* foreground, guac_terminal_color* background);
|
||||
|
||||
/**
|
||||
* Frees the given display.
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* A character which is not truly a character, but rather part of an
|
||||
@ -39,20 +40,26 @@
|
||||
*/
|
||||
typedef struct guac_terminal_color {
|
||||
|
||||
/**
|
||||
* The index of this color within the terminal palette, or -1 if the color
|
||||
* does not exist within the terminal palette.
|
||||
*/
|
||||
int palette_index;
|
||||
|
||||
/**
|
||||
* The red component of this color.
|
||||
*/
|
||||
int red;
|
||||
uint8_t red;
|
||||
|
||||
/**
|
||||
* The green component of this color.
|
||||
*/
|
||||
int green;
|
||||
uint8_t green;
|
||||
|
||||
/**
|
||||
* The blue component of this color.
|
||||
*/
|
||||
int blue;
|
||||
uint8_t blue;
|
||||
|
||||
} guac_terminal_color;
|
||||
|
||||
@ -83,14 +90,14 @@ typedef struct guac_terminal_attributes {
|
||||
bool underscore;
|
||||
|
||||
/**
|
||||
* The foreground color of this character, as a palette index.
|
||||
* The foreground color of this character.
|
||||
*/
|
||||
int foreground;
|
||||
guac_terminal_color foreground;
|
||||
|
||||
/**
|
||||
* The background color of this character, as a palette index.
|
||||
* The background color of this character.
|
||||
*/
|
||||
int background;
|
||||
guac_terminal_color background;
|
||||
|
||||
} guac_terminal_attributes;
|
||||
|
||||
|
@ -779,7 +779,8 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
|
||||
|
||||
/* Foreground */
|
||||
else if (value >= 30 && value <= 37)
|
||||
term->current_attributes.foreground = value - 30;
|
||||
term->current_attributes.foreground =
|
||||
guac_terminal_palette[value - 30];
|
||||
|
||||
/* Underscore on, default foreground */
|
||||
else if (value == 38) {
|
||||
@ -797,7 +798,8 @@ int guac_terminal_csi(guac_terminal* term, unsigned char c) {
|
||||
|
||||
/* Background */
|
||||
else if (value >= 40 && value <= 47)
|
||||
term->current_attributes.background = value - 40;
|
||||
term->current_attributes.background =
|
||||
guac_terminal_palette[value - 40];
|
||||
|
||||
/* Reset background */
|
||||
else if (value == 49)
|
||||
|
Loading…
Reference in New Issue
Block a user