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] = {
|
const guac_terminal_color guac_terminal_palette[16] = {
|
||||||
|
|
||||||
/* Normal colors */
|
/* Normal colors */
|
||||||
{0x00, 0x00, 0x00}, /* Black */
|
{0, 0x00, 0x00, 0x00}, /* Black */
|
||||||
{0x99, 0x3E, 0x3E}, /* Red */
|
{1, 0x99, 0x3E, 0x3E}, /* Red */
|
||||||
{0x3E, 0x99, 0x3E}, /* Green */
|
{2, 0x3E, 0x99, 0x3E}, /* Green */
|
||||||
{0x99, 0x99, 0x3E}, /* Brown */
|
{3, 0x99, 0x99, 0x3E}, /* Brown */
|
||||||
{0x3E, 0x3E, 0x99}, /* Blue */
|
{4, 0x3E, 0x3E, 0x99}, /* Blue */
|
||||||
{0x99, 0x3E, 0x99}, /* Magenta */
|
{5, 0x99, 0x3E, 0x99}, /* Magenta */
|
||||||
{0x3E, 0x99, 0x99}, /* Cyan */
|
{6, 0x3E, 0x99, 0x99}, /* Cyan */
|
||||||
{0x99, 0x99, 0x99}, /* White */
|
{7, 0x99, 0x99, 0x99}, /* White */
|
||||||
|
|
||||||
/* Intense colors */
|
/* Intense colors */
|
||||||
{0x3E, 0x3E, 0x3E}, /* Black */
|
{8, 0x3E, 0x3E, 0x3E}, /* Black */
|
||||||
{0xFF, 0x67, 0x67}, /* Red */
|
{9, 0xFF, 0x67, 0x67}, /* Red */
|
||||||
{0x67, 0xFF, 0x67}, /* Green */
|
{10, 0x67, 0xFF, 0x67}, /* Green */
|
||||||
{0xFF, 0xFF, 0x67}, /* Brown */
|
{11, 0xFF, 0xFF, 0x67}, /* Brown */
|
||||||
{0x67, 0x67, 0xFF}, /* Blue */
|
{12, 0x67, 0x67, 0xFF}, /* Blue */
|
||||||
{0xFF, 0x67, 0xFF}, /* Magenta */
|
{13, 0xFF, 0x67, 0xFF}, /* Magenta */
|
||||||
{0x67, 0xFF, 0xFF}, /* Cyan */
|
{14, 0x67, 0xFF, 0xFF}, /* Cyan */
|
||||||
{0xFF, 0xFF, 0xFF}, /* White */
|
{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,
|
int __guac_terminal_set_colors(guac_terminal_display* display,
|
||||||
guac_terminal_attributes* attributes) {
|
guac_terminal_attributes* attributes) {
|
||||||
|
|
||||||
int background, foreground;
|
const guac_terminal_color* background;
|
||||||
|
const guac_terminal_color* foreground;
|
||||||
|
|
||||||
/* Handle reverse video */
|
/* Handle reverse video */
|
||||||
if (attributes->reverse != attributes->cursor) {
|
if (attributes->reverse != attributes->cursor) {
|
||||||
background = attributes->foreground;
|
background = &attributes->foreground;
|
||||||
foreground = attributes->background;
|
foreground = &attributes->background;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
foreground = attributes->foreground;
|
foreground = &attributes->foreground;
|
||||||
background = attributes->background;
|
background = &attributes->background;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle bold */
|
/* Handle bold */
|
||||||
if (attributes->bold && foreground <= 7)
|
if (attributes->bold && foreground->palette_index >= 0
|
||||||
foreground += 8;
|
&& foreground->palette_index <= 7) {
|
||||||
|
foreground = &guac_terminal_palette[foreground->palette_index + 8];
|
||||||
|
}
|
||||||
|
|
||||||
display->glyph_foreground = foreground;
|
display->glyph_foreground = *foreground;
|
||||||
display->glyph_background = background;
|
display->glyph_background = *background;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -163,12 +166,10 @@ int __guac_terminal_set(guac_terminal_display* display, int row, int col, int co
|
|||||||
char utf8[4];
|
char utf8[4];
|
||||||
|
|
||||||
/* Use foreground color */
|
/* Use foreground color */
|
||||||
const guac_terminal_color* color =
|
const guac_terminal_color* color = &display->glyph_foreground;
|
||||||
&guac_terminal_palette[display->glyph_foreground];
|
|
||||||
|
|
||||||
/* Use background color */
|
/* Use background color */
|
||||||
const guac_terminal_color* background =
|
const guac_terminal_color* background = &display->glyph_background;
|
||||||
&guac_terminal_palette[display->glyph_background];
|
|
||||||
|
|
||||||
cairo_surface_t* surface;
|
cairo_surface_t* surface;
|
||||||
cairo_t* cairo;
|
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,
|
guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
|
||||||
const char* font_name, int font_size, int dpi,
|
const char* font_name, int font_size, int dpi,
|
||||||
int foreground, int background) {
|
guac_terminal_color* foreground, guac_terminal_color* background) {
|
||||||
|
|
||||||
PangoFontMap* font_map;
|
PangoFontMap* font_map;
|
||||||
PangoFont* font;
|
PangoFont* font;
|
||||||
@ -303,8 +304,8 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
display->default_foreground = display->glyph_foreground = foreground;
|
display->default_foreground = display->glyph_foreground = *foreground;
|
||||||
display->default_background = display->glyph_background = background;
|
display->default_background = display->glyph_background = *background;
|
||||||
|
|
||||||
/* Calculate character dimensions */
|
/* Calculate character dimensions */
|
||||||
display->char_width =
|
display->char_width =
|
||||||
@ -688,14 +689,11 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
|
|||||||
int rect_width, rect_height;
|
int rect_width, rect_height;
|
||||||
|
|
||||||
/* Color of the rectangle to draw */
|
/* Color of the rectangle to draw */
|
||||||
int color;
|
const guac_terminal_color* color;
|
||||||
if (current->character.attributes.reverse != current->character.attributes.cursor)
|
if (current->character.attributes.reverse != current->character.attributes.cursor)
|
||||||
color = current->character.attributes.foreground;
|
color = ¤t->character.attributes.foreground;
|
||||||
else
|
else
|
||||||
color = current->character.attributes.background;
|
color = ¤t->character.attributes.background;
|
||||||
|
|
||||||
const guac_terminal_color* guac_color =
|
|
||||||
&guac_terminal_palette[color];
|
|
||||||
|
|
||||||
/* Current row within a subrect */
|
/* Current row within a subrect */
|
||||||
guac_terminal_operation* rect_current_row;
|
guac_terminal_operation* rect_current_row;
|
||||||
@ -709,16 +707,16 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
|
|||||||
/* Find width */
|
/* Find width */
|
||||||
for (rect_col=col; rect_col<display->width; rect_col++) {
|
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)
|
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
|
else
|
||||||
joining_color = rect_current->character.attributes.background;
|
joining_color = &rect_current->character.attributes.background;
|
||||||
|
|
||||||
/* If not identical operation, stop */
|
/* If not identical operation, stop */
|
||||||
if (rect_current->type != GUAC_CHAR_SET
|
if (rect_current->type != GUAC_CHAR_SET
|
||||||
|| guac_terminal_has_glyph(rect_current->character.value)
|
|| guac_terminal_has_glyph(rect_current->character.value)
|
||||||
|| joining_color != color)
|
|| guac_terminal_colorcmp(joining_color, color) != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Next column */
|
/* 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++) {
|
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)
|
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
|
else
|
||||||
joining_color = rect_current->character.attributes.background;
|
joining_color = &rect_current->character.attributes.background;
|
||||||
|
|
||||||
/* Mark clear operations as NOP */
|
/* Mark clear operations as NOP */
|
||||||
if (rect_current->type == GUAC_CHAR_SET
|
if (rect_current->type == GUAC_CHAR_SET
|
||||||
&& !guac_terminal_has_glyph(rect_current->character.value)
|
&& !guac_terminal_has_glyph(rect_current->character.value)
|
||||||
&& joining_color == color)
|
&& guac_terminal_colorcmp(joining_color, color) == 0)
|
||||||
rect_current->type = GUAC_CHAR_NOP;
|
rect_current->type = GUAC_CHAR_NOP;
|
||||||
|
|
||||||
/* Next column */
|
/* Next column */
|
||||||
@ -783,7 +781,7 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
|
|||||||
row * display->char_height,
|
row * display->char_height,
|
||||||
rect_width * display->char_width,
|
rect_width * display->char_width,
|
||||||
rect_height * display->char_height,
|
rect_height * display->char_height,
|
||||||
guac_color->red, guac_color->green, guac_color->blue,
|
color->red, color->green, color->blue,
|
||||||
0xFF);
|
0xFF);
|
||||||
|
|
||||||
} /* end if clear operation */
|
} /* end if clear operation */
|
||||||
|
@ -205,8 +205,7 @@ static void guac_terminal_repaint_default_layer(guac_terminal* terminal,
|
|||||||
guac_terminal_display* display = terminal->display;
|
guac_terminal_display* display = terminal->display;
|
||||||
|
|
||||||
/* Get background color */
|
/* Get background color */
|
||||||
const guac_terminal_color* color =
|
const guac_terminal_color* color = &display->default_background;
|
||||||
&guac_terminal_palette[display->default_background];
|
|
||||||
|
|
||||||
/* Reset size */
|
/* Reset size */
|
||||||
guac_protocol_send_size(socket, GUAC_DEFAULT_LAYER, width, height);
|
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 = {
|
guac_terminal_char default_char = {
|
||||||
.value = 0,
|
.value = 0,
|
||||||
.attributes = {
|
.attributes = {
|
||||||
.foreground = default_foreground,
|
.foreground = guac_terminal_palette[default_foreground],
|
||||||
.background = default_background,
|
.background = guac_terminal_palette[default_background],
|
||||||
.bold = false,
|
.bold = false,
|
||||||
.reverse = false,
|
.reverse = false,
|
||||||
.underscore = false
|
.underscore = false
|
||||||
@ -326,8 +325,8 @@ guac_terminal* guac_terminal_create(guac_client* client,
|
|||||||
/* Init display */
|
/* Init display */
|
||||||
term->display = guac_terminal_display_alloc(client,
|
term->display = guac_terminal_display_alloc(client,
|
||||||
font_name, font_size, dpi,
|
font_name, font_size, dpi,
|
||||||
default_char.attributes.foreground,
|
&default_char.attributes.foreground,
|
||||||
default_char.attributes.background);
|
&default_char.attributes.background);
|
||||||
|
|
||||||
/* Fail if display init failed */
|
/* Fail if display init failed */
|
||||||
if (term->display == NULL) {
|
if (term->display == NULL) {
|
||||||
@ -875,17 +874,18 @@ static bool guac_terminal_is_visible(guac_terminal* term,
|
|||||||
if (guac_terminal_has_glyph(c->value))
|
if (guac_terminal_has_glyph(c->value))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
int background;
|
const guac_terminal_color* background;
|
||||||
|
|
||||||
/* Determine actual background color of character */
|
/* Determine actual background color of character */
|
||||||
if (c->attributes.reverse != c->attributes.cursor)
|
if (c->attributes.reverse != c->attributes.cursor)
|
||||||
background = c->attributes.foreground;
|
background = &c->attributes.foreground;
|
||||||
else
|
else
|
||||||
background = c->attributes.background;
|
background = &c->attributes.background;
|
||||||
|
|
||||||
/* Blank characters are visible if their background color differs from that
|
/* Blank characters are visible if their background color differs from that
|
||||||
* of the terminal */
|
* 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
|
#define _GUAC_TERMINAL_COMMON_H
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#include <stdbool.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);
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -220,22 +220,24 @@ typedef struct guac_terminal_display {
|
|||||||
/**
|
/**
|
||||||
* Default foreground color for all glyphs.
|
* Default foreground color for all glyphs.
|
||||||
*/
|
*/
|
||||||
int default_foreground;
|
guac_terminal_color default_foreground;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default background color for all glyphs and the terminal itself.
|
* 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.
|
* 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,
|
guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
|
||||||
const char* font_name, int font_size, int dpi,
|
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.
|
* Frees the given display.
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A character which is not truly a character, but rather part of an
|
* A character which is not truly a character, but rather part of an
|
||||||
@ -39,20 +40,26 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct guac_terminal_color {
|
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.
|
* The red component of this color.
|
||||||
*/
|
*/
|
||||||
int red;
|
uint8_t red;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The green component of this color.
|
* The green component of this color.
|
||||||
*/
|
*/
|
||||||
int green;
|
uint8_t green;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The blue component of this color.
|
* The blue component of this color.
|
||||||
*/
|
*/
|
||||||
int blue;
|
uint8_t blue;
|
||||||
|
|
||||||
} guac_terminal_color;
|
} guac_terminal_color;
|
||||||
|
|
||||||
@ -83,14 +90,14 @@ typedef struct guac_terminal_attributes {
|
|||||||
bool underscore;
|
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;
|
} guac_terminal_attributes;
|
||||||
|
|
||||||
|
@ -779,7 +779,8 @@ 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 = value - 30;
|
term->current_attributes.foreground =
|
||||||
|
guac_terminal_palette[value - 30];
|
||||||
|
|
||||||
/* Underscore on, default foreground */
|
/* Underscore on, default foreground */
|
||||||
else if (value == 38) {
|
else if (value == 38) {
|
||||||
@ -797,7 +798,8 @@ 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 = value - 40;
|
term->current_attributes.background =
|
||||||
|
guac_terminal_palette[value - 40];
|
||||||
|
|
||||||
/* Reset background */
|
/* Reset background */
|
||||||
else if (value == 49)
|
else if (value == 49)
|
||||||
|
Loading…
Reference in New Issue
Block a user