diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2011-01-08 00:48:55 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2011-01-08 00:48:55 +0000 |
commit | 4f2baba24cae23530d9c11975caf2ade6b71ff6d (patch) | |
tree | 34e1f1dada0d208e04cd1e99df9a1db3fe605439 /usr.bin | |
parent | 58a8e761531f995ce31d0f8cdea924d05310d058 (diff) |
Accept colours of the hex form #ffffff and translate to the nearest from
the xterm(1) 256-colour set.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tmux/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/tmux/colour.c | 121 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 11 |
3 files changed, 128 insertions, 10 deletions
diff --git a/usr.bin/tmux/Makefile b/usr.bin/tmux/Makefile index e9cbd7081cd..a37ec8d49b5 100644 --- a/usr.bin/tmux/Makefile +++ b/usr.bin/tmux/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.50 2011/01/04 02:03:41 nicm Exp $ +# $OpenBSD: Makefile,v 1.51 2011/01/08 00:48:54 nicm Exp $ PROG= tmux SRCS= arguments.c attributes.c cfg.c client.c clock.c \ @@ -44,7 +44,7 @@ CDIAGFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations CDIAGFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare CDIAGFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align -LDADD= -lutil -lcurses -levent -DPADD= ${LIBUTIL} ${LIBCURSES} ${LIBEVENT} +LDADD= -lutil -lcurses -levent -lm +DPADD= ${LIBUTIL} ${LIBCURSES} ${LIBEVENT} ${LIBM} .include <bsd.prog.mk> diff --git a/usr.bin/tmux/colour.c b/usr.bin/tmux/colour.c index 288b35e3185..e4870ee6876 100644 --- a/usr.bin/tmux/colour.c +++ b/usr.bin/tmux/colour.c @@ -1,4 +1,4 @@ -/* $OpenBSD: colour.c,v 1.2 2009/09/10 17:16:24 nicm Exp $ */ +/* $OpenBSD: colour.c,v 1.3 2011/01/08 00:48:54 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -18,6 +18,8 @@ #include <sys/types.h> +#include <ctype.h> +#include <math.h> #include <stdlib.h> #include <string.h> @@ -28,6 +30,101 @@ * of the 256 colour palette. */ +/* An RGB colour. */ +struct colour_rgb { + u_char r; + u_char g; + u_char b; +}; + +/* 256 colour RGB table, generated on first use. */ +struct colour_rgb *colour_rgb_256; + +void colour_rgb_generate256(void); +double colour_rgb_distance(struct colour_rgb *, struct colour_rgb *); +int colour_rgb_find(struct colour_rgb *); + +/* Generate 256 colour RGB table. */ +void +colour_rgb_generate256(void) +{ + struct colour_rgb *rgb; + u_int i, r, g, b; + + /* + * Allocate the table. The first 16 colours are often changed by users + * and terminals so don't include them. + */ + colour_rgb_256 = xcalloc(240, sizeof *colour_rgb_256); + + /* Add the colours first. */ + r = g = b = 0; + for (i = 240; i > 24; i--) { + rgb = &colour_rgb_256[240 - i]; + + if (r != 0) + rgb->r = (r * 40) + 55; + if (g != 0) + rgb->g = (g * 40) + 55; + if (b != 0) + rgb->b = (b * 40) + 55; + + b++; + if (b > 5) { + b = 0; + g++; + } + if (g > 5) { + g = 0; + r++; + } + } + + /* Then add the greys. */ + for (i = 24; i > 0; i--) { + rgb = &colour_rgb_256[240 - i]; + + rgb->r = 8 + (24 - i) * 10; + rgb->g = 8 + (24 - i) * 10; + rgb->b = 8 + (24 - i) * 10; + } +} + +/* Get colour RGB distance. */ +double +colour_rgb_distance(struct colour_rgb *rgb1, struct colour_rgb *rgb2) +{ + int r, g, b; + + r = rgb1->r - rgb2->r; + g = rgb1->g - rgb2->g; + b = rgb1->b - rgb2->b; + return (sqrt(r * r + g * g + b * b)); +} + +/* Work out the nearest colour from the 256 colour set. */ +int +colour_rgb_find(struct colour_rgb *rgb) +{ + double distance, lowest; + u_int colour, i; + + if (colour_rgb_256 == NULL) + colour_rgb_generate256(); + + colour = 16; + lowest = INFINITY; + for (i = 0; i < 240; i++) { + distance = colour_rgb_distance(&colour_rgb_256[i], rgb); + if (distance < lowest) { + lowest = distance; + colour = 16 + i; + } + } + return (colour); +} + +/* Set grid cell foreground colour. */ void colour_set_fg(struct grid_cell *gc, int c) { @@ -36,6 +133,7 @@ colour_set_fg(struct grid_cell *gc, int c) gc->fg = c; } +/* Set grid cell background colour. */ void colour_set_bg(struct grid_cell *gc, int c) { @@ -44,6 +142,7 @@ colour_set_bg(struct grid_cell *gc, int c) gc->bg = c; } +/* Convert colour to a string. */ const char * colour_tostring(int c) { @@ -77,11 +176,25 @@ colour_tostring(int c) return (NULL); } +/* Convert colour from string. */ int colour_fromstring(const char *s) { - const char *errstr; - int n; + const char *errstr; + const char *cp; + struct colour_rgb rgb; + int n; + + if (*s == '#' && strlen(s) == 7) { + for (cp = s + 1; isxdigit((u_char) *cp); cp++) + ; + if (*cp != '\0') + return (-1); + n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &rgb.r, &rgb.g, &rgb.b); + if (n != 3) + return (-1); + return (colour_rgb_find(&rgb) | 0x100); + } if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) { n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr); @@ -111,6 +224,7 @@ colour_fromstring(const char *s) return (-1); } +/* Convert 256 colour palette to 16. */ u_char colour_256to16(u_char c) { @@ -136,6 +250,7 @@ colour_256to16(u_char c) return (table[c]); } +/* Convert 256 colour palette to 88. */ u_char colour_256to88(u_char c) { diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index b35fe796e0b..974fa3cfaff 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.204 2011/01/04 02:03:41 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.205 2011/01/08 00:48:54 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 4 2011 $ +.Dd $Mdocdate: January 8 2011 $ .Dt TMUX 1 .Os .Sh NAME @@ -1793,8 +1793,11 @@ is one of: .Ic colour0 to .Ic colour255 -from the 256-colour palette, or -.Ic default . +from the 256-colour set, +.Ic default , +or a hexadecimal RGB string such as +.Ql #ffffff , +which chooses the closest match from the default 256-colour set. .It Ic message-fg Ar colour Set status line message foreground colour. .It Ic message-limit Ar number |