Change the way the working directory for new processes is discovered. If
[tmux-openbsd.git] / colour.c
blobae69e88f3bc296837fa52e4b8fd68e0ac072cc6b
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
21 #include <ctype.h>
22 #include <stdlib.h>
23 #include <string.h>
25 #include "tmux.h"
28 * Colour to string conversion functions. Bit 8 of the colour means it is one
29 * of the 256 colour palette.
32 /* An RGB colour. */
33 struct colour_rgb {
34 u_char r;
35 u_char g;
36 u_char b;
39 /* 256 colour RGB table, generated on first use. */
40 struct colour_rgb *colour_rgb_256;
42 void colour_rgb_generate256(void);
43 u_int colour_rgb_distance(struct colour_rgb *, struct colour_rgb *);
44 int colour_rgb_find(struct colour_rgb *);
46 /* Generate 256 colour RGB table. */
47 void
48 colour_rgb_generate256(void)
50 struct colour_rgb *rgb;
51 u_int i, r, g, b;
54 * Allocate the table. The first 16 colours are often changed by users
55 * and terminals so don't include them.
57 colour_rgb_256 = xcalloc(240, sizeof *colour_rgb_256);
59 /* Add the colours first. */
60 r = g = b = 0;
61 for (i = 240; i > 24; i--) {
62 rgb = &colour_rgb_256[240 - i];
64 if (r != 0)
65 rgb->r = (r * 40) + 55;
66 if (g != 0)
67 rgb->g = (g * 40) + 55;
68 if (b != 0)
69 rgb->b = (b * 40) + 55;
71 b++;
72 if (b > 5) {
73 b = 0;
74 g++;
76 if (g > 5) {
77 g = 0;
78 r++;
82 /* Then add the greys. */
83 for (i = 24; i > 0; i--) {
84 rgb = &colour_rgb_256[240 - i];
86 rgb->r = 8 + (24 - i) * 10;
87 rgb->g = 8 + (24 - i) * 10;
88 rgb->b = 8 + (24 - i) * 10;
92 /* Get colour RGB distance. */
93 u_int
94 colour_rgb_distance(struct colour_rgb *rgb1, struct colour_rgb *rgb2)
96 int r, g, b;
98 r = rgb1->r - rgb2->r;
99 g = rgb1->g - rgb2->g;
100 b = rgb1->b - rgb2->b;
101 return (r * r + g * g + b * b);
104 /* Work out the nearest colour from the 256 colour set. */
106 colour_rgb_find(struct colour_rgb *rgb)
108 u_int distance, lowest, colour, i;
110 if (colour_rgb_256 == NULL)
111 colour_rgb_generate256();
113 colour = 16;
114 lowest = UINT_MAX;
115 for (i = 0; i < 240; i++) {
116 distance = colour_rgb_distance(&colour_rgb_256[i], rgb);
117 if (distance < lowest) {
118 lowest = distance;
119 colour = 16 + i;
122 return (colour);
125 /* Set grid cell foreground colour. */
126 void
127 colour_set_fg(struct grid_cell *gc, int c)
129 if (c & 0x100)
130 gc->flags |= GRID_FLAG_FG256;
131 gc->fg = c;
134 /* Set grid cell background colour. */
135 void
136 colour_set_bg(struct grid_cell *gc, int c)
138 if (c & 0x100)
139 gc->flags |= GRID_FLAG_BG256;
140 gc->bg = c;
143 /* Convert colour to a string. */
144 const char *
145 colour_tostring(int c)
147 static char s[32];
149 if (c & 0x100) {
150 xsnprintf(s, sizeof s, "colour%u", c & ~0x100);
151 return (s);
154 switch (c) {
155 case 0:
156 return ("black");
157 case 1:
158 return ("red");
159 case 2:
160 return ("green");
161 case 3:
162 return ("yellow");
163 case 4:
164 return ("blue");
165 case 5:
166 return ("magenta");
167 case 6:
168 return ("cyan");
169 case 7:
170 return ("white");
171 case 8:
172 return ("default");
174 return (NULL);
177 /* Convert colour from string. */
179 colour_fromstring(const char *s)
181 const char *errstr;
182 const char *cp;
183 struct colour_rgb rgb;
184 int n;
186 if (*s == '#' && strlen(s) == 7) {
187 for (cp = s + 1; isxdigit((u_char) *cp); cp++)
189 if (*cp != '\0')
190 return (-1);
191 n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &rgb.r, &rgb.g, &rgb.b);
192 if (n != 3)
193 return (-1);
194 return (colour_rgb_find(&rgb) | 0x100);
197 if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
198 n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr);
199 if (errstr != NULL)
200 return (-1);
201 return (n | 0x100);
204 if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0'))
205 return (0);
206 if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0'))
207 return (1);
208 if (strcasecmp(s, "green") == 0 || (s[0] == '2' && s[1] == '\0'))
209 return (2);
210 if (strcasecmp(s, "yellow") == 0 || (s[0] == '3' && s[1] == '\0'))
211 return (3);
212 if (strcasecmp(s, "blue") == 0 || (s[0] == '4' && s[1] == '\0'))
213 return (4);
214 if (strcasecmp(s, "magenta") == 0 || (s[0] == '5' && s[1] == '\0'))
215 return (5);
216 if (strcasecmp(s, "cyan") == 0 || (s[0] == '6' && s[1] == '\0'))
217 return (6);
218 if (strcasecmp(s, "white") == 0 || (s[0] == '7' && s[1] == '\0'))
219 return (7);
220 if (strcasecmp(s, "default") == 0 || (s[0] == '8' && s[1] == '\0'))
221 return (8);
222 return (-1);
225 /* Convert 256 colour palette to 16. */
226 u_char
227 colour_256to16(u_char c)
229 static const u_char table[256] = {
230 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
231 0, 4, 4, 4, 12, 12, 2, 6, 4, 4, 12, 12, 2, 2, 6, 4,
232 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
233 10, 10, 10, 14, 1, 5, 4, 4, 12, 12, 3, 8, 4, 4, 12, 12,
234 2, 2, 6, 4, 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10,
235 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 5, 4, 12, 12, 1, 1,
236 5, 4, 12, 12, 3, 3, 8, 4, 12, 12, 2, 2, 2, 6, 12, 12,
237 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 1, 5,
238 12, 12, 1, 1, 1, 5, 12, 12, 1, 1, 1, 5, 12, 12, 3, 3,
239 3, 7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,
240 9, 9, 9, 9, 13, 12, 9, 9, 9, 9, 13, 12, 9, 9, 9, 9,
241 13, 12, 9, 9, 9, 9, 13, 12, 11, 11, 11, 11, 7, 12, 10, 10,
242 10, 10, 10, 14, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13,
243 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9,
244 9, 13, 11, 11, 11, 11, 11, 15, 0, 0, 0, 0, 0, 0, 8, 8,
245 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15
248 return (table[c]);
251 /* Convert 256 colour palette to 88. */
252 u_char
253 colour_256to88(u_char c)
255 static const u_char table[256] = {
256 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
257 16, 17, 17, 18, 18, 19, 20, 21, 21, 22, 22, 23, 20, 21, 21, 22,
258 22, 23, 24, 25, 25, 26, 26, 27, 24, 25, 25, 26, 26, 27, 28, 29,
259 29, 30, 30, 31, 32, 33, 33, 34, 34, 35, 36, 37, 37, 38, 38, 39,
260 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43, 40, 41, 41, 42,
261 42, 43, 44, 45, 45, 46, 46, 47, 32, 33, 33, 34, 34, 35, 36, 37,
262 37, 38, 38, 39, 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43,
263 40, 41, 41, 42, 42, 43, 44, 45, 45, 46, 46, 47, 48, 49, 49, 50,
264 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54, 54, 55, 56, 57,
265 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61, 61, 62, 62, 63,
266 48, 49, 49, 50, 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54,
267 54, 55, 56, 57, 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61,
268 61, 62, 62, 63, 64, 65, 65, 66, 66, 67, 68, 69, 69, 70, 70, 71,
269 68, 69, 69, 70, 70, 71, 72, 73, 73, 74, 74, 75, 72, 73, 73, 74,
270 74, 75, 76, 77, 77, 78, 78, 79, 0, 0, 80, 80, 80, 81, 81, 81,
271 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87
274 return (table[c]);