1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
5  * Copyright (c) 2016 Avi Halachmi <avihpit@yahoo.com>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 
27 #include "tmux.h"
28 
29 static int
colour_dist_sq(int R,int G,int B,int r,int g,int b)30 colour_dist_sq(int R, int G, int B, int r, int g, int b)
31 {
32           return ((R - r) * (R - r) + (G - g) * (G - g) + (B - b) * (B - b));
33 }
34 
35 static int
colour_to_6cube(int v)36 colour_to_6cube(int v)
37 {
38           if (v < 48)
39                     return (0);
40           if (v < 114)
41                     return (1);
42           return ((v - 35) / 40);
43 }
44 
45 /*
46  * Convert an RGB triplet to the xterm(1) 256 colour palette.
47  *
48  * xterm provides a 6x6x6 colour cube (16 - 231) and 24 greys (232 - 255). We
49  * map our RGB colour to the closest in the cube, also work out the closest
50  * grey, and use the nearest of the two.
51  *
52  * Note that the xterm has much lower resolution for darker colours (they are
53  * not evenly spread out), so our 6 levels are not evenly spread: 0x0, 0x5f
54  * (95), 0x87 (135), 0xaf (175), 0xd7 (215) and 0xff (255). Greys are more
55  * evenly spread (8, 18, 28 ... 238).
56  */
57 int
colour_find_rgb(u_char r,u_char g,u_char b)58 colour_find_rgb(u_char r, u_char g, u_char b)
59 {
60           static const int    q2c[6] = { 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff };
61           int                           qr, qg, qb, cr, cg, cb, d, idx;
62           int                           grey_avg, grey_idx, grey;
63 
64           /* Map RGB to 6x6x6 cube. */
65           qr = colour_to_6cube(r); cr = q2c[qr];
66           qg = colour_to_6cube(g); cg = q2c[qg];
67           qb = colour_to_6cube(b); cb = q2c[qb];
68 
69           /* If we have hit the colour exactly, return early. */
70           if (cr == r && cg == g && cb == b)
71                     return ((16 + (36 * qr) + (6 * qg) + qb) | COLOUR_FLAG_256);
72 
73           /* Work out the closest grey (average of RGB). */
74           grey_avg = (r + g + b) / 3;
75           if (grey_avg > 238)
76                     grey_idx = 23;
77           else
78                     grey_idx = (grey_avg - 3) / 10;
79           grey = 8 + (10 * grey_idx);
80 
81           /* Is grey or 6x6x6 colour closest? */
82           d = colour_dist_sq(cr, cg, cb, r, g, b);
83           if (colour_dist_sq(grey, grey, grey, r, g, b) < d)
84                     idx = 232 + grey_idx;
85           else
86                     idx = 16 + (36 * qr) + (6 * qg) + qb;
87           return (idx | COLOUR_FLAG_256);
88 }
89 
90 /* Join RGB into a colour. */
91 int
colour_join_rgb(u_char r,u_char g,u_char b)92 colour_join_rgb(u_char r, u_char g, u_char b)
93 {
94           return ((((int)((r) & 0xff)) << 16) |
95               (((int)((g) & 0xff)) << 8) |
96               (((int)((b) & 0xff))) | COLOUR_FLAG_RGB);
97 }
98 
99 /* Split colour into RGB. */
100 void
colour_split_rgb(int c,u_char * r,u_char * g,u_char * b)101 colour_split_rgb(int c, u_char *r, u_char *g, u_char *b)
102 {
103           *r = (c >> 16) & 0xff;
104           *g = (c >> 8) & 0xff;
105           *b = c & 0xff;
106 }
107 
108 /* Force colour to RGB if not already. */
109 int
colour_force_rgb(int c)110 colour_force_rgb(int c)
111 {
112           if (c & COLOUR_FLAG_RGB)
113                     return (c);
114           if (c & COLOUR_FLAG_256)
115                     return (colour_256toRGB(c));
116           if (c >= 0 && c <= 7)
117                     return (colour_256toRGB(c));
118           if (c >= 90 && c <= 97)
119                     return (colour_256toRGB(8 + c - 90));
120           return (-1);
121 }
122 
123 /* Convert colour to a string. */
124 const char *
colour_tostring(int c)125 colour_tostring(int c)
126 {
127           static char         s[32];
128           u_char              r, g, b;
129 
130           if (c == -1)
131                     return ("none");
132 
133           if (c & COLOUR_FLAG_RGB) {
134                     colour_split_rgb(c, &r, &g, &b);
135                     xsnprintf(s, sizeof s, "#%02x%02x%02x", r, g, b);
136                     return (s);
137           }
138 
139           if (c & COLOUR_FLAG_256) {
140                     xsnprintf(s, sizeof s, "colour%u", c & 0xff);
141                     return (s);
142           }
143 
144           switch (c) {
145           case 0:
146                     return ("black");
147           case 1:
148                     return ("red");
149           case 2:
150                     return ("green");
151           case 3:
152                     return ("yellow");
153           case 4:
154                     return ("blue");
155           case 5:
156                     return ("magenta");
157           case 6:
158                     return ("cyan");
159           case 7:
160                     return ("white");
161           case 8:
162                     return ("default");
163           case 9:
164                     return ("terminal");
165           case 90:
166                     return ("brightblack");
167           case 91:
168                     return ("brightred");
169           case 92:
170                     return ("brightgreen");
171           case 93:
172                     return ("brightyellow");
173           case 94:
174                     return ("brightblue");
175           case 95:
176                     return ("brightmagenta");
177           case 96:
178                     return ("brightcyan");
179           case 97:
180                     return ("brightwhite");
181           }
182           return ("invalid");
183 }
184 
185 /* Convert colour from string. */
186 int
colour_fromstring(const char * s)187 colour_fromstring(const char *s)
188 {
189           const char          *errstr;
190           const char          *cp;
191           int                  n;
192           u_char               r, g, b;
193 
194           if (*s == '#' && strlen(s) == 7) {
195                     for (cp = s + 1; isxdigit((u_char) *cp); cp++)
196                               ;
197                     if (*cp != '\0')
198                               return (-1);
199                     n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &r, &g, &b);
200                     if (n != 3)
201                               return (-1);
202                     return (colour_join_rgb(r, g, b));
203           }
204 
205           if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
206                     n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr);
207                     if (errstr != NULL)
208                               return (-1);
209                     return (n | COLOUR_FLAG_256);
210           }
211           if (strncasecmp(s, "color", (sizeof "color") - 1) == 0) {
212                     n = strtonum(s + (sizeof "color") - 1, 0, 255, &errstr);
213                     if (errstr != NULL)
214                               return (-1);
215                     return (n | COLOUR_FLAG_256);
216           }
217 
218           if (strcasecmp(s, "default") == 0)
219                     return (8);
220           if (strcasecmp(s, "terminal") == 0)
221                     return (9);
222 
223           if (strcasecmp(s, "black") == 0 || strcmp(s, "0") == 0)
224                     return (0);
225           if (strcasecmp(s, "red") == 0 || strcmp(s, "1") == 0)
226                     return (1);
227           if (strcasecmp(s, "green") == 0 || strcmp(s, "2") == 0)
228                     return (2);
229           if (strcasecmp(s, "yellow") == 0 || strcmp(s, "3") == 0)
230                     return (3);
231           if (strcasecmp(s, "blue") == 0 || strcmp(s, "4") == 0)
232                     return (4);
233           if (strcasecmp(s, "magenta") == 0 || strcmp(s, "5") == 0)
234                     return (5);
235           if (strcasecmp(s, "cyan") == 0 || strcmp(s, "6") == 0)
236                     return (6);
237           if (strcasecmp(s, "white") == 0 || strcmp(s, "7") == 0)
238                     return (7);
239           if (strcasecmp(s, "brightblack") == 0 || strcmp(s, "90") == 0)
240                     return (90);
241           if (strcasecmp(s, "brightred") == 0 || strcmp(s, "91") == 0)
242                     return (91);
243           if (strcasecmp(s, "brightgreen") == 0 || strcmp(s, "92") == 0)
244                     return (92);
245           if (strcasecmp(s, "brightyellow") == 0 || strcmp(s, "93") == 0)
246                     return (93);
247           if (strcasecmp(s, "brightblue") == 0 || strcmp(s, "94") == 0)
248                     return (94);
249           if (strcasecmp(s, "brightmagenta") == 0 || strcmp(s, "95") == 0)
250                     return (95);
251           if (strcasecmp(s, "brightcyan") == 0 || strcmp(s, "96") == 0)
252                     return (96);
253           if (strcasecmp(s, "brightwhite") == 0 || strcmp(s, "97") == 0)
254                     return (97);
255           return (colour_byname(s));
256 }
257 
258 /* Convert 256 colour to RGB colour. */
259 int
colour_256toRGB(int c)260 colour_256toRGB(int c)
261 {
262           static const int table[256] = {
263                     0x000000, 0x800000, 0x008000, 0x808000,
264                     0x000080, 0x800080, 0x008080, 0xc0c0c0,
265                     0x808080, 0xff0000, 0x00ff00, 0xffff00,
266                     0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
267                     0x000000, 0x00005f, 0x000087, 0x0000af,
268                     0x0000d7, 0x0000ff, 0x005f00, 0x005f5f,
269                     0x005f87, 0x005faf, 0x005fd7, 0x005fff,
270                     0x008700, 0x00875f, 0x008787, 0x0087af,
271                     0x0087d7, 0x0087ff, 0x00af00, 0x00af5f,
272                     0x00af87, 0x00afaf, 0x00afd7, 0x00afff,
273                     0x00d700, 0x00d75f, 0x00d787, 0x00d7af,
274                     0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f,
275                     0x00ff87, 0x00ffaf, 0x00ffd7, 0x00ffff,
276                     0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af,
277                     0x5f00d7, 0x5f00ff, 0x5f5f00, 0x5f5f5f,
278                     0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff,
279                     0x5f8700, 0x5f875f, 0x5f8787, 0x5f87af,
280                     0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f,
281                     0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff,
282                     0x5fd700, 0x5fd75f, 0x5fd787, 0x5fd7af,
283                     0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f,
284                     0x5fff87, 0x5fffaf, 0x5fffd7, 0x5fffff,
285                     0x870000, 0x87005f, 0x870087, 0x8700af,
286                     0x8700d7, 0x8700ff, 0x875f00, 0x875f5f,
287                     0x875f87, 0x875faf, 0x875fd7, 0x875fff,
288                     0x878700, 0x87875f, 0x878787, 0x8787af,
289                     0x8787d7, 0x8787ff, 0x87af00, 0x87af5f,
290                     0x87af87, 0x87afaf, 0x87afd7, 0x87afff,
291                     0x87d700, 0x87d75f, 0x87d787, 0x87d7af,
292                     0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f,
293                     0x87ff87, 0x87ffaf, 0x87ffd7, 0x87ffff,
294                     0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af,
295                     0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f,
296                     0xaf5f87, 0xaf5faf, 0xaf5fd7, 0xaf5fff,
297                     0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af,
298                     0xaf87d7, 0xaf87ff, 0xafaf00, 0xafaf5f,
299                     0xafaf87, 0xafafaf, 0xafafd7, 0xafafff,
300                     0xafd700, 0xafd75f, 0xafd787, 0xafd7af,
301                     0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f,
302                     0xafff87, 0xafffaf, 0xafffd7, 0xafffff,
303                     0xd70000, 0xd7005f, 0xd70087, 0xd700af,
304                     0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f,
305                     0xd75f87, 0xd75faf, 0xd75fd7, 0xd75fff,
306                     0xd78700, 0xd7875f, 0xd78787, 0xd787af,
307                     0xd787d7, 0xd787ff, 0xd7af00, 0xd7af5f,
308                     0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff,
309                     0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af,
310                     0xd7d7d7, 0xd7d7ff, 0xd7ff00, 0xd7ff5f,
311                     0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff,
312                     0xff0000, 0xff005f, 0xff0087, 0xff00af,
313                     0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f,
314                     0xff5f87, 0xff5faf, 0xff5fd7, 0xff5fff,
315                     0xff8700, 0xff875f, 0xff8787, 0xff87af,
316                     0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f,
317                     0xffaf87, 0xffafaf, 0xffafd7, 0xffafff,
318                     0xffd700, 0xffd75f, 0xffd787, 0xffd7af,
319                     0xffd7d7, 0xffd7ff, 0xffff00, 0xffff5f,
320                     0xffff87, 0xffffaf, 0xffffd7, 0xffffff,
321                     0x080808, 0x121212, 0x1c1c1c, 0x262626,
322                     0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e,
323                     0x585858, 0x626262, 0x6c6c6c, 0x767676,
324                     0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e,
325                     0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6,
326                     0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee
327           };
328 
329           return (table[c & 0xff] | COLOUR_FLAG_RGB);
330 }
331 
332 /* Convert 256 colour to 16 colour. */
333 int
colour_256to16(int c)334 colour_256to16(int c)
335 {
336           static const char table[256] = {
337                      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
338                      0,  4,  4,  4, 12, 12,  2,  6,  4,  4, 12, 12,  2,  2,  6,  4,
339                     12, 12,  2,  2,  2,  6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
340                     10, 10, 10, 14,  1,  5,  4,  4, 12, 12,  3,  8,  4,  4, 12, 12,
341                      2,  2,  6,  4, 12, 12,  2,  2,  2,  6, 12, 12, 10, 10, 10, 10,
342                     14, 12, 10, 10, 10, 10, 10, 14,  1,  1,  5,  4, 12, 12,  1,  1,
343                      5,  4, 12, 12,  3,  3,  8,  4, 12, 12,  2,  2,  2,  6, 12, 12,
344                     10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,  1,  1,  1,  5,
345                     12, 12,  1,  1,  1,  5, 12, 12,  1,  1,  1,  5, 12, 12,  3,  3,
346                      3,  7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,
347                      9,  9,  9,  9, 13, 12,  9,  9,  9,  9, 13, 12,  9,  9,  9,  9,
348                     13, 12,  9,  9,  9,  9, 13, 12, 11, 11, 11, 11,  7, 12, 10, 10,
349                     10, 10, 10, 14,  9,  9,  9,  9,  9, 13,  9,  9,  9,  9,  9, 13,
350                      9,  9,  9,  9,  9, 13,  9,  9,  9,  9,  9, 13,  9,  9,  9,  9,
351                      9, 13, 11, 11, 11, 11, 11, 15,  0,  0,  0,  0,  0,  0,  8,  8,
352                      8,  8,  8,  8,  7,  7,  7,  7,  7,  7, 15, 15, 15, 15, 15, 15
353           };
354 
355           return (table[c & 0xff]);
356 }
357 
358 /* Get colour by X11 colour name. */
359 int
colour_byname(const char * name)360 colour_byname(const char *name)
361 {
362           static const struct {
363                     const char          *name;
364                     int                  c;
365           } colours[] = {
366                     { "AliceBlue", 0xf0f8ff },
367                     { "AntiqueWhite", 0xfaebd7 },
368                     { "AntiqueWhite1", 0xffefdb },
369                     { "AntiqueWhite2", 0xeedfcc },
370                     { "AntiqueWhite3", 0xcdc0b0 },
371                     { "AntiqueWhite4", 0x8b8378 },
372                     { "BlanchedAlmond", 0xffebcd },
373                     { "BlueViolet", 0x8a2be2 },
374                     { "CadetBlue", 0x5f9ea0 },
375                     { "CadetBlue1", 0x98f5ff },
376                     { "CadetBlue2", 0x8ee5ee },
377                     { "CadetBlue3", 0x7ac5cd },
378                     { "CadetBlue4", 0x53868b },
379                     { "CornflowerBlue", 0x6495ed },
380                     { "DarkBlue", 0x00008b },
381                     { "DarkCyan", 0x008b8b },
382                     { "DarkGoldenrod", 0xb8860b },
383                     { "DarkGoldenrod1", 0xffb90f },
384                     { "DarkGoldenrod2", 0xeead0e },
385                     { "DarkGoldenrod3", 0xcd950c },
386                     { "DarkGoldenrod4", 0x8b6508 },
387                     { "DarkGray", 0xa9a9a9 },
388                     { "DarkGreen", 0x006400 },
389                     { "DarkGrey", 0xa9a9a9 },
390                     { "DarkKhaki", 0xbdb76b },
391                     { "DarkMagenta", 0x8b008b },
392                     { "DarkOliveGreen", 0x556b2f },
393                     { "DarkOliveGreen1", 0xcaff70 },
394                     { "DarkOliveGreen2", 0xbcee68 },
395                     { "DarkOliveGreen3", 0xa2cd5a },
396                     { "DarkOliveGreen4", 0x6e8b3d },
397                     { "DarkOrange", 0xff8c00 },
398                     { "DarkOrange1", 0xff7f00 },
399                     { "DarkOrange2", 0xee7600 },
400                     { "DarkOrange3", 0xcd6600 },
401                     { "DarkOrange4", 0x8b4500 },
402                     { "DarkOrchid", 0x9932cc },
403                     { "DarkOrchid1", 0xbf3eff },
404                     { "DarkOrchid2", 0xb23aee },
405                     { "DarkOrchid3", 0x9a32cd },
406                     { "DarkOrchid4", 0x68228b },
407                     { "DarkRed", 0x8b0000 },
408                     { "DarkSalmon", 0xe9967a },
409                     { "DarkSeaGreen", 0x8fbc8f },
410                     { "DarkSeaGreen1", 0xc1ffc1 },
411                     { "DarkSeaGreen2", 0xb4eeb4 },
412                     { "DarkSeaGreen3", 0x9bcd9b },
413                     { "DarkSeaGreen4", 0x698b69 },
414                     { "DarkSlateBlue", 0x483d8b },
415                     { "DarkSlateGray", 0x2f4f4f },
416                     { "DarkSlateGray1", 0x97ffff },
417                     { "DarkSlateGray2", 0x8deeee },
418                     { "DarkSlateGray3", 0x79cdcd },
419                     { "DarkSlateGray4", 0x528b8b },
420                     { "DarkSlateGrey", 0x2f4f4f },
421                     { "DarkTurquoise", 0x00ced1 },
422                     { "DarkViolet", 0x9400d3 },
423                     { "DeepPink", 0xff1493 },
424                     { "DeepPink1", 0xff1493 },
425                     { "DeepPink2", 0xee1289 },
426                     { "DeepPink3", 0xcd1076 },
427                     { "DeepPink4", 0x8b0a50 },
428                     { "DeepSkyBlue", 0x00bfff },
429                     { "DeepSkyBlue1", 0x00bfff },
430                     { "DeepSkyBlue2", 0x00b2ee },
431                     { "DeepSkyBlue3", 0x009acd },
432                     { "DeepSkyBlue4", 0x00688b },
433                     { "DimGray", 0x696969 },
434                     { "DimGrey", 0x696969 },
435                     { "DodgerBlue", 0x1e90ff },
436                     { "DodgerBlue1", 0x1e90ff },
437                     { "DodgerBlue2", 0x1c86ee },
438                     { "DodgerBlue3", 0x1874cd },
439                     { "DodgerBlue4", 0x104e8b },
440                     { "FloralWhite", 0xfffaf0 },
441                     { "ForestGreen", 0x228b22 },
442                     { "GhostWhite", 0xf8f8ff },
443                     { "GreenYellow", 0xadff2f },
444                     { "HotPink", 0xff69b4 },
445                     { "HotPink1", 0xff6eb4 },
446                     { "HotPink2", 0xee6aa7 },
447                     { "HotPink3", 0xcd6090 },
448                     { "HotPink4", 0x8b3a62 },
449                     { "IndianRed", 0xcd5c5c },
450                     { "IndianRed1", 0xff6a6a },
451                     { "IndianRed2", 0xee6363 },
452                     { "IndianRed3", 0xcd5555 },
453                     { "IndianRed4", 0x8b3a3a },
454                     { "LavenderBlush", 0xfff0f5 },
455                     { "LavenderBlush1", 0xfff0f5 },
456                     { "LavenderBlush2", 0xeee0e5 },
457                     { "LavenderBlush3", 0xcdc1c5 },
458                     { "LavenderBlush4", 0x8b8386 },
459                     { "LawnGreen", 0x7cfc00 },
460                     { "LemonChiffon", 0xfffacd },
461                     { "LemonChiffon1", 0xfffacd },
462                     { "LemonChiffon2", 0xeee9bf },
463                     { "LemonChiffon3", 0xcdc9a5 },
464                     { "LemonChiffon4", 0x8b8970 },
465                     { "LightBlue", 0xadd8e6 },
466                     { "LightBlue1", 0xbfefff },
467                     { "LightBlue2", 0xb2dfee },
468                     { "LightBlue3", 0x9ac0cd },
469                     { "LightBlue4", 0x68838b },
470                     { "LightCoral", 0xf08080 },
471                     { "LightCyan", 0xe0ffff },
472                     { "LightCyan1", 0xe0ffff },
473                     { "LightCyan2", 0xd1eeee },
474                     { "LightCyan3", 0xb4cdcd },
475                     { "LightCyan4", 0x7a8b8b },
476                     { "LightGoldenrod", 0xeedd82 },
477                     { "LightGoldenrod1", 0xffec8b },
478                     { "LightGoldenrod2", 0xeedc82 },
479                     { "LightGoldenrod3", 0xcdbe70 },
480                     { "LightGoldenrod4", 0x8b814c },
481                     { "LightGoldenrodYellow", 0xfafad2 },
482                     { "LightGray", 0xd3d3d3 },
483                     { "LightGreen", 0x90ee90 },
484                     { "LightGrey", 0xd3d3d3 },
485                     { "LightPink", 0xffb6c1 },
486                     { "LightPink1", 0xffaeb9 },
487                     { "LightPink2", 0xeea2ad },
488                     { "LightPink3", 0xcd8c95 },
489                     { "LightPink4", 0x8b5f65 },
490                     { "LightSalmon", 0xffa07a },
491                     { "LightSalmon1", 0xffa07a },
492                     { "LightSalmon2", 0xee9572 },
493                     { "LightSalmon3", 0xcd8162 },
494                     { "LightSalmon4", 0x8b5742 },
495                     { "LightSeaGreen", 0x20b2aa },
496                     { "LightSkyBlue", 0x87cefa },
497                     { "LightSkyBlue1", 0xb0e2ff },
498                     { "LightSkyBlue2", 0xa4d3ee },
499                     { "LightSkyBlue3", 0x8db6cd },
500                     { "LightSkyBlue4", 0x607b8b },
501                     { "LightSlateBlue", 0x8470ff },
502                     { "LightSlateGray", 0x778899 },
503                     { "LightSlateGrey", 0x778899 },
504                     { "LightSteelBlue", 0xb0c4de },
505                     { "LightSteelBlue1", 0xcae1ff },
506                     { "LightSteelBlue2", 0xbcd2ee },
507                     { "LightSteelBlue3", 0xa2b5cd },
508                     { "LightSteelBlue4", 0x6e7b8b },
509                     { "LightYellow", 0xffffe0 },
510                     { "LightYellow1", 0xffffe0 },
511                     { "LightYellow2", 0xeeeed1 },
512                     { "LightYellow3", 0xcdcdb4 },
513                     { "LightYellow4", 0x8b8b7a },
514                     { "LimeGreen", 0x32cd32 },
515                     { "MediumAquamarine", 0x66cdaa },
516                     { "MediumBlue", 0x0000cd },
517                     { "MediumOrchid", 0xba55d3 },
518                     { "MediumOrchid1", 0xe066ff },
519                     { "MediumOrchid2", 0xd15fee },
520                     { "MediumOrchid3", 0xb452cd },
521                     { "MediumOrchid4", 0x7a378b },
522                     { "MediumPurple", 0x9370db },
523                     { "MediumPurple1", 0xab82ff },
524                     { "MediumPurple2", 0x9f79ee },
525                     { "MediumPurple3", 0x8968cd },
526                     { "MediumPurple4", 0x5d478b },
527                     { "MediumSeaGreen", 0x3cb371 },
528                     { "MediumSlateBlue", 0x7b68ee },
529                     { "MediumSpringGreen", 0x00fa9a },
530                     { "MediumTurquoise", 0x48d1cc },
531                     { "MediumVioletRed", 0xc71585 },
532                     { "MidnightBlue", 0x191970 },
533                     { "MintCream", 0xf5fffa },
534                     { "MistyRose", 0xffe4e1 },
535                     { "MistyRose1", 0xffe4e1 },
536                     { "MistyRose2", 0xeed5d2 },
537                     { "MistyRose3", 0xcdb7b5 },
538                     { "MistyRose4", 0x8b7d7b },
539                     { "NavajoWhite", 0xffdead },
540                     { "NavajoWhite1", 0xffdead },
541                     { "NavajoWhite2", 0xeecfa1 },
542                     { "NavajoWhite3", 0xcdb38b },
543                     { "NavajoWhite4", 0x8b795e },
544                     { "NavyBlue", 0x000080 },
545                     { "OldLace", 0xfdf5e6 },
546                     { "OliveDrab", 0x6b8e23 },
547                     { "OliveDrab1", 0xc0ff3e },
548                     { "OliveDrab2", 0xb3ee3a },
549                     { "OliveDrab3", 0x9acd32 },
550                     { "OliveDrab4", 0x698b22 },
551                     { "OrangeRed", 0xff4500 },
552                     { "OrangeRed1", 0xff4500 },
553                     { "OrangeRed2", 0xee4000 },
554                     { "OrangeRed3", 0xcd3700 },
555                     { "OrangeRed4", 0x8b2500 },
556                     { "PaleGoldenrod", 0xeee8aa },
557                     { "PaleGreen", 0x98fb98 },
558                     { "PaleGreen1", 0x9aff9a },
559                     { "PaleGreen2", 0x90ee90 },
560                     { "PaleGreen3", 0x7ccd7c },
561                     { "PaleGreen4", 0x548b54 },
562                     { "PaleTurquoise", 0xafeeee },
563                     { "PaleTurquoise1", 0xbbffff },
564                     { "PaleTurquoise2", 0xaeeeee },
565                     { "PaleTurquoise3", 0x96cdcd },
566                     { "PaleTurquoise4", 0x668b8b },
567                     { "PaleVioletRed", 0xdb7093 },
568                     { "PaleVioletRed1", 0xff82ab },
569                     { "PaleVioletRed2", 0xee799f },
570                     { "PaleVioletRed3", 0xcd6889 },
571                     { "PaleVioletRed4", 0x8b475d },
572                     { "PapayaWhip", 0xffefd5 },
573                     { "PeachPuff", 0xffdab9 },
574                     { "PeachPuff1", 0xffdab9 },
575                     { "PeachPuff2", 0xeecbad },
576                     { "PeachPuff3", 0xcdaf95 },
577                     { "PeachPuff4", 0x8b7765 },
578                     { "PowderBlue", 0xb0e0e6 },
579                     { "RebeccaPurple", 0x663399 },
580                     { "RosyBrown", 0xbc8f8f },
581                     { "RosyBrown1", 0xffc1c1 },
582                     { "RosyBrown2", 0xeeb4b4 },
583                     { "RosyBrown3", 0xcd9b9b },
584                     { "RosyBrown4", 0x8b6969 },
585                     { "RoyalBlue", 0x4169e1 },
586                     { "RoyalBlue1", 0x4876ff },
587                     { "RoyalBlue2", 0x436eee },
588                     { "RoyalBlue3", 0x3a5fcd },
589                     { "RoyalBlue4", 0x27408b },
590                     { "SaddleBrown", 0x8b4513 },
591                     { "SandyBrown", 0xf4a460 },
592                     { "SeaGreen", 0x2e8b57 },
593                     { "SeaGreen1", 0x54ff9f },
594                     { "SeaGreen2", 0x4eee94 },
595                     { "SeaGreen3", 0x43cd80 },
596                     { "SeaGreen4", 0x2e8b57 },
597                     { "SkyBlue", 0x87ceeb },
598                     { "SkyBlue1", 0x87ceff },
599                     { "SkyBlue2", 0x7ec0ee },
600                     { "SkyBlue3", 0x6ca6cd },
601                     { "SkyBlue4", 0x4a708b },
602                     { "SlateBlue", 0x6a5acd },
603                     { "SlateBlue1", 0x836fff },
604                     { "SlateBlue2", 0x7a67ee },
605                     { "SlateBlue3", 0x6959cd },
606                     { "SlateBlue4", 0x473c8b },
607                     { "SlateGray", 0x708090 },
608                     { "SlateGray1", 0xc6e2ff },
609                     { "SlateGray2", 0xb9d3ee },
610                     { "SlateGray3", 0x9fb6cd },
611                     { "SlateGray4", 0x6c7b8b },
612                     { "SlateGrey", 0x708090 },
613                     { "SpringGreen", 0x00ff7f },
614                     { "SpringGreen1", 0x00ff7f },
615                     { "SpringGreen2", 0x00ee76 },
616                     { "SpringGreen3", 0x00cd66 },
617                     { "SpringGreen4", 0x008b45 },
618                     { "SteelBlue", 0x4682b4 },
619                     { "SteelBlue1", 0x63b8ff },
620                     { "SteelBlue2", 0x5cacee },
621                     { "SteelBlue3", 0x4f94cd },
622                     { "SteelBlue4", 0x36648b },
623                     { "VioletRed", 0xd02090 },
624                     { "VioletRed1", 0xff3e96 },
625                     { "VioletRed2", 0xee3a8c },
626                     { "VioletRed3", 0xcd3278 },
627                     { "VioletRed4", 0x8b2252 },
628                     { "WebGray", 0x808080 },
629                     { "WebGreen", 0x008000 },
630                     { "WebGrey", 0x808080 },
631                     { "WebMaroon", 0x800000 },
632                     { "WebPurple", 0x800080 },
633                     { "WhiteSmoke", 0xf5f5f5 },
634                     { "X11Gray", 0xbebebe },
635                     { "X11Green", 0x00ff00 },
636                     { "X11Grey", 0xbebebe },
637                     { "X11Maroon", 0xb03060 },
638                     { "X11Purple", 0xa020f0 },
639                     { "YellowGreen", 0x9acd32 },
640                     { "alice blue", 0xf0f8ff },
641                     { "antique white", 0xfaebd7 },
642                     { "aqua", 0x00ffff },
643                     { "aquamarine", 0x7fffd4 },
644                     { "aquamarine1", 0x7fffd4 },
645                     { "aquamarine2", 0x76eec6 },
646                     { "aquamarine3", 0x66cdaa },
647                     { "aquamarine4", 0x458b74 },
648                     { "azure", 0xf0ffff },
649                     { "azure1", 0xf0ffff },
650                     { "azure2", 0xe0eeee },
651                     { "azure3", 0xc1cdcd },
652                     { "azure4", 0x838b8b },
653                     { "beige", 0xf5f5dc },
654                     { "bisque", 0xffe4c4 },
655                     { "bisque1", 0xffe4c4 },
656                     { "bisque2", 0xeed5b7 },
657                     { "bisque3", 0xcdb79e },
658                     { "bisque4", 0x8b7d6b },
659                     { "black", 0x000000 },
660                     { "blanched almond", 0xffebcd },
661                     { "blue violet", 0x8a2be2 },
662                     { "blue", 0x0000ff },
663                     { "blue1", 0x0000ff },
664                     { "blue2", 0x0000ee },
665                     { "blue3", 0x0000cd },
666                     { "blue4", 0x00008b },
667                     { "brown", 0xa52a2a },
668                     { "brown1", 0xff4040 },
669                     { "brown2", 0xee3b3b },
670                     { "brown3", 0xcd3333 },
671                     { "brown4", 0x8b2323 },
672                     { "burlywood", 0xdeb887 },
673                     { "burlywood1", 0xffd39b },
674                     { "burlywood2", 0xeec591 },
675                     { "burlywood3", 0xcdaa7d },
676                     { "burlywood4", 0x8b7355 },
677                     { "cadet blue", 0x5f9ea0 },
678                     { "chartreuse", 0x7fff00 },
679                     { "chartreuse1", 0x7fff00 },
680                     { "chartreuse2", 0x76ee00 },
681                     { "chartreuse3", 0x66cd00 },
682                     { "chartreuse4", 0x458b00 },
683                     { "chocolate", 0xd2691e },
684                     { "chocolate1", 0xff7f24 },
685                     { "chocolate2", 0xee7621 },
686                     { "chocolate3", 0xcd661d },
687                     { "chocolate4", 0x8b4513 },
688                     { "coral", 0xff7f50 },
689                     { "coral1", 0xff7256 },
690                     { "coral2", 0xee6a50 },
691                     { "coral3", 0xcd5b45 },
692                     { "coral4", 0x8b3e2f },
693                     { "cornflower blue", 0x6495ed },
694                     { "cornsilk", 0xfff8dc },
695                     { "cornsilk1", 0xfff8dc },
696                     { "cornsilk2", 0xeee8cd },
697                     { "cornsilk3", 0xcdc8b1 },
698                     { "cornsilk4", 0x8b8878 },
699                     { "crimson", 0xdc143c },
700                     { "cyan", 0x00ffff },
701                     { "cyan1", 0x00ffff },
702                     { "cyan2", 0x00eeee },
703                     { "cyan3", 0x00cdcd },
704                     { "cyan4", 0x008b8b },
705                     { "dark blue", 0x00008b },
706                     { "dark cyan", 0x008b8b },
707                     { "dark goldenrod", 0xb8860b },
708                     { "dark gray", 0xa9a9a9 },
709                     { "dark green", 0x006400 },
710                     { "dark grey", 0xa9a9a9 },
711                     { "dark khaki", 0xbdb76b },
712                     { "dark magenta", 0x8b008b },
713                     { "dark olive green", 0x556b2f },
714                     { "dark orange", 0xff8c00 },
715                     { "dark orchid", 0x9932cc },
716                     { "dark red", 0x8b0000 },
717                     { "dark salmon", 0xe9967a },
718                     { "dark sea green", 0x8fbc8f },
719                     { "dark slate blue", 0x483d8b },
720                     { "dark slate gray", 0x2f4f4f },
721                     { "dark slate grey", 0x2f4f4f },
722                     { "dark turquoise", 0x00ced1 },
723                     { "dark violet", 0x9400d3 },
724                     { "deep pink", 0xff1493 },
725                     { "deep sky blue", 0x00bfff },
726                     { "dim gray", 0x696969 },
727                     { "dim grey", 0x696969 },
728                     { "dodger blue", 0x1e90ff },
729                     { "firebrick", 0xb22222 },
730                     { "firebrick1", 0xff3030 },
731                     { "firebrick2", 0xee2c2c },
732                     { "firebrick3", 0xcd2626 },
733                     { "firebrick4", 0x8b1a1a },
734                     { "floral white", 0xfffaf0 },
735                     { "forest green", 0x228b22 },
736                     { "fuchsia", 0xff00ff },
737                     { "gainsboro", 0xdcdcdc },
738                     { "ghost white", 0xf8f8ff },
739                     { "gold", 0xffd700 },
740                     { "gold1", 0xffd700 },
741                     { "gold2", 0xeec900 },
742                     { "gold3", 0xcdad00 },
743                     { "gold4", 0x8b7500 },
744                     { "goldenrod", 0xdaa520 },
745                     { "goldenrod1", 0xffc125 },
746                     { "goldenrod2", 0xeeb422 },
747                     { "goldenrod3", 0xcd9b1d },
748                     { "goldenrod4", 0x8b6914 },
749                     { "green yellow", 0xadff2f },
750                     { "green", 0x00ff00 },
751                     { "green1", 0x00ff00 },
752                     { "green2", 0x00ee00 },
753                     { "green3", 0x00cd00 },
754                     { "green4", 0x008b00 },
755                     { "honeydew", 0xf0fff0 },
756                     { "honeydew1", 0xf0fff0 },
757                     { "honeydew2", 0xe0eee0 },
758                     { "honeydew3", 0xc1cdc1 },
759                     { "honeydew4", 0x838b83 },
760                     { "hot pink", 0xff69b4 },
761                     { "indian red", 0xcd5c5c },
762                     { "indigo", 0x4b0082 },
763                     { "ivory", 0xfffff0 },
764                     { "ivory1", 0xfffff0 },
765                     { "ivory2", 0xeeeee0 },
766                     { "ivory3", 0xcdcdc1 },
767                     { "ivory4", 0x8b8b83 },
768                     { "khaki", 0xf0e68c },
769                     { "khaki1", 0xfff68f },
770                     { "khaki2", 0xeee685 },
771                     { "khaki3", 0xcdc673 },
772                     { "khaki4", 0x8b864e },
773                     { "lavender blush", 0xfff0f5 },
774                     { "lavender", 0xe6e6fa },
775                     { "lawn green", 0x7cfc00 },
776                     { "lemon chiffon", 0xfffacd },
777                     { "light blue", 0xadd8e6 },
778                     { "light coral", 0xf08080 },
779                     { "light cyan", 0xe0ffff },
780                     { "light goldenrod yellow", 0xfafad2 },
781                     { "light goldenrod", 0xeedd82 },
782                     { "light gray", 0xd3d3d3 },
783                     { "light green", 0x90ee90 },
784                     { "light grey", 0xd3d3d3 },
785                     { "light pink", 0xffb6c1 },
786                     { "light salmon", 0xffa07a },
787                     { "light sea green", 0x20b2aa },
788                     { "light sky blue", 0x87cefa },
789                     { "light slate blue", 0x8470ff },
790                     { "light slate gray", 0x778899 },
791                     { "light slate grey", 0x778899 },
792                     { "light steel blue", 0xb0c4de },
793                     { "light yellow", 0xffffe0 },
794                     { "lime green", 0x32cd32 },
795                     { "lime", 0x00ff00 },
796                     { "linen", 0xfaf0e6 },
797                     { "magenta", 0xff00ff },
798                     { "magenta1", 0xff00ff },
799                     { "magenta2", 0xee00ee },
800                     { "magenta3", 0xcd00cd },
801                     { "magenta4", 0x8b008b },
802                     { "maroon", 0xb03060 },
803                     { "maroon1", 0xff34b3 },
804                     { "maroon2", 0xee30a7 },
805                     { "maroon3", 0xcd2990 },
806                     { "maroon4", 0x8b1c62 },
807                     { "medium aquamarine", 0x66cdaa },
808                     { "medium blue", 0x0000cd },
809                     { "medium orchid", 0xba55d3 },
810                     { "medium purple", 0x9370db },
811                     { "medium sea green", 0x3cb371 },
812                     { "medium slate blue", 0x7b68ee },
813                     { "medium spring green", 0x00fa9a },
814                     { "medium turquoise", 0x48d1cc },
815                     { "medium violet red", 0xc71585 },
816                     { "midnight blue", 0x191970 },
817                     { "mint cream", 0xf5fffa },
818                     { "misty rose", 0xffe4e1 },
819                     { "moccasin", 0xffe4b5 },
820                     { "navajo white", 0xffdead },
821                     { "navy blue", 0x000080 },
822                     { "navy", 0x000080 },
823                     { "old lace", 0xfdf5e6 },
824                     { "olive drab", 0x6b8e23 },
825                     { "olive", 0x808000 },
826                     { "orange red", 0xff4500 },
827                     { "orange", 0xffa500 },
828                     { "orange1", 0xffa500 },
829                     { "orange2", 0xee9a00 },
830                     { "orange3", 0xcd8500 },
831                     { "orange4", 0x8b5a00 },
832                     { "orchid", 0xda70d6 },
833                     { "orchid1", 0xff83fa },
834                     { "orchid2", 0xee7ae9 },
835                     { "orchid3", 0xcd69c9 },
836                     { "orchid4", 0x8b4789 },
837                     { "pale goldenrod", 0xeee8aa },
838                     { "pale green", 0x98fb98 },
839                     { "pale turquoise", 0xafeeee },
840                     { "pale violet red", 0xdb7093 },
841                     { "papaya whip", 0xffefd5 },
842                     { "peach puff", 0xffdab9 },
843                     { "peru", 0xcd853f },
844                     { "pink", 0xffc0cb },
845                     { "pink1", 0xffb5c5 },
846                     { "pink2", 0xeea9b8 },
847                     { "pink3", 0xcd919e },
848                     { "pink4", 0x8b636c },
849                     { "plum", 0xdda0dd },
850                     { "plum1", 0xffbbff },
851                     { "plum2", 0xeeaeee },
852                     { "plum3", 0xcd96cd },
853                     { "plum4", 0x8b668b },
854                     { "powder blue", 0xb0e0e6 },
855                     { "purple", 0xa020f0 },
856                     { "purple1", 0x9b30ff },
857                     { "purple2", 0x912cee },
858                     { "purple3", 0x7d26cd },
859                     { "purple4", 0x551a8b },
860                     { "rebecca purple", 0x663399 },
861                     { "red", 0xff0000 },
862                     { "red1", 0xff0000 },
863                     { "red2", 0xee0000 },
864                     { "red3", 0xcd0000 },
865                     { "red4", 0x8b0000 },
866                     { "rosy brown", 0xbc8f8f },
867                     { "royal blue", 0x4169e1 },
868                     { "saddle brown", 0x8b4513 },
869                     { "salmon", 0xfa8072 },
870                     { "salmon1", 0xff8c69 },
871                     { "salmon2", 0xee8262 },
872                     { "salmon3", 0xcd7054 },
873                     { "salmon4", 0x8b4c39 },
874                     { "sandy brown", 0xf4a460 },
875                     { "sea green", 0x2e8b57 },
876                     { "seashell", 0xfff5ee },
877                     { "seashell1", 0xfff5ee },
878                     { "seashell2", 0xeee5de },
879                     { "seashell3", 0xcdc5bf },
880                     { "seashell4", 0x8b8682 },
881                     { "sienna", 0xa0522d },
882                     { "sienna1", 0xff8247 },
883                     { "sienna2", 0xee7942 },
884                     { "sienna3", 0xcd6839 },
885                     { "sienna4", 0x8b4726 },
886                     { "silver", 0xc0c0c0 },
887                     { "sky blue", 0x87ceeb },
888                     { "slate blue", 0x6a5acd },
889                     { "slate gray", 0x708090 },
890                     { "slate grey", 0x708090 },
891                     { "snow", 0xfffafa },
892                     { "snow1", 0xfffafa },
893                     { "snow2", 0xeee9e9 },
894                     { "snow3", 0xcdc9c9 },
895                     { "snow4", 0x8b8989 },
896                     { "spring green", 0x00ff7f },
897                     { "steel blue", 0x4682b4 },
898                     { "tan", 0xd2b48c },
899                     { "tan1", 0xffa54f },
900                     { "tan2", 0xee9a49 },
901                     { "tan3", 0xcd853f },
902                     { "tan4", 0x8b5a2b },
903                     { "teal", 0x008080 },
904                     { "thistle", 0xd8bfd8 },
905                     { "thistle1", 0xffe1ff },
906                     { "thistle2", 0xeed2ee },
907                     { "thistle3", 0xcdb5cd },
908                     { "thistle4", 0x8b7b8b },
909                     { "tomato", 0xff6347 },
910                     { "tomato1", 0xff6347 },
911                     { "tomato2", 0xee5c42 },
912                     { "tomato3", 0xcd4f39 },
913                     { "tomato4", 0x8b3626 },
914                     { "turquoise", 0x40e0d0 },
915                     { "turquoise1", 0x00f5ff },
916                     { "turquoise2", 0x00e5ee },
917                     { "turquoise3", 0x00c5cd },
918                     { "turquoise4", 0x00868b },
919                     { "violet red", 0xd02090 },
920                     { "violet", 0xee82ee },
921                     { "web gray", 0x808080 },
922                     { "web green", 0x008000 },
923                     { "web grey", 0x808080 },
924                     { "web maroon", 0x800000 },
925                     { "web purple", 0x800080 },
926                     { "wheat", 0xf5deb3 },
927                     { "wheat1", 0xffe7ba },
928                     { "wheat2", 0xeed8ae },
929                     { "wheat3", 0xcdba96 },
930                     { "wheat4", 0x8b7e66 },
931                     { "white smoke", 0xf5f5f5 },
932                     { "white", 0xffffff },
933                     { "x11 gray", 0xbebebe },
934                     { "x11 green", 0x00ff00 },
935                     { "x11 grey", 0xbebebe },
936                     { "x11 maroon", 0xb03060 },
937                     { "x11 purple", 0xa020f0 },
938                     { "yellow green", 0x9acd32 },
939                     { "yellow", 0xffff00 },
940                     { "yellow1", 0xffff00 },
941                     { "yellow2", 0xeeee00 },
942                     { "yellow3", 0xcdcd00 },
943                     { "yellow4", 0x8b8b00 }
944           };
945           u_int                i;
946           int                  c;
947           const char          *errstr;
948 
949           if (strncmp(name, "grey", 4) == 0 || strncmp(name, "gray", 4) == 0) {
950                     if (name[4] == '\0')
951                               return (0xbebebe|COLOUR_FLAG_RGB);
952                     c = strtonum(name + 4, 0, 100, &errstr);
953                     if (errstr != NULL)
954                               return (-1);
955                     c = round(2.55 * c);
956                     if (c < 0 || c > 255)
957                               return (-1);
958                     return (colour_join_rgb(c, c, c));
959           }
960           for (i = 0; i < nitems(colours); i++) {
961                     if (strcasecmp(colours[i].name, name) == 0)
962                               return (colours[i].c|COLOUR_FLAG_RGB);
963           }
964           return (-1);
965 }
966 
967 /* Parse colour from an X11 string. */
968 int
colour_parseX11(const char * p)969 colour_parseX11(const char *p)
970 {
971           double     c, m, y, k = 0;
972           u_int      r, g, b;
973           size_t     len = strlen(p);
974           int        colour = -1;
975           char      *copy;
976 
977           if ((len == 12 && sscanf(p, "rgb:%02x/%02x/%02x", &r, &g, &b) == 3) ||
978               (len == 7 && sscanf(p, "#%02x%02x%02x", &r, &g, &b) == 3) ||
979               sscanf(p, "%d,%d,%d", &r, &g, &b) == 3)
980                     colour = colour_join_rgb(r, g, b);
981           else if ((len == 18 &&
982               sscanf(p, "rgb:%04x/%04x/%04x", &r, &g, &b) == 3) ||
983               (len == 13 && sscanf(p, "#%04x%04x%04x", &r, &g, &b) == 3))
984                     colour = colour_join_rgb(r >> 8, g >> 8, b >> 8);
985           else if ((sscanf(p, "cmyk:%lf/%lf/%lf/%lf", &c, &m, &y, &k) == 4 ||
986               sscanf(p, "cmy:%lf/%lf/%lf", &c, &m, &y) == 3) &&
987               c >= 0 && c <= 1 && m >= 0 && m <= 1 &&
988               y >= 0 && y <= 1 && k >= 0 && k <= 1) {
989                     colour = colour_join_rgb(
990                         (1 - c) * (1 - k) * 255,
991                         (1 - m) * (1 - k) * 255,
992                         (1 - y) * (1 - k) * 255);
993           } else {
994                     while (len != 0 && *p == ' ') {
995                               p++;
996                               len--;
997                     }
998                     while (len != 0 && p[len - 1] == ' ')
999                               len--;
1000                     copy = xstrndup(p, len);
1001                     colour = colour_byname(copy);
1002                     free(copy);
1003           }
1004           log_debug("%s: %s = %s", __func__, p, colour_tostring(colour));
1005           return (colour);
1006 }
1007 
1008 /* Initialize palette. */
1009 void
colour_palette_init(struct colour_palette * p)1010 colour_palette_init(struct colour_palette *p)
1011 {
1012           p->fg = 8;
1013           p->bg = 8;
1014           p->palette = NULL;
1015           p->default_palette = NULL;
1016 }
1017 
1018 /* Clear palette. */
1019 void
colour_palette_clear(struct colour_palette * p)1020 colour_palette_clear(struct colour_palette *p)
1021 {
1022           if (p != NULL) {
1023                     p->fg = 8;
1024                     p->bg = 8;
1025                     free(p->palette);
1026                     p->palette = NULL;
1027           }
1028 }
1029 
1030 /* Free a palette. */
1031 void
colour_palette_free(struct colour_palette * p)1032 colour_palette_free(struct colour_palette *p)
1033 {
1034           if (p != NULL) {
1035                     free(p->palette);
1036                     p->palette = NULL;
1037                     free(p->default_palette);
1038                     p->default_palette = NULL;
1039           }
1040 }
1041 
1042 /* Get a colour from a palette. */
1043 int
colour_palette_get(struct colour_palette * p,int c)1044 colour_palette_get(struct colour_palette *p, int c)
1045 {
1046           if (p == NULL)
1047                     return (-1);
1048 
1049           if (c >= 90 && c <= 97)
1050                     c = 8 + c - 90;
1051           else if (c & COLOUR_FLAG_256)
1052                     c &= ~COLOUR_FLAG_256;
1053           else if (c >= 8)
1054                     return (-1);
1055 
1056           if (p->palette != NULL && p->palette[c] != -1)
1057                     return (p->palette[c]);
1058           if (p->default_palette != NULL && p->default_palette[c] != -1)
1059                     return (p->default_palette[c]);
1060           return (-1);
1061 }
1062 
1063 /* Set a colour in a palette. */
1064 int
colour_palette_set(struct colour_palette * p,int n,int c)1065 colour_palette_set(struct colour_palette *p, int n, int c)
1066 {
1067           u_int     i;
1068 
1069           if (p == NULL || n > 255)
1070                     return (0);
1071 
1072           if (c == -1 && p->palette == NULL)
1073                     return (0);
1074 
1075           if (c != -1 && p->palette == NULL) {
1076                     if (p->palette == NULL)
1077                               p->palette = xcalloc(256, sizeof *p->palette);
1078                     for (i = 0; i < 256; i++)
1079                               p->palette[i] = -1;
1080           }
1081           p->palette[n] = c;
1082           return (1);
1083 }
1084 
1085 /* Build palette defaults from an option. */
1086 void
colour_palette_from_option(struct colour_palette * p,struct options * oo)1087 colour_palette_from_option(struct colour_palette *p, struct options *oo)
1088 {
1089           struct options_entry                    *o;
1090           struct options_array_item     *a;
1091           u_int                                    i, n;
1092           int                                      c;
1093 
1094           if (p == NULL)
1095                     return;
1096 
1097           o = options_get(oo, "pane-colours");
1098           if ((a = options_array_first(o)) == NULL) {
1099                     if (p->default_palette != NULL) {
1100                               free(p->default_palette);
1101                               p->default_palette = NULL;
1102                     }
1103                     return;
1104           }
1105           if (p->default_palette == NULL)
1106                     p->default_palette = xcalloc(256, sizeof *p->default_palette);
1107           for (i = 0; i < 256; i++)
1108                     p->default_palette[i] = -1;
1109           while (a != NULL) {
1110                     n = options_array_item_index(a);
1111                     if (n < 256) {
1112                               c = options_array_item_value(a)->number;
1113                               p->default_palette[n] = c;
1114                     }
1115                     a = options_array_next(a);
1116           }
1117 }
1118