2 * Copyright Neil Brown ©2019-2023 <neil@brown.name>
3 * May be distributed under terms of GPLv2 - see file:COPYING
5 * Provide a colour-name service.
6 * A client (normally a display) call "colour:map" passing a
7 * string name of a colour. The callback is passed the chosen colour
8 * as RGB values (0-1000) in num1 num2 and x, and as string in hex format #RRggBB
9 * Alternate interfaces are "colour:map:bg" and "colour:map:fg"
10 * The are passes a reference colour in 'str2' (#rrggbb).
11 * for colour:map:bg, the reference should be the default background
12 * for colour:map:fg, the reference should be the chosen background.
13 * One day these might modify the reult to provide better contrast.
15 * Colours have a base name and modifiers.
16 * The base name is either a word (e.g. "green" "rebeccapurple") or a
17 * hex colour #rrggbb. In either case, case is ignored.
18 * The modifier can adjust value or saturation.
19 * -nn (0-99) reduces the brightness - scales each channel towards zero.
20 * 0 means black. 99 means no-change
21 * +nn (0-99) reduces saturation - scales each channel towards max.
22 * 0 means no change, 99 means white.
23 * So "white-50" and "black+50" are both mid-grey. "yellow-90+90" is a pale yellow.
26 #define _GNU_SOURCE for_asprintf
32 static struct colours {
37 { "white", 1000, 1000, 1000 },
38 { "red", 1000, 0, 0 },
39 { "green", 0, 1000, 0 },
40 { "blue", 0, 0, 1000 },
41 { "yellow", 1000, 1000, 0 },
42 { "magenta", 1000, 0, 1000 },
43 { "cyan", 0, 1000, 1000 },
44 { "darkblue", 0, 0, 550 },
45 { "purple", 500, 0, 500 },
46 { "grey", 500, 500, 500 },
47 { "pink", 1000, 800, 800 },
50 static void gethex(char *col safe, int rgb[])
58 for (i = 0; i < 3; i++) {
61 rgb[i] = strtoul(b, NULL, 16) * 1000 / 255;
65 static bool find_colour(char *col, int rgb[])
69 for (i = 0; i < ARRAY_SIZE(colours); i++) {
70 if (strcasecmp(col, colours[i].name) == 0) {
71 rgb[0] = colours[i].r;
72 rgb[1] = colours[i].g;
73 rgb[2] = colours[i].b;
80 static void add_value(char *n, int rgb[])
85 if (scale < 0 || scale > 99)
87 for (i = 0; i < 3; i++)
88 rgb[i] = rgb[i] * scale / 99;
91 static void add_sat(char *n, int rgb[])
96 if (scale < 0 || scale > 99)
98 for (i = 0; i < 3; i++)
99 rgb[i] = 1000 - ( (99 - scale) * (1000 - rgb[i]) / 99);
106 int rgb[3] = { 500, 500, 500};
111 col = strdup(ci->str);
112 p = strchr(col, '+');
115 m = strchr(col, '-');
120 else if (!find_colour(col, rgb))
121 find_colour("grey", rgb);
127 asprintf(&col, "#%02x%02x%02x", rgb[0]*255/1000,
128 rgb[1]*255/1000, rgb[2]*255/1000);
129 ret = comm_call(ci->comm2, "colour:callback", ci->focus,
131 rgb[1], NULL, NULL, rgb[2], 0);
136 void edlib_init(struct pane *ed safe)
138 call_comm("global-set-command", ed, &colour_map,
139 0, NULL, "colour:map");
140 call_comm("global-set-command-prefix", ed, &colour_map,
141 0, NULL, "colour:map:");