From 27cf97cb9e08e3ba4093c573b61c1a71e547c890 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 10 Jul 2017 21:38:12 -0700 Subject: [PATCH 1/2] GUACAMOLE-279: Handle xterm palette assignments, parsing each color as an X11 color spec. --- src/terminal/Makefile.am | 6 ++- src/terminal/terminal/xparsecolor.h | 48 +++++++++++++++++++ src/terminal/terminal_handlers.c | 73 ++++++++++++++++++++++++++++- src/terminal/xparsecolor.c | 70 +++++++++++++++++++++++++++ 4 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 src/terminal/terminal/xparsecolor.h create mode 100644 src/terminal/xparsecolor.c diff --git a/src/terminal/Makefile.am b/src/terminal/Makefile.am index b3474605..c7cedbba 100644 --- a/src/terminal/Makefile.am +++ b/src/terminal/Makefile.am @@ -32,7 +32,8 @@ noinst_HEADERS = \ terminal/terminal.h \ terminal/terminal_handlers.h \ terminal/types.h \ - terminal/typescript.h + terminal/typescript.h \ + terminal/xparsecolor.h libguac_terminal_la_SOURCES = \ buffer.c \ @@ -43,7 +44,8 @@ libguac_terminal_la_SOURCES = \ scrollbar.c \ terminal.c \ terminal_handlers.c \ - typescript.c + typescript.c \ + xparsecolor.c libguac_terminal_la_CFLAGS = \ -Werror -Wall \ diff --git a/src/terminal/terminal/xparsecolor.h b/src/terminal/terminal/xparsecolor.h new file mode 100644 index 00000000..7cb2fcaa --- /dev/null +++ b/src/terminal/terminal/xparsecolor.h @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef GUAC_TERMINAL_XPARSECOLOR_H +#define GUAC_TERMINAL_XPARSECOLOR_H + +#include "config.h" + +#include "terminal/palette.h" + +/** + * Parses an X11 color spec, as defined by Xlib's XParseColor(), storing the + * result in the provided guac_terminal_color structure. If the color spec is + * not valid, the provided guac_terminal_color is not touched. + * + * Currently, only the "rgb:*" format color specs are supported. + * + * @param spec + * The X11 color spec to parse. + * + * @param color + * A pointer to the guac_terminal_color structure which should receive the + * parsed result. + * + * @returns + * Zero if the color spec was successfully parsed, non-zero otherwise. + */ +int guac_terminal_xparsecolor(const char* spec, + guac_terminal_color* color); + +#endif + diff --git a/src/terminal/terminal_handlers.c b/src/terminal/terminal_handlers.c index 6f013a21..02e9f9df 100644 --- a/src/terminal/terminal_handlers.c +++ b/src/terminal/terminal_handlers.c @@ -24,6 +24,7 @@ #include "terminal/terminal.h" #include "terminal/terminal_handlers.h" #include "terminal/types.h" +#include "terminal/xparsecolor.h" #include #include @@ -1212,8 +1213,76 @@ int guac_terminal_window_title(guac_terminal* term, unsigned char c) { int guac_terminal_xterm_palette(guac_terminal* term, unsigned char c) { - /* NOTE: Currently unimplemented. Attempts to set the 256-color palette - * are ignored. */ + /** + * Whether we are currently reading the color spec. If false, we are + * currently reading the color index. + */ + static bool read_color_spec = false; + + /** + * The index of the palette entry being modified. + */ + static int index = 0; + + /** + * The color spec string, valid only if read_color_spec is true. + */ + static char color_spec[256]; + + /** + * The current position within the color spec string, valid only if + * read_color_spec is true. + */ + static int color_spec_pos = 0; + + /* If not reading the color spec, parse the index */ + if (!read_color_spec) { + + /* If digit, append to index */ + if (c >= '0' && c <= '9') + index = index * 10 + c - '0'; + + /* If end of parameter, switch to reading the color */ + else if (c == ';') { + read_color_spec = true; + color_spec_pos = 0; + } + + } + + /* Once the index has been parsed, read the color spec */ + else { + + /* Modify palette once index/spec pair has been read */ + if (c == ';' || c == 0x9C || c == 0x5C || c == 0x07) { + + guac_terminal_color color; + + /* Terminate color spec string */ + color_spec[color_spec_pos] = '\0'; + + /* Modify palette if color spec is valid */ + if (!guac_terminal_xparsecolor(color_spec, &color)) + guac_terminal_display_assign_color(term->display, + index, &color); + else + guac_client_log(term->client, GUAC_LOG_DEBUG, + "Invalid XParseColor() color spec: \"%s\"", + color_spec); + + /* Resume parsing index */ + read_color_spec = false; + index = 0; + + } + + /* Append characters to color spec as long as available space is not + * exceeded */ + else if (color_spec_pos < 255) { + color_spec[color_spec_pos++] = c; + } + + } /* Stop on ECMA-48 ST (String Terminator */ if (c == 0x9C || c == 0x5C || c == 0x07) diff --git a/src/terminal/xparsecolor.c b/src/terminal/xparsecolor.c new file mode 100644 index 00000000..740f2b41 --- /dev/null +++ b/src/terminal/xparsecolor.c @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "config.h" + +#include "terminal/named-colors.h" +#include "terminal/palette.h" + +#include + +int guac_terminal_xparsecolor(const char* spec, + guac_terminal_color* color) { + + int red; + int green; + int blue; + + /* 12-bit RGB ("rgb:h/h/h"), zero-padded to 24-bit */ + if (sscanf(spec, "rgb:%1x/%1x/%1x", &red, &green, &blue) == 3) { + color->red = red << 4; + color->green = green << 4; + color->blue = blue << 4; + return 0; + } + + /* 24-bit RGB ("rgb:hh/hh/hh") */ + if (sscanf(spec, "rgb:%2x/%2x/%2x", &red, &green, &blue) == 3) { + color->red = red; + color->green = green; + color->blue = blue; + return 0; + } + + /* 36-bit RGB ("rgb:hhh/hhh/hhh"), truncated to 24-bit */ + if (sscanf(spec, "rgb:%3x/%3x/%3x", &red, &green, &blue) == 3) { + color->red = red >> 4; + color->green = green >> 4; + color->blue = blue >> 4; + return 0; + } + + /* 48-bit RGB ("rgb:hhhh/hhhh/hhhh"), truncated to 24-bit */ + if (sscanf(spec, "rgb:%4x/%4x/%4x", &red, &green, &blue) == 3) { + color->red = red >> 8; + color->green = green >> 8; + color->blue = blue >> 8; + return 0; + } + + /* Invalid color spec */ + return 1; + +} + From b0d9bbc121d935e724ca90fad9641371c76abd79 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 10 Jul 2017 23:03:06 -0700 Subject: [PATCH 2/2] GUACAMOLE-279: Add explicit definitions for each human-readable xterm color. --- src/terminal/Makefile.am | 2 + src/terminal/named-colors.c | 797 +++++++++++++++++++++++++++ src/terminal/terminal/named-colors.h | 45 ++ src/terminal/xparsecolor.c | 4 +- 4 files changed, 846 insertions(+), 2 deletions(-) create mode 100644 src/terminal/named-colors.c create mode 100644 src/terminal/terminal/named-colors.h diff --git a/src/terminal/Makefile.am b/src/terminal/Makefile.am index c7cedbba..8121bd3e 100644 --- a/src/terminal/Makefile.am +++ b/src/terminal/Makefile.am @@ -27,6 +27,7 @@ noinst_HEADERS = \ terminal/char_mappings.h \ terminal/common.h \ terminal/display.h \ + terminal/named-colors.h \ terminal/palette.h \ terminal/scrollbar.h \ terminal/terminal.h \ @@ -40,6 +41,7 @@ libguac_terminal_la_SOURCES = \ char_mappings.c \ common.c \ display.c \ + named-colors.c \ palette.c \ scrollbar.c \ terminal.c \ diff --git a/src/terminal/named-colors.c b/src/terminal/named-colors.c new file mode 100644 index 00000000..89deee8b --- /dev/null +++ b/src/terminal/named-colors.c @@ -0,0 +1,797 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "config.h" +#include "terminal/palette.h" + +#include +#include + +/** + * A guac_terminal_color definition associated with a descriptive name. + */ +typedef struct guac_terminal_named_color { + + /** + * The color associated with the name. + */ + guac_terminal_color color; + + /** + * The name of the color. Each name must be lowercase and may not contain + * any whitespace. + */ + const char* name; + +} guac_terminal_named_color; + +/** + * An array of several colors and their corresponding names. This array must at + * least contain the color names accepted by xterm. + */ +const guac_terminal_named_color GUAC_TERMINAL_NAMED_COLORS[] = { + + /* Color names supported by xterm */ + + {{ -1, 0xF0, 0xF8, 0xFF }, "aliceblue" }, + {{ -1, 0xFA, 0xEB, 0xD7 }, "antiquewhite" }, + {{ -1, 0xFF, 0xEF, 0xDB }, "antiquewhite1" }, + {{ -1, 0xEE, 0xDF, 0xCC }, "antiquewhite2" }, + {{ -1, 0xCD, 0xC0, 0xB0 }, "antiquewhite3" }, + {{ -1, 0x8B, 0x83, 0x78 }, "antiquewhite4" }, + {{ -1, 0x00, 0xFF, 0xFF }, "aqua" }, + {{ -1, 0x7F, 0xFF, 0xD4 }, "aquamarine" }, + {{ -1, 0x7F, 0xFF, 0xD4 }, "aquamarine1" }, + {{ -1, 0x76, 0xEE, 0xC6 }, "aquamarine2" }, + {{ -1, 0x66, 0xCD, 0xAA }, "aquamarine3" }, + {{ -1, 0x45, 0x8B, 0x74 }, "aquamarine4" }, + {{ -1, 0xF0, 0xFF, 0xFF }, "azure" }, + {{ -1, 0xF0, 0xFF, 0xFF }, "azure1" }, + {{ -1, 0xE0, 0xEE, 0xEE }, "azure2" }, + {{ -1, 0xC1, 0xCD, 0xCD }, "azure3" }, + {{ -1, 0x83, 0x8B, 0x8B }, "azure4" }, + {{ -1, 0xF5, 0xF5, 0xDC }, "beige" }, + {{ -1, 0xFF, 0xE4, 0xC4 }, "bisque" }, + {{ -1, 0xFF, 0xE4, 0xC4 }, "bisque1" }, + {{ -1, 0xEE, 0xD5, 0xB7 }, "bisque2" }, + {{ -1, 0xCD, 0xB7, 0x9E }, "bisque3" }, + {{ -1, 0x8B, 0x7D, 0x6B }, "bisque4" }, + {{ -1, 0x00, 0x00, 0x00 }, "black" }, + {{ -1, 0xFF, 0xEB, 0xCD }, "blanchedalmond" }, + {{ -1, 0x00, 0x00, 0xFF }, "blue" }, + {{ -1, 0x00, 0x00, 0xFF }, "blue1" }, + {{ -1, 0x00, 0x00, 0xEE }, "blue2" }, + {{ -1, 0x00, 0x00, 0xCD }, "blue3" }, + {{ -1, 0x00, 0x00, 0x8B }, "blue4" }, + {{ -1, 0x8A, 0x2B, 0xE2 }, "blueviolet" }, + {{ -1, 0xA5, 0x2A, 0x2A }, "brown" }, + {{ -1, 0xFF, 0x40, 0x40 }, "brown1" }, + {{ -1, 0xEE, 0x3B, 0x3B }, "brown2" }, + {{ -1, 0xCD, 0x33, 0x33 }, "brown3" }, + {{ -1, 0x8B, 0x23, 0x23 }, "brown4" }, + {{ -1, 0xDE, 0xB8, 0x87 }, "burlywood" }, + {{ -1, 0xFF, 0xD3, 0x9B }, "burlywood1" }, + {{ -1, 0xEE, 0xC5, 0x91 }, "burlywood2" }, + {{ -1, 0xCD, 0xAA, 0x7D }, "burlywood3" }, + {{ -1, 0x8B, 0x73, 0x55 }, "burlywood4" }, + {{ -1, 0x5F, 0x9E, 0xA0 }, "cadetblue" }, + {{ -1, 0x98, 0xF5, 0xFF }, "cadetblue1" }, + {{ -1, 0x8E, 0xE5, 0xEE }, "cadetblue2" }, + {{ -1, 0x7A, 0xC5, 0xCD }, "cadetblue3" }, + {{ -1, 0x53, 0x86, 0x8B }, "cadetblue4" }, + {{ -1, 0x7F, 0xFF, 0x00 }, "chartreuse" }, + {{ -1, 0x7F, 0xFF, 0x00 }, "chartreuse1" }, + {{ -1, 0x76, 0xEE, 0x00 }, "chartreuse2" }, + {{ -1, 0x66, 0xCD, 0x00 }, "chartreuse3" }, + {{ -1, 0x45, 0x8B, 0x00 }, "chartreuse4" }, + {{ -1, 0xD2, 0x69, 0x1E }, "chocolate" }, + {{ -1, 0xFF, 0x7F, 0x24 }, "chocolate1" }, + {{ -1, 0xEE, 0x76, 0x21 }, "chocolate2" }, + {{ -1, 0xCD, 0x66, 0x1D }, "chocolate3" }, + {{ -1, 0x8B, 0x45, 0x13 }, "chocolate4" }, + {{ -1, 0xFF, 0x7F, 0x50 }, "coral" }, + {{ -1, 0xFF, 0x72, 0x56 }, "coral1" }, + {{ -1, 0xEE, 0x6A, 0x50 }, "coral2" }, + {{ -1, 0xCD, 0x5B, 0x45 }, "coral3" }, + {{ -1, 0x8B, 0x3E, 0x2F }, "coral4" }, + {{ -1, 0x64, 0x95, 0xED }, "cornflowerblue" }, + {{ -1, 0xFF, 0xF8, 0xDC }, "cornsilk" }, + {{ -1, 0xFF, 0xF8, 0xDC }, "cornsilk1" }, + {{ -1, 0xEE, 0xE8, 0xCD }, "cornsilk2" }, + {{ -1, 0xCD, 0xC8, 0xB1 }, "cornsilk3" }, + {{ -1, 0x8B, 0x88, 0x78 }, "cornsilk4" }, + {{ -1, 0xDC, 0x14, 0x3C }, "crimson" }, + {{ -1, 0x00, 0xFF, 0xFF }, "cyan" }, + {{ -1, 0x00, 0xFF, 0xFF }, "cyan1" }, + {{ -1, 0x00, 0xEE, 0xEE }, "cyan2" }, + {{ -1, 0x00, 0xCD, 0xCD }, "cyan3" }, + {{ -1, 0x00, 0x8B, 0x8B }, "cyan4" }, + {{ -1, 0x00, 0x00, 0x8B }, "darkblue" }, + {{ -1, 0x00, 0x8B, 0x8B }, "darkcyan" }, + {{ -1, 0xB8, 0x86, 0x0B }, "darkgoldenrod" }, + {{ -1, 0xFF, 0xB9, 0x0F }, "darkgoldenrod1" }, + {{ -1, 0xEE, 0xAD, 0x0E }, "darkgoldenrod2" }, + {{ -1, 0xCD, 0x95, 0x0C }, "darkgoldenrod3" }, + {{ -1, 0x8B, 0x65, 0x08 }, "darkgoldenrod4" }, + {{ -1, 0xA9, 0xA9, 0xA9 }, "darkgray" }, + {{ -1, 0x00, 0x64, 0x00 }, "darkgreen" }, + {{ -1, 0xA9, 0xA9, 0xA9 }, "darkgrey" }, + {{ -1, 0xBD, 0xB7, 0x6B }, "darkkhaki" }, + {{ -1, 0x8B, 0x00, 0x8B }, "darkmagenta" }, + {{ -1, 0x55, 0x6B, 0x2F }, "darkolivegreen" }, + {{ -1, 0xCA, 0xFF, 0x70 }, "darkolivegreen1" }, + {{ -1, 0xBC, 0xEE, 0x68 }, "darkolivegreen2" }, + {{ -1, 0xA2, 0xCD, 0x5A }, "darkolivegreen3" }, + {{ -1, 0x6E, 0x8B, 0x3D }, "darkolivegreen4" }, + {{ -1, 0xFF, 0x8C, 0x00 }, "darkorange" }, + {{ -1, 0xFF, 0x7F, 0x00 }, "darkorange1" }, + {{ -1, 0xEE, 0x76, 0x00 }, "darkorange2" }, + {{ -1, 0xCD, 0x66, 0x00 }, "darkorange3" }, + {{ -1, 0x8B, 0x45, 0x00 }, "darkorange4" }, + {{ -1, 0x99, 0x32, 0xCC }, "darkorchid" }, + {{ -1, 0xBF, 0x3E, 0xFF }, "darkorchid1" }, + {{ -1, 0xB2, 0x3A, 0xEE }, "darkorchid2" }, + {{ -1, 0x9A, 0x32, 0xCD }, "darkorchid3" }, + {{ -1, 0x68, 0x22, 0x8B }, "darkorchid4" }, + {{ -1, 0x8B, 0x00, 0x00 }, "darkred" }, + {{ -1, 0xE9, 0x96, 0x7A }, "darksalmon" }, + {{ -1, 0x8F, 0xBC, 0x8F }, "darkseagreen" }, + {{ -1, 0xC1, 0xFF, 0xC1 }, "darkseagreen1" }, + {{ -1, 0xB4, 0xEE, 0xB4 }, "darkseagreen2" }, + {{ -1, 0x9B, 0xCD, 0x9B }, "darkseagreen3" }, + {{ -1, 0x69, 0x8B, 0x69 }, "darkseagreen4" }, + {{ -1, 0x48, 0x3D, 0x8B }, "darkslateblue" }, + {{ -1, 0x2F, 0x4F, 0x4F }, "darkslategray" }, + {{ -1, 0x97, 0xFF, 0xFF }, "darkslategray1" }, + {{ -1, 0x8D, 0xEE, 0xEE }, "darkslategray2" }, + {{ -1, 0x79, 0xCD, 0xCD }, "darkslategray3" }, + {{ -1, 0x52, 0x8B, 0x8B }, "darkslategray4" }, + {{ -1, 0x2F, 0x4F, 0x4F }, "darkslategrey" }, + {{ -1, 0x00, 0xCE, 0xD1 }, "darkturquoise" }, + {{ -1, 0x94, 0x00, 0xD3 }, "darkviolet" }, + {{ -1, 0xFF, 0x14, 0x93 }, "deeppink" }, + {{ -1, 0xFF, 0x14, 0x93 }, "deeppink1" }, + {{ -1, 0xEE, 0x12, 0x89 }, "deeppink2" }, + {{ -1, 0xCD, 0x10, 0x76 }, "deeppink3" }, + {{ -1, 0x8B, 0x0A, 0x50 }, "deeppink4" }, + {{ -1, 0x00, 0xBF, 0xFF }, "deepskyblue" }, + {{ -1, 0x00, 0xBF, 0xFF }, "deepskyblue1" }, + {{ -1, 0x00, 0xB2, 0xEE }, "deepskyblue2" }, + {{ -1, 0x00, 0x9A, 0xCD }, "deepskyblue3" }, + {{ -1, 0x00, 0x68, 0x8B }, "deepskyblue4" }, + {{ -1, 0x69, 0x69, 0x69 }, "dimgray" }, + {{ -1, 0x69, 0x69, 0x69 }, "dimgrey" }, + {{ -1, 0x1E, 0x90, 0xFF }, "dodgerblue" }, + {{ -1, 0x1E, 0x90, 0xFF }, "dodgerblue1" }, + {{ -1, 0x1C, 0x86, 0xEE }, "dodgerblue2" }, + {{ -1, 0x18, 0x74, 0xCD }, "dodgerblue3" }, + {{ -1, 0x10, 0x4E, 0x8B }, "dodgerblue4" }, + {{ -1, 0xB2, 0x22, 0x22 }, "firebrick" }, + {{ -1, 0xFF, 0x30, 0x30 }, "firebrick1" }, + {{ -1, 0xEE, 0x2C, 0x2C }, "firebrick2" }, + {{ -1, 0xCD, 0x26, 0x26 }, "firebrick3" }, + {{ -1, 0x8B, 0x1A, 0x1A }, "firebrick4" }, + {{ -1, 0xFF, 0xFA, 0xF0 }, "floralwhite" }, + {{ -1, 0x22, 0x8B, 0x22 }, "forestgreen" }, + {{ -1, 0xFF, 0x00, 0xFF }, "fuchsia" }, + {{ -1, 0xDC, 0xDC, 0xDC }, "gainsboro" }, + {{ -1, 0xF8, 0xF8, 0xFF }, "ghostwhite" }, + {{ -1, 0xFF, 0xD7, 0x00 }, "gold" }, + {{ -1, 0xFF, 0xD7, 0x00 }, "gold1" }, + {{ -1, 0xEE, 0xC9, 0x00 }, "gold2" }, + {{ -1, 0xCD, 0xAD, 0x00 }, "gold3" }, + {{ -1, 0x8B, 0x75, 0x00 }, "gold4" }, + {{ -1, 0xDA, 0xA5, 0x20 }, "goldenrod" }, + {{ -1, 0xFF, 0xC1, 0x25 }, "goldenrod1" }, + {{ -1, 0xEE, 0xB4, 0x22 }, "goldenrod2" }, + {{ -1, 0xCD, 0x9B, 0x1D }, "goldenrod3" }, + {{ -1, 0x8B, 0x69, 0x14 }, "goldenrod4" }, + {{ -1, 0xBE, 0xBE, 0xBE }, "gray" }, + {{ -1, 0x00, 0x00, 0x00 }, "gray0" }, + {{ -1, 0x03, 0x03, 0x03 }, "gray1" }, + {{ -1, 0x1A, 0x1A, 0x1A }, "gray10" }, + {{ -1, 0xFF, 0xFF, 0xFF }, "gray100" }, + {{ -1, 0x1C, 0x1C, 0x1C }, "gray11" }, + {{ -1, 0x1F, 0x1F, 0x1F }, "gray12" }, + {{ -1, 0x21, 0x21, 0x21 }, "gray13" }, + {{ -1, 0x24, 0x24, 0x24 }, "gray14" }, + {{ -1, 0x26, 0x26, 0x26 }, "gray15" }, + {{ -1, 0x29, 0x29, 0x29 }, "gray16" }, + {{ -1, 0x2B, 0x2B, 0x2B }, "gray17" }, + {{ -1, 0x2E, 0x2E, 0x2E }, "gray18" }, + {{ -1, 0x30, 0x30, 0x30 }, "gray19" }, + {{ -1, 0x05, 0x05, 0x05 }, "gray2" }, + {{ -1, 0x33, 0x33, 0x33 }, "gray20" }, + {{ -1, 0x36, 0x36, 0x36 }, "gray21" }, + {{ -1, 0x38, 0x38, 0x38 }, "gray22" }, + {{ -1, 0x3B, 0x3B, 0x3B }, "gray23" }, + {{ -1, 0x3D, 0x3D, 0x3D }, "gray24" }, + {{ -1, 0x40, 0x40, 0x40 }, "gray25" }, + {{ -1, 0x42, 0x42, 0x42 }, "gray26" }, + {{ -1, 0x45, 0x45, 0x45 }, "gray27" }, + {{ -1, 0x47, 0x47, 0x47 }, "gray28" }, + {{ -1, 0x4A, 0x4A, 0x4A }, "gray29" }, + {{ -1, 0x08, 0x08, 0x08 }, "gray3" }, + {{ -1, 0x4D, 0x4D, 0x4D }, "gray30" }, + {{ -1, 0x4F, 0x4F, 0x4F }, "gray31" }, + {{ -1, 0x52, 0x52, 0x52 }, "gray32" }, + {{ -1, 0x54, 0x54, 0x54 }, "gray33" }, + {{ -1, 0x57, 0x57, 0x57 }, "gray34" }, + {{ -1, 0x59, 0x59, 0x59 }, "gray35" }, + {{ -1, 0x5C, 0x5C, 0x5C }, "gray36" }, + {{ -1, 0x5E, 0x5E, 0x5E }, "gray37" }, + {{ -1, 0x61, 0x61, 0x61 }, "gray38" }, + {{ -1, 0x63, 0x63, 0x63 }, "gray39" }, + {{ -1, 0x0A, 0x0A, 0x0A }, "gray4" }, + {{ -1, 0x66, 0x66, 0x66 }, "gray40" }, + {{ -1, 0x69, 0x69, 0x69 }, "gray41" }, + {{ -1, 0x6B, 0x6B, 0x6B }, "gray42" }, + {{ -1, 0x6E, 0x6E, 0x6E }, "gray43" }, + {{ -1, 0x70, 0x70, 0x70 }, "gray44" }, + {{ -1, 0x73, 0x73, 0x73 }, "gray45" }, + {{ -1, 0x75, 0x75, 0x75 }, "gray46" }, + {{ -1, 0x78, 0x78, 0x78 }, "gray47" }, + {{ -1, 0x7A, 0x7A, 0x7A }, "gray48" }, + {{ -1, 0x7D, 0x7D, 0x7D }, "gray49" }, + {{ -1, 0x0D, 0x0D, 0x0D }, "gray5" }, + {{ -1, 0x7F, 0x7F, 0x7F }, "gray50" }, + {{ -1, 0x82, 0x82, 0x82 }, "gray51" }, + {{ -1, 0x85, 0x85, 0x85 }, "gray52" }, + {{ -1, 0x87, 0x87, 0x87 }, "gray53" }, + {{ -1, 0x8A, 0x8A, 0x8A }, "gray54" }, + {{ -1, 0x8C, 0x8C, 0x8C }, "gray55" }, + {{ -1, 0x8F, 0x8F, 0x8F }, "gray56" }, + {{ -1, 0x91, 0x91, 0x91 }, "gray57" }, + {{ -1, 0x94, 0x94, 0x94 }, "gray58" }, + {{ -1, 0x96, 0x96, 0x96 }, "gray59" }, + {{ -1, 0x0F, 0x0F, 0x0F }, "gray6" }, + {{ -1, 0x99, 0x99, 0x99 }, "gray60" }, + {{ -1, 0x9C, 0x9C, 0x9C }, "gray61" }, + {{ -1, 0x9E, 0x9E, 0x9E }, "gray62" }, + {{ -1, 0xA1, 0xA1, 0xA1 }, "gray63" }, + {{ -1, 0xA3, 0xA3, 0xA3 }, "gray64" }, + {{ -1, 0xA6, 0xA6, 0xA6 }, "gray65" }, + {{ -1, 0xA8, 0xA8, 0xA8 }, "gray66" }, + {{ -1, 0xAB, 0xAB, 0xAB }, "gray67" }, + {{ -1, 0xAD, 0xAD, 0xAD }, "gray68" }, + {{ -1, 0xB0, 0xB0, 0xB0 }, "gray69" }, + {{ -1, 0x12, 0x12, 0x12 }, "gray7" }, + {{ -1, 0xB3, 0xB3, 0xB3 }, "gray70" }, + {{ -1, 0xB5, 0xB5, 0xB5 }, "gray71" }, + {{ -1, 0xB8, 0xB8, 0xB8 }, "gray72" }, + {{ -1, 0xBA, 0xBA, 0xBA }, "gray73" }, + {{ -1, 0xBD, 0xBD, 0xBD }, "gray74" }, + {{ -1, 0xBF, 0xBF, 0xBF }, "gray75" }, + {{ -1, 0xC2, 0xC2, 0xC2 }, "gray76" }, + {{ -1, 0xC4, 0xC4, 0xC4 }, "gray77" }, + {{ -1, 0xC7, 0xC7, 0xC7 }, "gray78" }, + {{ -1, 0xC9, 0xC9, 0xC9 }, "gray79" }, + {{ -1, 0x14, 0x14, 0x14 }, "gray8" }, + {{ -1, 0xCC, 0xCC, 0xCC }, "gray80" }, + {{ -1, 0xCF, 0xCF, 0xCF }, "gray81" }, + {{ -1, 0xD1, 0xD1, 0xD1 }, "gray82" }, + {{ -1, 0xD4, 0xD4, 0xD4 }, "gray83" }, + {{ -1, 0xD6, 0xD6, 0xD6 }, "gray84" }, + {{ -1, 0xD9, 0xD9, 0xD9 }, "gray85" }, + {{ -1, 0xDB, 0xDB, 0xDB }, "gray86" }, + {{ -1, 0xDE, 0xDE, 0xDE }, "gray87" }, + {{ -1, 0xE0, 0xE0, 0xE0 }, "gray88" }, + {{ -1, 0xE3, 0xE3, 0xE3 }, "gray89" }, + {{ -1, 0x17, 0x17, 0x17 }, "gray9" }, + {{ -1, 0xE5, 0xE5, 0xE5 }, "gray90" }, + {{ -1, 0xE8, 0xE8, 0xE8 }, "gray91" }, + {{ -1, 0xEB, 0xEB, 0xEB }, "gray92" }, + {{ -1, 0xED, 0xED, 0xED }, "gray93" }, + {{ -1, 0xF0, 0xF0, 0xF0 }, "gray94" }, + {{ -1, 0xF2, 0xF2, 0xF2 }, "gray95" }, + {{ -1, 0xF5, 0xF5, 0xF5 }, "gray96" }, + {{ -1, 0xF7, 0xF7, 0xF7 }, "gray97" }, + {{ -1, 0xFA, 0xFA, 0xFA }, "gray98" }, + {{ -1, 0xFC, 0xFC, 0xFC }, "gray99" }, + {{ -1, 0x00, 0xFF, 0x00 }, "green" }, + {{ -1, 0x00, 0xFF, 0x00 }, "green1" }, + {{ -1, 0x00, 0xEE, 0x00 }, "green2" }, + {{ -1, 0x00, 0xCD, 0x00 }, "green3" }, + {{ -1, 0x00, 0x8B, 0x00 }, "green4" }, + {{ -1, 0xAD, 0xFF, 0x2F }, "greenyellow" }, + {{ -1, 0xBE, 0xBE, 0xBE }, "grey" }, + {{ -1, 0x00, 0x00, 0x00 }, "grey0" }, + {{ -1, 0x03, 0x03, 0x03 }, "grey1" }, + {{ -1, 0x1A, 0x1A, 0x1A }, "grey10" }, + {{ -1, 0xFF, 0xFF, 0xFF }, "grey100" }, + {{ -1, 0x1C, 0x1C, 0x1C }, "grey11" }, + {{ -1, 0x1F, 0x1F, 0x1F }, "grey12" }, + {{ -1, 0x21, 0x21, 0x21 }, "grey13" }, + {{ -1, 0x24, 0x24, 0x24 }, "grey14" }, + {{ -1, 0x26, 0x26, 0x26 }, "grey15" }, + {{ -1, 0x29, 0x29, 0x29 }, "grey16" }, + {{ -1, 0x2B, 0x2B, 0x2B }, "grey17" }, + {{ -1, 0x2E, 0x2E, 0x2E }, "grey18" }, + {{ -1, 0x30, 0x30, 0x30 }, "grey19" }, + {{ -1, 0x05, 0x05, 0x05 }, "grey2" }, + {{ -1, 0x33, 0x33, 0x33 }, "grey20" }, + {{ -1, 0x36, 0x36, 0x36 }, "grey21" }, + {{ -1, 0x38, 0x38, 0x38 }, "grey22" }, + {{ -1, 0x3B, 0x3B, 0x3B }, "grey23" }, + {{ -1, 0x3D, 0x3D, 0x3D }, "grey24" }, + {{ -1, 0x40, 0x40, 0x40 }, "grey25" }, + {{ -1, 0x42, 0x42, 0x42 }, "grey26" }, + {{ -1, 0x45, 0x45, 0x45 }, "grey27" }, + {{ -1, 0x47, 0x47, 0x47 }, "grey28" }, + {{ -1, 0x4A, 0x4A, 0x4A }, "grey29" }, + {{ -1, 0x08, 0x08, 0x08 }, "grey3" }, + {{ -1, 0x4D, 0x4D, 0x4D }, "grey30" }, + {{ -1, 0x4F, 0x4F, 0x4F }, "grey31" }, + {{ -1, 0x52, 0x52, 0x52 }, "grey32" }, + {{ -1, 0x54, 0x54, 0x54 }, "grey33" }, + {{ -1, 0x57, 0x57, 0x57 }, "grey34" }, + {{ -1, 0x59, 0x59, 0x59 }, "grey35" }, + {{ -1, 0x5C, 0x5C, 0x5C }, "grey36" }, + {{ -1, 0x5E, 0x5E, 0x5E }, "grey37" }, + {{ -1, 0x61, 0x61, 0x61 }, "grey38" }, + {{ -1, 0x63, 0x63, 0x63 }, "grey39" }, + {{ -1, 0x0A, 0x0A, 0x0A }, "grey4" }, + {{ -1, 0x66, 0x66, 0x66 }, "grey40" }, + {{ -1, 0x69, 0x69, 0x69 }, "grey41" }, + {{ -1, 0x6B, 0x6B, 0x6B }, "grey42" }, + {{ -1, 0x6E, 0x6E, 0x6E }, "grey43" }, + {{ -1, 0x70, 0x70, 0x70 }, "grey44" }, + {{ -1, 0x73, 0x73, 0x73 }, "grey45" }, + {{ -1, 0x75, 0x75, 0x75 }, "grey46" }, + {{ -1, 0x78, 0x78, 0x78 }, "grey47" }, + {{ -1, 0x7A, 0x7A, 0x7A }, "grey48" }, + {{ -1, 0x7D, 0x7D, 0x7D }, "grey49" }, + {{ -1, 0x0D, 0x0D, 0x0D }, "grey5" }, + {{ -1, 0x7F, 0x7F, 0x7F }, "grey50" }, + {{ -1, 0x82, 0x82, 0x82 }, "grey51" }, + {{ -1, 0x85, 0x85, 0x85 }, "grey52" }, + {{ -1, 0x87, 0x87, 0x87 }, "grey53" }, + {{ -1, 0x8A, 0x8A, 0x8A }, "grey54" }, + {{ -1, 0x8C, 0x8C, 0x8C }, "grey55" }, + {{ -1, 0x8F, 0x8F, 0x8F }, "grey56" }, + {{ -1, 0x91, 0x91, 0x91 }, "grey57" }, + {{ -1, 0x94, 0x94, 0x94 }, "grey58" }, + {{ -1, 0x96, 0x96, 0x96 }, "grey59" }, + {{ -1, 0x0F, 0x0F, 0x0F }, "grey6" }, + {{ -1, 0x99, 0x99, 0x99 }, "grey60" }, + {{ -1, 0x9C, 0x9C, 0x9C }, "grey61" }, + {{ -1, 0x9E, 0x9E, 0x9E }, "grey62" }, + {{ -1, 0xA1, 0xA1, 0xA1 }, "grey63" }, + {{ -1, 0xA3, 0xA3, 0xA3 }, "grey64" }, + {{ -1, 0xA6, 0xA6, 0xA6 }, "grey65" }, + {{ -1, 0xA8, 0xA8, 0xA8 }, "grey66" }, + {{ -1, 0xAB, 0xAB, 0xAB }, "grey67" }, + {{ -1, 0xAD, 0xAD, 0xAD }, "grey68" }, + {{ -1, 0xB0, 0xB0, 0xB0 }, "grey69" }, + {{ -1, 0x12, 0x12, 0x12 }, "grey7" }, + {{ -1, 0xB3, 0xB3, 0xB3 }, "grey70" }, + {{ -1, 0xB5, 0xB5, 0xB5 }, "grey71" }, + {{ -1, 0xB8, 0xB8, 0xB8 }, "grey72" }, + {{ -1, 0xBA, 0xBA, 0xBA }, "grey73" }, + {{ -1, 0xBD, 0xBD, 0xBD }, "grey74" }, + {{ -1, 0xBF, 0xBF, 0xBF }, "grey75" }, + {{ -1, 0xC2, 0xC2, 0xC2 }, "grey76" }, + {{ -1, 0xC4, 0xC4, 0xC4 }, "grey77" }, + {{ -1, 0xC7, 0xC7, 0xC7 }, "grey78" }, + {{ -1, 0xC9, 0xC9, 0xC9 }, "grey79" }, + {{ -1, 0x14, 0x14, 0x14 }, "grey8" }, + {{ -1, 0xCC, 0xCC, 0xCC }, "grey80" }, + {{ -1, 0xCF, 0xCF, 0xCF }, "grey81" }, + {{ -1, 0xD1, 0xD1, 0xD1 }, "grey82" }, + {{ -1, 0xD4, 0xD4, 0xD4 }, "grey83" }, + {{ -1, 0xD6, 0xD6, 0xD6 }, "grey84" }, + {{ -1, 0xD9, 0xD9, 0xD9 }, "grey85" }, + {{ -1, 0xDB, 0xDB, 0xDB }, "grey86" }, + {{ -1, 0xDE, 0xDE, 0xDE }, "grey87" }, + {{ -1, 0xE0, 0xE0, 0xE0 }, "grey88" }, + {{ -1, 0xE3, 0xE3, 0xE3 }, "grey89" }, + {{ -1, 0x17, 0x17, 0x17 }, "grey9" }, + {{ -1, 0xE5, 0xE5, 0xE5 }, "grey90" }, + {{ -1, 0xE8, 0xE8, 0xE8 }, "grey91" }, + {{ -1, 0xEB, 0xEB, 0xEB }, "grey92" }, + {{ -1, 0xED, 0xED, 0xED }, "grey93" }, + {{ -1, 0xF0, 0xF0, 0xF0 }, "grey94" }, + {{ -1, 0xF2, 0xF2, 0xF2 }, "grey95" }, + {{ -1, 0xF5, 0xF5, 0xF5 }, "grey96" }, + {{ -1, 0xF7, 0xF7, 0xF7 }, "grey97" }, + {{ -1, 0xFA, 0xFA, 0xFA }, "grey98" }, + {{ -1, 0xFC, 0xFC, 0xFC }, "grey99" }, + {{ -1, 0xF0, 0xFF, 0xF0 }, "honeydew" }, + {{ -1, 0xF0, 0xFF, 0xF0 }, "honeydew1" }, + {{ -1, 0xE0, 0xEE, 0xE0 }, "honeydew2" }, + {{ -1, 0xC1, 0xCD, 0xC1 }, "honeydew3" }, + {{ -1, 0x83, 0x8B, 0x83 }, "honeydew4" }, + {{ -1, 0xFF, 0x69, 0xB4 }, "hotpink" }, + {{ -1, 0xFF, 0x6E, 0xB4 }, "hotpink1" }, + {{ -1, 0xEE, 0x6A, 0xA7 }, "hotpink2" }, + {{ -1, 0xCD, 0x60, 0x90 }, "hotpink3" }, + {{ -1, 0x8B, 0x3A, 0x62 }, "hotpink4" }, + {{ -1, 0xCD, 0x5C, 0x5C }, "indianred" }, + {{ -1, 0xFF, 0x6A, 0x6A }, "indianred1" }, + {{ -1, 0xEE, 0x63, 0x63 }, "indianred2" }, + {{ -1, 0xCD, 0x55, 0x55 }, "indianred3" }, + {{ -1, 0x8B, 0x3A, 0x3A }, "indianred4" }, + {{ -1, 0x4B, 0x00, 0x82 }, "indigo" }, + {{ -1, 0xFF, 0xFF, 0xF0 }, "ivory" }, + {{ -1, 0xFF, 0xFF, 0xF0 }, "ivory1" }, + {{ -1, 0xEE, 0xEE, 0xE0 }, "ivory2" }, + {{ -1, 0xCD, 0xCD, 0xC1 }, "ivory3" }, + {{ -1, 0x8B, 0x8B, 0x83 }, "ivory4" }, + {{ -1, 0xF0, 0xE6, 0x8C }, "khaki" }, + {{ -1, 0xFF, 0xF6, 0x8F }, "khaki1" }, + {{ -1, 0xEE, 0xE6, 0x85 }, "khaki2" }, + {{ -1, 0xCD, 0xC6, 0x73 }, "khaki3" }, + {{ -1, 0x8B, 0x86, 0x4E }, "khaki4" }, + {{ -1, 0xE6, 0xE6, 0xFA }, "lavender" }, + {{ -1, 0xFF, 0xF0, 0xF5 }, "lavenderblush" }, + {{ -1, 0xFF, 0xF0, 0xF5 }, "lavenderblush1" }, + {{ -1, 0xEE, 0xE0, 0xE5 }, "lavenderblush2" }, + {{ -1, 0xCD, 0xC1, 0xC5 }, "lavenderblush3" }, + {{ -1, 0x8B, 0x83, 0x86 }, "lavenderblush4" }, + {{ -1, 0x7C, 0xFC, 0x00 }, "lawngreen" }, + {{ -1, 0xFF, 0xFA, 0xCD }, "lemonchiffon" }, + {{ -1, 0xFF, 0xFA, 0xCD }, "lemonchiffon1" }, + {{ -1, 0xEE, 0xE9, 0xBF }, "lemonchiffon2" }, + {{ -1, 0xCD, 0xC9, 0xA5 }, "lemonchiffon3" }, + {{ -1, 0x8B, 0x89, 0x70 }, "lemonchiffon4" }, + {{ -1, 0xAD, 0xD8, 0xE6 }, "lightblue" }, + {{ -1, 0xBF, 0xEF, 0xFF }, "lightblue1" }, + {{ -1, 0xB2, 0xDF, 0xEE }, "lightblue2" }, + {{ -1, 0x9A, 0xC0, 0xCD }, "lightblue3" }, + {{ -1, 0x68, 0x83, 0x8B }, "lightblue4" }, + {{ -1, 0xF0, 0x80, 0x80 }, "lightcoral" }, + {{ -1, 0xE0, 0xFF, 0xFF }, "lightcyan" }, + {{ -1, 0xE0, 0xFF, 0xFF }, "lightcyan1" }, + {{ -1, 0xD1, 0xEE, 0xEE }, "lightcyan2" }, + {{ -1, 0xB4, 0xCD, 0xCD }, "lightcyan3" }, + {{ -1, 0x7A, 0x8B, 0x8B }, "lightcyan4" }, + {{ -1, 0xEE, 0xDD, 0x82 }, "lightgoldenrod" }, + {{ -1, 0xFF, 0xEC, 0x8B }, "lightgoldenrod1" }, + {{ -1, 0xEE, 0xDC, 0x82 }, "lightgoldenrod2" }, + {{ -1, 0xCD, 0xBE, 0x70 }, "lightgoldenrod3" }, + {{ -1, 0x8B, 0x81, 0x4C }, "lightgoldenrod4" }, + {{ -1, 0xFA, 0xFA, 0xD2 }, "lightgoldenrodyellow" }, + {{ -1, 0xD3, 0xD3, 0xD3 }, "lightgray" }, + {{ -1, 0x90, 0xEE, 0x90 }, "lightgreen" }, + {{ -1, 0xD3, 0xD3, 0xD3 }, "lightgrey" }, + {{ -1, 0xFF, 0xB6, 0xC1 }, "lightpink" }, + {{ -1, 0xFF, 0xAE, 0xB9 }, "lightpink1" }, + {{ -1, 0xEE, 0xA2, 0xAD }, "lightpink2" }, + {{ -1, 0xCD, 0x8C, 0x95 }, "lightpink3" }, + {{ -1, 0x8B, 0x5F, 0x65 }, "lightpink4" }, + {{ -1, 0xFF, 0xA0, 0x7A }, "lightsalmon" }, + {{ -1, 0xFF, 0xA0, 0x7A }, "lightsalmon1" }, + {{ -1, 0xEE, 0x95, 0x72 }, "lightsalmon2" }, + {{ -1, 0xCD, 0x81, 0x62 }, "lightsalmon3" }, + {{ -1, 0x8B, 0x57, 0x42 }, "lightsalmon4" }, + {{ -1, 0x20, 0xB2, 0xAA }, "lightseagreen" }, + {{ -1, 0x87, 0xCE, 0xFA }, "lightskyblue" }, + {{ -1, 0xB0, 0xE2, 0xFF }, "lightskyblue1" }, + {{ -1, 0xA4, 0xD3, 0xEE }, "lightskyblue2" }, + {{ -1, 0x8D, 0xB6, 0xCD }, "lightskyblue3" }, + {{ -1, 0x60, 0x7B, 0x8B }, "lightskyblue4" }, + {{ -1, 0x84, 0x70, 0xFF }, "lightslateblue" }, + {{ -1, 0x77, 0x88, 0x99 }, "lightslategray" }, + {{ -1, 0x77, 0x88, 0x99 }, "lightslategrey" }, + {{ -1, 0xB0, 0xC4, 0xDE }, "lightsteelblue" }, + {{ -1, 0xCA, 0xE1, 0xFF }, "lightsteelblue1" }, + {{ -1, 0xBC, 0xD2, 0xEE }, "lightsteelblue2" }, + {{ -1, 0xA2, 0xB5, 0xCD }, "lightsteelblue3" }, + {{ -1, 0x6E, 0x7B, 0x8B }, "lightsteelblue4" }, + {{ -1, 0xFF, 0xFF, 0xE0 }, "lightyellow" }, + {{ -1, 0xFF, 0xFF, 0xE0 }, "lightyellow1" }, + {{ -1, 0xEE, 0xEE, 0xD1 }, "lightyellow2" }, + {{ -1, 0xCD, 0xCD, 0xB4 }, "lightyellow3" }, + {{ -1, 0x8B, 0x8B, 0x7A }, "lightyellow4" }, + {{ -1, 0x00, 0xFF, 0x00 }, "lime" }, + {{ -1, 0x32, 0xCD, 0x32 }, "limegreen" }, + {{ -1, 0xFA, 0xF0, 0xE6 }, "linen" }, + {{ -1, 0xFF, 0x00, 0xFF }, "magenta" }, + {{ -1, 0xFF, 0x00, 0xFF }, "magenta1" }, + {{ -1, 0xEE, 0x00, 0xEE }, "magenta2" }, + {{ -1, 0xCD, 0x00, 0xCD }, "magenta3" }, + {{ -1, 0x8B, 0x00, 0x8B }, "magenta4" }, + {{ -1, 0xB0, 0x30, 0x60 }, "maroon" }, + {{ -1, 0xFF, 0x34, 0xB3 }, "maroon1" }, + {{ -1, 0xEE, 0x30, 0xA7 }, "maroon2" }, + {{ -1, 0xCD, 0x29, 0x90 }, "maroon3" }, + {{ -1, 0x8B, 0x1C, 0x62 }, "maroon4" }, + {{ -1, 0x66, 0xCD, 0xAA }, "mediumaquamarine" }, + {{ -1, 0x00, 0x00, 0xCD }, "mediumblue" }, + {{ -1, 0xBA, 0x55, 0xD3 }, "mediumorchid" }, + {{ -1, 0xE0, 0x66, 0xFF }, "mediumorchid1" }, + {{ -1, 0xD1, 0x5F, 0xEE }, "mediumorchid2" }, + {{ -1, 0xB4, 0x52, 0xCD }, "mediumorchid3" }, + {{ -1, 0x7A, 0x37, 0x8B }, "mediumorchid4" }, + {{ -1, 0x93, 0x70, 0xDB }, "mediumpurple" }, + {{ -1, 0xAB, 0x82, 0xFF }, "mediumpurple1" }, + {{ -1, 0x9F, 0x79, 0xEE }, "mediumpurple2" }, + {{ -1, 0x89, 0x68, 0xCD }, "mediumpurple3" }, + {{ -1, 0x5D, 0x47, 0x8B }, "mediumpurple4" }, + {{ -1, 0x3C, 0xB3, 0x71 }, "mediumseagreen" }, + {{ -1, 0x7B, 0x68, 0xEE }, "mediumslateblue" }, + {{ -1, 0x00, 0xFA, 0x9A }, "mediumspringgreen" }, + {{ -1, 0x48, 0xD1, 0xCC }, "mediumturquoise" }, + {{ -1, 0xC7, 0x15, 0x85 }, "mediumvioletred" }, + {{ -1, 0x19, 0x19, 0x70 }, "midnightblue" }, + {{ -1, 0xF5, 0xFF, 0xFA }, "mintcream" }, + {{ -1, 0xFF, 0xE4, 0xE1 }, "mistyrose" }, + {{ -1, 0xFF, 0xE4, 0xE1 }, "mistyrose1" }, + {{ -1, 0xEE, 0xD5, 0xD2 }, "mistyrose2" }, + {{ -1, 0xCD, 0xB7, 0xB5 }, "mistyrose3" }, + {{ -1, 0x8B, 0x7D, 0x7B }, "mistyrose4" }, + {{ -1, 0xFF, 0xE4, 0xB5 }, "moccasin" }, + {{ -1, 0xFF, 0xDE, 0xAD }, "navajowhite" }, + {{ -1, 0xFF, 0xDE, 0xAD }, "navajowhite1" }, + {{ -1, 0xEE, 0xCF, 0xA1 }, "navajowhite2" }, + {{ -1, 0xCD, 0xB3, 0x8B }, "navajowhite3" }, + {{ -1, 0x8B, 0x79, 0x5E }, "navajowhite4" }, + {{ -1, 0x00, 0x00, 0x80 }, "navy" }, + {{ -1, 0x00, 0x00, 0x80 }, "navyblue" }, + {{ -1, 0xFD, 0xF5, 0xE6 }, "oldlace" }, + {{ -1, 0x80, 0x80, 0x00 }, "olive" }, + {{ -1, 0x6B, 0x8E, 0x23 }, "olivedrab" }, + {{ -1, 0xC0, 0xFF, 0x3E }, "olivedrab1" }, + {{ -1, 0xB3, 0xEE, 0x3A }, "olivedrab2" }, + {{ -1, 0x9A, 0xCD, 0x32 }, "olivedrab3" }, + {{ -1, 0x69, 0x8B, 0x22 }, "olivedrab4" }, + {{ -1, 0xFF, 0xA5, 0x00 }, "orange" }, + {{ -1, 0xFF, 0xA5, 0x00 }, "orange1" }, + {{ -1, 0xEE, 0x9A, 0x00 }, "orange2" }, + {{ -1, 0xCD, 0x85, 0x00 }, "orange3" }, + {{ -1, 0x8B, 0x5A, 0x00 }, "orange4" }, + {{ -1, 0xFF, 0x45, 0x00 }, "orangered" }, + {{ -1, 0xFF, 0x45, 0x00 }, "orangered1" }, + {{ -1, 0xEE, 0x40, 0x00 }, "orangered2" }, + {{ -1, 0xCD, 0x37, 0x00 }, "orangered3" }, + {{ -1, 0x8B, 0x25, 0x00 }, "orangered4" }, + {{ -1, 0xDA, 0x70, 0xD6 }, "orchid" }, + {{ -1, 0xFF, 0x83, 0xFA }, "orchid1" }, + {{ -1, 0xEE, 0x7A, 0xE9 }, "orchid2" }, + {{ -1, 0xCD, 0x69, 0xC9 }, "orchid3" }, + {{ -1, 0x8B, 0x47, 0x89 }, "orchid4" }, + {{ -1, 0xEE, 0xE8, 0xAA }, "palegoldenrod" }, + {{ -1, 0x98, 0xFB, 0x98 }, "palegreen" }, + {{ -1, 0x9A, 0xFF, 0x9A }, "palegreen1" }, + {{ -1, 0x90, 0xEE, 0x90 }, "palegreen2" }, + {{ -1, 0x7C, 0xCD, 0x7C }, "palegreen3" }, + {{ -1, 0x54, 0x8B, 0x54 }, "palegreen4" }, + {{ -1, 0xAF, 0xEE, 0xEE }, "paleturquoise" }, + {{ -1, 0xBB, 0xFF, 0xFF }, "paleturquoise1" }, + {{ -1, 0xAE, 0xEE, 0xEE }, "paleturquoise2" }, + {{ -1, 0x96, 0xCD, 0xCD }, "paleturquoise3" }, + {{ -1, 0x66, 0x8B, 0x8B }, "paleturquoise4" }, + {{ -1, 0xDB, 0x70, 0x93 }, "palevioletred" }, + {{ -1, 0xFF, 0x82, 0xAB }, "palevioletred1" }, + {{ -1, 0xEE, 0x79, 0x9F }, "palevioletred2" }, + {{ -1, 0xCD, 0x68, 0x89 }, "palevioletred3" }, + {{ -1, 0x8B, 0x47, 0x5D }, "palevioletred4" }, + {{ -1, 0xFF, 0xEF, 0xD5 }, "papayawhip" }, + {{ -1, 0xFF, 0xDA, 0xB9 }, "peachpuff" }, + {{ -1, 0xFF, 0xDA, 0xB9 }, "peachpuff1" }, + {{ -1, 0xEE, 0xCB, 0xAD }, "peachpuff2" }, + {{ -1, 0xCD, 0xAF, 0x95 }, "peachpuff3" }, + {{ -1, 0x8B, 0x77, 0x65 }, "peachpuff4" }, + {{ -1, 0xCD, 0x85, 0x3F }, "peru" }, + {{ -1, 0xFF, 0xC0, 0xCB }, "pink" }, + {{ -1, 0xFF, 0xB5, 0xC5 }, "pink1" }, + {{ -1, 0xEE, 0xA9, 0xB8 }, "pink2" }, + {{ -1, 0xCD, 0x91, 0x9E }, "pink3" }, + {{ -1, 0x8B, 0x63, 0x6C }, "pink4" }, + {{ -1, 0xDD, 0xA0, 0xDD }, "plum" }, + {{ -1, 0xFF, 0xBB, 0xFF }, "plum1" }, + {{ -1, 0xEE, 0xAE, 0xEE }, "plum2" }, + {{ -1, 0xCD, 0x96, 0xCD }, "plum3" }, + {{ -1, 0x8B, 0x66, 0x8B }, "plum4" }, + {{ -1, 0xB0, 0xE0, 0xE6 }, "powderblue" }, + {{ -1, 0xA0, 0x20, 0xF0 }, "purple" }, + {{ -1, 0x9B, 0x30, 0xFF }, "purple1" }, + {{ -1, 0x91, 0x2C, 0xEE }, "purple2" }, + {{ -1, 0x7D, 0x26, 0xCD }, "purple3" }, + {{ -1, 0x55, 0x1A, 0x8B }, "purple4" }, + {{ -1, 0x66, 0x33, 0x99 }, "rebeccapurple" }, + {{ -1, 0xFF, 0x00, 0x00 }, "red" }, + {{ -1, 0xFF, 0x00, 0x00 }, "red1" }, + {{ -1, 0xEE, 0x00, 0x00 }, "red2" }, + {{ -1, 0xCD, 0x00, 0x00 }, "red3" }, + {{ -1, 0x8B, 0x00, 0x00 }, "red4" }, + {{ -1, 0xBC, 0x8F, 0x8F }, "rosybrown" }, + {{ -1, 0xFF, 0xC1, 0xC1 }, "rosybrown1" }, + {{ -1, 0xEE, 0xB4, 0xB4 }, "rosybrown2" }, + {{ -1, 0xCD, 0x9B, 0x9B }, "rosybrown3" }, + {{ -1, 0x8B, 0x69, 0x69 }, "rosybrown4" }, + {{ -1, 0x41, 0x69, 0xE1 }, "royalblue" }, + {{ -1, 0x48, 0x76, 0xFF }, "royalblue1" }, + {{ -1, 0x43, 0x6E, 0xEE }, "royalblue2" }, + {{ -1, 0x3A, 0x5F, 0xCD }, "royalblue3" }, + {{ -1, 0x27, 0x40, 0x8B }, "royalblue4" }, + {{ -1, 0x8B, 0x45, 0x13 }, "saddlebrown" }, + {{ -1, 0xFA, 0x80, 0x72 }, "salmon" }, + {{ -1, 0xFF, 0x8C, 0x69 }, "salmon1" }, + {{ -1, 0xEE, 0x82, 0x62 }, "salmon2" }, + {{ -1, 0xCD, 0x70, 0x54 }, "salmon3" }, + {{ -1, 0x8B, 0x4C, 0x39 }, "salmon4" }, + {{ -1, 0xF4, 0xA4, 0x60 }, "sandybrown" }, + {{ -1, 0x2E, 0x8B, 0x57 }, "seagreen" }, + {{ -1, 0x54, 0xFF, 0x9F }, "seagreen1" }, + {{ -1, 0x4E, 0xEE, 0x94 }, "seagreen2" }, + {{ -1, 0x43, 0xCD, 0x80 }, "seagreen3" }, + {{ -1, 0x2E, 0x8B, 0x57 }, "seagreen4" }, + {{ -1, 0xFF, 0xF5, 0xEE }, "seashell" }, + {{ -1, 0xFF, 0xF5, 0xEE }, "seashell1" }, + {{ -1, 0xEE, 0xE5, 0xDE }, "seashell2" }, + {{ -1, 0xCD, 0xC5, 0xBF }, "seashell3" }, + {{ -1, 0x8B, 0x86, 0x82 }, "seashell4" }, + {{ -1, 0xA0, 0x52, 0x2D }, "sienna" }, + {{ -1, 0xFF, 0x82, 0x47 }, "sienna1" }, + {{ -1, 0xEE, 0x79, 0x42 }, "sienna2" }, + {{ -1, 0xCD, 0x68, 0x39 }, "sienna3" }, + {{ -1, 0x8B, 0x47, 0x26 }, "sienna4" }, + {{ -1, 0xC0, 0xC0, 0xC0 }, "silver" }, + {{ -1, 0x87, 0xCE, 0xEB }, "skyblue" }, + {{ -1, 0x87, 0xCE, 0xFF }, "skyblue1" }, + {{ -1, 0x7E, 0xC0, 0xEE }, "skyblue2" }, + {{ -1, 0x6C, 0xA6, 0xCD }, "skyblue3" }, + {{ -1, 0x4A, 0x70, 0x8B }, "skyblue4" }, + {{ -1, 0x6A, 0x5A, 0xCD }, "slateblue" }, + {{ -1, 0x83, 0x6F, 0xFF }, "slateblue1" }, + {{ -1, 0x7A, 0x67, 0xEE }, "slateblue2" }, + {{ -1, 0x69, 0x59, 0xCD }, "slateblue3" }, + {{ -1, 0x47, 0x3C, 0x8B }, "slateblue4" }, + {{ -1, 0x70, 0x80, 0x90 }, "slategray" }, + {{ -1, 0xC6, 0xE2, 0xFF }, "slategray1" }, + {{ -1, 0xB9, 0xD3, 0xEE }, "slategray2" }, + {{ -1, 0x9F, 0xB6, 0xCD }, "slategray3" }, + {{ -1, 0x6C, 0x7B, 0x8B }, "slategray4" }, + {{ -1, 0x70, 0x80, 0x90 }, "slategrey" }, + {{ -1, 0xFF, 0xFA, 0xFA }, "snow" }, + {{ -1, 0xFF, 0xFA, 0xFA }, "snow1" }, + {{ -1, 0xEE, 0xE9, 0xE9 }, "snow2" }, + {{ -1, 0xCD, 0xC9, 0xC9 }, "snow3" }, + {{ -1, 0x8B, 0x89, 0x89 }, "snow4" }, + {{ -1, 0x00, 0xFF, 0x7F }, "springgreen" }, + {{ -1, 0x00, 0xFF, 0x7F }, "springgreen1" }, + {{ -1, 0x00, 0xEE, 0x76 }, "springgreen2" }, + {{ -1, 0x00, 0xCD, 0x66 }, "springgreen3" }, + {{ -1, 0x00, 0x8B, 0x45 }, "springgreen4" }, + {{ -1, 0x46, 0x82, 0xB4 }, "steelblue" }, + {{ -1, 0x63, 0xB8, 0xFF }, "steelblue1" }, + {{ -1, 0x5C, 0xAC, 0xEE }, "steelblue2" }, + {{ -1, 0x4F, 0x94, 0xCD }, "steelblue3" }, + {{ -1, 0x36, 0x64, 0x8B }, "steelblue4" }, + {{ -1, 0xD2, 0xB4, 0x8C }, "tan" }, + {{ -1, 0xFF, 0xA5, 0x4F }, "tan1" }, + {{ -1, 0xEE, 0x9A, 0x49 }, "tan2" }, + {{ -1, 0xCD, 0x85, 0x3F }, "tan3" }, + {{ -1, 0x8B, 0x5A, 0x2B }, "tan4" }, + {{ -1, 0x00, 0x80, 0x80 }, "teal" }, + {{ -1, 0xD8, 0xBF, 0xD8 }, "thistle" }, + {{ -1, 0xFF, 0xE1, 0xFF }, "thistle1" }, + {{ -1, 0xEE, 0xD2, 0xEE }, "thistle2" }, + {{ -1, 0xCD, 0xB5, 0xCD }, "thistle3" }, + {{ -1, 0x8B, 0x7B, 0x8B }, "thistle4" }, + {{ -1, 0xFF, 0x63, 0x47 }, "tomato" }, + {{ -1, 0xFF, 0x63, 0x47 }, "tomato1" }, + {{ -1, 0xEE, 0x5C, 0x42 }, "tomato2" }, + {{ -1, 0xCD, 0x4F, 0x39 }, "tomato3" }, + {{ -1, 0x8B, 0x36, 0x26 }, "tomato4" }, + {{ -1, 0x40, 0xE0, 0xD0 }, "turquoise" }, + {{ -1, 0x00, 0xF5, 0xFF }, "turquoise1" }, + {{ -1, 0x00, 0xE5, 0xEE }, "turquoise2" }, + {{ -1, 0x00, 0xC5, 0xCD }, "turquoise3" }, + {{ -1, 0x00, 0x86, 0x8B }, "turquoise4" }, + {{ -1, 0xEE, 0x82, 0xEE }, "violet" }, + {{ -1, 0xD0, 0x20, 0x90 }, "violetred" }, + {{ -1, 0xFF, 0x3E, 0x96 }, "violetred1" }, + {{ -1, 0xEE, 0x3A, 0x8C }, "violetred2" }, + {{ -1, 0xCD, 0x32, 0x78 }, "violetred3" }, + {{ -1, 0x8B, 0x22, 0x52 }, "violetred4" }, + {{ -1, 0x80, 0x80, 0x80 }, "webgray" }, + {{ -1, 0x00, 0x80, 0x00 }, "webgreen" }, + {{ -1, 0x80, 0x80, 0x80 }, "webgrey" }, + {{ -1, 0x80, 0x00, 0x00 }, "webmaroon" }, + {{ -1, 0x80, 0x00, 0x80 }, "webpurple" }, + {{ -1, 0xF5, 0xDE, 0xB3 }, "wheat" }, + {{ -1, 0xFF, 0xE7, 0xBA }, "wheat1" }, + {{ -1, 0xEE, 0xD8, 0xAE }, "wheat2" }, + {{ -1, 0xCD, 0xBA, 0x96 }, "wheat3" }, + {{ -1, 0x8B, 0x7E, 0x66 }, "wheat4" }, + {{ -1, 0xFF, 0xFF, 0xFF }, "white" }, + {{ -1, 0xF5, 0xF5, 0xF5 }, "whitesmoke" }, + {{ -1, 0xBE, 0xBE, 0xBE }, "x11gray" }, + {{ -1, 0x00, 0xFF, 0x00 }, "x11green" }, + {{ -1, 0xBE, 0xBE, 0xBE }, "x11grey" }, + {{ -1, 0xB0, 0x30, 0x60 }, "x11maroon" }, + {{ -1, 0xA0, 0x20, 0xF0 }, "x11purple" }, + {{ -1, 0xFF, 0xFF, 0x00 }, "yellow" }, + {{ -1, 0xFF, 0xFF, 0x00 }, "yellow1" }, + {{ -1, 0xEE, 0xEE, 0x00 }, "yellow2" }, + {{ -1, 0xCD, 0xCD, 0x00 }, "yellow3" }, + {{ -1, 0x8B, 0x8B, 0x00 }, "yellow4" }, + {{ -1, 0x9A, 0xCD, 0x32 }, "yellowgreen" } + +}; + +/** + * The number of elements within the GUAC_TERMINAL_NAMED_COLORS array. + */ +#define GUAC_TERMINAL_NAMED_COLORS_LENGTH \ + (sizeof(GUAC_TERMINAL_NAMED_COLORS) / sizeof(guac_terminal_named_color)) + +/** + * Compares the string search key given to bsearch() with the name of a + * guac_terminal_named_color, ignoring case and whitespace. + * + * @param a + * A pointer to a string containing the search key (color name). + * + * @param b + * A pointer to a guac_terminal_named_color structure whose name should be + * compared against the search key. + * + * @returns + * Zero if the search key and color name are identical, a negative value if + * the search key sorts before the color name, or a positive value if the + * search key sorts after the color name. + */ +static int guac_terminal_named_color_search(const void* a, const void* b) { + + const char* key = (const char*) a; + const char* name = ((const guac_terminal_named_color*) b)->name; + + /* For each corresponding character pair in each string */ + for (; *key && *name; key++, name++) { + + /* Skip any spaces in key (name will never have spaces) */ + while (*key && isspace(*key)) key++; + + /* Compare, ignoring case (name is already known to be lowercase) */ + int difference = tolower(*key) - *name; + if (difference) + return difference; + + } + + /* If we haven't reached the end of name yet, key is shorter */ + if (*name) + return -1; + + /* The strings are identical */ + return 0; + +} + +int guac_terminal_find_color(const char* name, guac_terminal_color* color) { + + /* Search for the color having the given name */ + guac_terminal_named_color* found = bsearch(name, + GUAC_TERMINAL_NAMED_COLORS, GUAC_TERMINAL_NAMED_COLORS_LENGTH, + sizeof(guac_terminal_named_color), + guac_terminal_named_color_search); + + /* Fail if no such color is found */ + if (color == NULL) + return 1; + + /* Otherwise copy the found color */ + *color = found->color; + return 0; + +} + diff --git a/src/terminal/terminal/named-colors.h b/src/terminal/terminal/named-colors.h new file mode 100644 index 00000000..675bf124 --- /dev/null +++ b/src/terminal/terminal/named-colors.h @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef GUAC_TERMINAL_NAMED_COLORS_H +#define GUAC_TERMINAL_NAMED_COLORS_H + +#include "config.h" +#include "terminal/palette.h" + +/** + * Searches for the color having the given name, storing that color within the + * given guac_terminal_color structure if found. If the color cannot be found, + * the guac_terminal_color structure is not touched. All color names supported + * by xterm are recognized by this function. + * + * @param name + * The name of the color to search for. + * + * @param color + * A pointer to the guac_terminal_color structure in which the found color + * should be stored. + * + * @returns + * Zero if the color was successfully found, non-zero otherwise. + */ +int guac_terminal_find_color(const char* name, guac_terminal_color* color); + +#endif + diff --git a/src/terminal/xparsecolor.c b/src/terminal/xparsecolor.c index 740f2b41..5aa1fd4c 100644 --- a/src/terminal/xparsecolor.c +++ b/src/terminal/xparsecolor.c @@ -63,8 +63,8 @@ int guac_terminal_xparsecolor(const char* spec, return 0; } - /* Invalid color spec */ - return 1; + /* If not RGB, search for color by name */ + return guac_terminal_find_color(spec, color); }