summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2011-01-08 00:48:55 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2011-01-08 00:48:55 +0000
commit4f2baba24cae23530d9c11975caf2ade6b71ff6d (patch)
tree34e1f1dada0d208e04cd1e99df9a1db3fe605439 /usr.bin
parent58a8e761531f995ce31d0f8cdea924d05310d058 (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/Makefile6
-rw-r--r--usr.bin/tmux/colour.c121
-rw-r--r--usr.bin/tmux/tmux.111
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