Coverage Report

Created: 2026-08-13 06:06

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