Home | History | Annotate | Line # | Download | only in dist
colour.c revision 1.5
      1 /* $OpenBSD$ */
      2 
      3 /*
      4  * Copyright (c) 2008 Nicholas Marriott <nicm (at) users.sourceforge.net>
      5  *
      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.
      9  *
     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.
     17  */
     18 
     19 #include <sys/types.h>
     20 
     21 #include <ctype.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 
     25 #include "tmux.h"
     26 
     27 /*
     28  * Colour to string conversion functions. Bit 8 of the colour means it is one
     29  * of the 256 colour palette.
     30  */
     31 
     32 struct colour_rgb {
     33 	u_char  i;
     34 	u_char	r;
     35 	u_char	g;
     36 	u_char	b;
     37 };
     38 
     39 const struct colour_rgb colour_from_256[] = {
     40 	{   0, 0x00, 0x00, 0x00 }, {   1, 0x00, 0x00, 0x5f },
     41 	{   2, 0x00, 0x00, 0x87 }, {   3, 0x00, 0x00, 0xaf },
     42 	{   4, 0x00, 0x00, 0xd7 }, {   5, 0x00, 0x00, 0xff },
     43 	{   6, 0x00, 0x5f, 0x00 }, {   7, 0x00, 0x5f, 0x5f },
     44 	{   8, 0x00, 0x5f, 0x87 }, {   9, 0x00, 0x5f, 0xaf },
     45 	{  10, 0x00, 0x5f, 0xd7 }, {  11, 0x00, 0x5f, 0xff },
     46 	{  12, 0x00, 0x87, 0x00 }, {  13, 0x00, 0x87, 0x5f },
     47 	{  14, 0x00, 0x87, 0x87 }, {  15, 0x00, 0x87, 0xaf },
     48 	{  16, 0x00, 0x87, 0xd7 }, {  17, 0x00, 0x87, 0xff },
     49 	{  18, 0x00, 0xaf, 0x00 }, {  19, 0x00, 0xaf, 0x5f },
     50 	{  20, 0x00, 0xaf, 0x87 }, {  21, 0x00, 0xaf, 0xaf },
     51 	{  22, 0x00, 0xaf, 0xd7 }, {  23, 0x00, 0xaf, 0xff },
     52 	{  24, 0x00, 0xd7, 0x00 }, {  25, 0x00, 0xd7, 0x5f },
     53 	{  26, 0x00, 0xd7, 0x87 }, {  27, 0x00, 0xd7, 0xaf },
     54 	{  28, 0x00, 0xd7, 0xd7 }, {  29, 0x00, 0xd7, 0xff },
     55 	{  30, 0x00, 0xff, 0x00 }, {  31, 0x00, 0xff, 0x5f },
     56 	{  32, 0x00, 0xff, 0x87 }, {  33, 0x00, 0xff, 0xaf },
     57 	{  34, 0x00, 0xff, 0xd7 }, {  35, 0x00, 0xff, 0xff },
     58 	{  36, 0x5f, 0x00, 0x00 }, {  37, 0x5f, 0x00, 0x5f },
     59 	{  38, 0x5f, 0x00, 0x87 }, {  39, 0x5f, 0x00, 0xaf },
     60 	{  40, 0x5f, 0x00, 0xd7 }, {  41, 0x5f, 0x00, 0xff },
     61 	{  42, 0x5f, 0x5f, 0x00 }, {  43, 0x5f, 0x5f, 0x5f },
     62 	{  44, 0x5f, 0x5f, 0x87 }, {  45, 0x5f, 0x5f, 0xaf },
     63 	{  46, 0x5f, 0x5f, 0xd7 }, {  47, 0x5f, 0x5f, 0xff },
     64 	{  48, 0x5f, 0x87, 0x00 }, {  49, 0x5f, 0x87, 0x5f },
     65 	{  50, 0x5f, 0x87, 0x87 }, {  51, 0x5f, 0x87, 0xaf },
     66 	{  52, 0x5f, 0x87, 0xd7 }, {  53, 0x5f, 0x87, 0xff },
     67 	{  54, 0x5f, 0xaf, 0x00 }, {  55, 0x5f, 0xaf, 0x5f },
     68 	{  56, 0x5f, 0xaf, 0x87 }, {  57, 0x5f, 0xaf, 0xaf },
     69 	{  58, 0x5f, 0xaf, 0xd7 }, {  59, 0x5f, 0xaf, 0xff },
     70 	{  60, 0x5f, 0xd7, 0x00 }, {  61, 0x5f, 0xd7, 0x5f },
     71 	{  62, 0x5f, 0xd7, 0x87 }, {  63, 0x5f, 0xd7, 0xaf },
     72 	{  64, 0x5f, 0xd7, 0xd7 }, {  65, 0x5f, 0xd7, 0xff },
     73 	{  66, 0x5f, 0xff, 0x00 }, {  67, 0x5f, 0xff, 0x5f },
     74 	{  68, 0x5f, 0xff, 0x87 }, {  69, 0x5f, 0xff, 0xaf },
     75 	{  70, 0x5f, 0xff, 0xd7 }, {  71, 0x5f, 0xff, 0xff },
     76 	{  72, 0x87, 0x00, 0x00 }, {  73, 0x87, 0x00, 0x5f },
     77 	{  74, 0x87, 0x00, 0x87 }, {  75, 0x87, 0x00, 0xaf },
     78 	{  76, 0x87, 0x00, 0xd7 }, {  77, 0x87, 0x00, 0xff },
     79 	{  78, 0x87, 0x5f, 0x00 }, {  79, 0x87, 0x5f, 0x5f },
     80 	{  80, 0x87, 0x5f, 0x87 }, {  81, 0x87, 0x5f, 0xaf },
     81 	{  82, 0x87, 0x5f, 0xd7 }, {  83, 0x87, 0x5f, 0xff },
     82 	{  84, 0x87, 0x87, 0x00 }, {  85, 0x87, 0x87, 0x5f },
     83 	{  86, 0x87, 0x87, 0x87 }, {  87, 0x87, 0x87, 0xaf },
     84 	{  88, 0x87, 0x87, 0xd7 }, {  89, 0x87, 0x87, 0xff },
     85 	{  90, 0x87, 0xaf, 0x00 }, {  91, 0x87, 0xaf, 0x5f },
     86 	{  92, 0x87, 0xaf, 0x87 }, {  93, 0x87, 0xaf, 0xaf },
     87 	{  94, 0x87, 0xaf, 0xd7 }, {  95, 0x87, 0xaf, 0xff },
     88 	{  96, 0x87, 0xd7, 0x00 }, {  97, 0x87, 0xd7, 0x5f },
     89 	{  98, 0x87, 0xd7, 0x87 }, {  99, 0x87, 0xd7, 0xaf },
     90 	{ 100, 0x87, 0xd7, 0xd7 }, { 101, 0x87, 0xd7, 0xff },
     91 	{ 102, 0x87, 0xff, 0x00 }, { 103, 0x87, 0xff, 0x5f },
     92 	{ 104, 0x87, 0xff, 0x87 }, { 105, 0x87, 0xff, 0xaf },
     93 	{ 106, 0x87, 0xff, 0xd7 }, { 107, 0x87, 0xff, 0xff },
     94 	{ 108, 0xaf, 0x00, 0x00 }, { 109, 0xaf, 0x00, 0x5f },
     95 	{ 110, 0xaf, 0x00, 0x87 }, { 111, 0xaf, 0x00, 0xaf },
     96 	{ 112, 0xaf, 0x00, 0xd7 }, { 113, 0xaf, 0x00, 0xff },
     97 	{ 114, 0xaf, 0x5f, 0x00 }, { 115, 0xaf, 0x5f, 0x5f },
     98 	{ 116, 0xaf, 0x5f, 0x87 }, { 117, 0xaf, 0x5f, 0xaf },
     99 	{ 118, 0xaf, 0x5f, 0xd7 }, { 119, 0xaf, 0x5f, 0xff },
    100 	{ 120, 0xaf, 0x87, 0x00 }, { 121, 0xaf, 0x87, 0x5f },
    101 	{ 122, 0xaf, 0x87, 0x87 }, { 123, 0xaf, 0x87, 0xaf },
    102 	{ 124, 0xaf, 0x87, 0xd7 }, { 125, 0xaf, 0x87, 0xff },
    103 	{ 126, 0xaf, 0xaf, 0x00 }, { 127, 0xaf, 0xaf, 0x5f },
    104 	{ 128, 0xaf, 0xaf, 0x87 }, { 129, 0xaf, 0xaf, 0xaf },
    105 	{ 130, 0xaf, 0xaf, 0xd7 }, { 131, 0xaf, 0xaf, 0xff },
    106 	{ 132, 0xaf, 0xd7, 0x00 }, { 133, 0xaf, 0xd7, 0x5f },
    107 	{ 134, 0xaf, 0xd7, 0x87 }, { 135, 0xaf, 0xd7, 0xaf },
    108 	{ 136, 0xaf, 0xd7, 0xd7 }, { 137, 0xaf, 0xd7, 0xff },
    109 	{ 138, 0xaf, 0xff, 0x00 }, { 139, 0xaf, 0xff, 0x5f },
    110 	{ 140, 0xaf, 0xff, 0x87 }, { 141, 0xaf, 0xff, 0xaf },
    111 	{ 142, 0xaf, 0xff, 0xd7 }, { 143, 0xaf, 0xff, 0xff },
    112 	{ 144, 0xd7, 0x00, 0x00 }, { 145, 0xd7, 0x00, 0x5f },
    113 	{ 146, 0xd7, 0x00, 0x87 }, { 147, 0xd7, 0x00, 0xaf },
    114 	{ 148, 0xd7, 0x00, 0xd7 }, { 149, 0xd7, 0x00, 0xff },
    115 	{ 150, 0xd7, 0x5f, 0x00 }, { 151, 0xd7, 0x5f, 0x5f },
    116 	{ 152, 0xd7, 0x5f, 0x87 }, { 153, 0xd7, 0x5f, 0xaf },
    117 	{ 154, 0xd7, 0x5f, 0xd7 }, { 155, 0xd7, 0x5f, 0xff },
    118 	{ 156, 0xd7, 0x87, 0x00 }, { 157, 0xd7, 0x87, 0x5f },
    119 	{ 158, 0xd7, 0x87, 0x87 }, { 159, 0xd7, 0x87, 0xaf },
    120 	{ 160, 0xd7, 0x87, 0xd7 }, { 161, 0xd7, 0x87, 0xff },
    121 	{ 162, 0xd7, 0xaf, 0x00 }, { 163, 0xd7, 0xaf, 0x5f },
    122 	{ 164, 0xd7, 0xaf, 0x87 }, { 165, 0xd7, 0xaf, 0xaf },
    123 	{ 166, 0xd7, 0xaf, 0xd7 }, { 167, 0xd7, 0xaf, 0xff },
    124 	{ 168, 0xd7, 0xd7, 0x00 }, { 169, 0xd7, 0xd7, 0x5f },
    125 	{ 170, 0xd7, 0xd7, 0x87 }, { 171, 0xd7, 0xd7, 0xaf },
    126 	{ 172, 0xd7, 0xd7, 0xd7 }, { 173, 0xd7, 0xd7, 0xff },
    127 	{ 174, 0xd7, 0xff, 0x00 }, { 175, 0xd7, 0xff, 0x5f },
    128 	{ 176, 0xd7, 0xff, 0x87 }, { 177, 0xd7, 0xff, 0xaf },
    129 	{ 178, 0xd7, 0xff, 0xd7 }, { 179, 0xd7, 0xff, 0xff },
    130 	{ 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
    131 	{ 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
    132 	{ 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
    133 	{ 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
    134 	{ 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
    135 	{ 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
    136 	{ 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
    137 	{ 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
    138 	{ 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
    139 	{ 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
    140 	{ 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
    141 	{ 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
    142 	{ 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
    143 	{ 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
    144 	{ 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
    145 	{ 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
    146 	{ 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
    147 	{ 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
    148 	{ 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
    149 	{ 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
    150 	{ 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
    151 	{ 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
    152 	{ 224, 0x58, 0x58, 0x58 }, { 225, 0x62, 0x62, 0x62 },
    153 	{ 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
    154 	{ 228, 0x80, 0x80, 0x80 }, { 229, 0x8a, 0x8a, 0x8a },
    155 	{ 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
    156 	{ 232, 0xa8, 0xa8, 0xa8 }, { 233, 0xb2, 0xb2, 0xb2 },
    157 	{ 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
    158 	{ 236, 0xd0, 0xd0, 0xd0 }, { 237, 0xda, 0xda, 0xda },
    159 	{ 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
    160 };
    161 const struct colour_rgb colour_to_256[] = {
    162 	{   0, 0x00, 0x00, 0x00 }, {   1, 0x00, 0x00, 0x5f },
    163 	{   2, 0x00, 0x00, 0x87 }, {   3, 0x00, 0x00, 0xaf },
    164 	{   4, 0x00, 0x00, 0xd7 }, {   5, 0x00, 0x00, 0xff },
    165 	{   6, 0x00, 0x5f, 0x00 }, {   7, 0x00, 0x5f, 0x5f },
    166 	{   8, 0x00, 0x5f, 0x87 }, {   9, 0x00, 0x5f, 0xaf },
    167 	{  10, 0x00, 0x5f, 0xd7 }, {  11, 0x00, 0x5f, 0xff },
    168 	{  12, 0x00, 0x87, 0x00 }, {  13, 0x00, 0x87, 0x5f },
    169 	{  14, 0x00, 0x87, 0x87 }, {  15, 0x00, 0x87, 0xaf },
    170 	{  16, 0x00, 0x87, 0xd7 }, {  17, 0x00, 0x87, 0xff },
    171 	{  18, 0x00, 0xaf, 0x00 }, {  19, 0x00, 0xaf, 0x5f },
    172 	{  20, 0x00, 0xaf, 0x87 }, {  21, 0x00, 0xaf, 0xaf },
    173 	{  22, 0x00, 0xaf, 0xd7 }, {  23, 0x00, 0xaf, 0xff },
    174 	{  24, 0x00, 0xd7, 0x00 }, {  25, 0x00, 0xd7, 0x5f },
    175 	{  26, 0x00, 0xd7, 0x87 }, {  27, 0x00, 0xd7, 0xaf },
    176 	{  28, 0x00, 0xd7, 0xd7 }, {  29, 0x00, 0xd7, 0xff },
    177 	{  30, 0x00, 0xff, 0x00 }, {  31, 0x00, 0xff, 0x5f },
    178 	{  32, 0x00, 0xff, 0x87 }, {  33, 0x00, 0xff, 0xaf },
    179 	{  34, 0x00, 0xff, 0xd7 }, {  35, 0x00, 0xff, 0xff },
    180 	{ 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
    181 	{ 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
    182 	{ 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
    183 	{ 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
    184 	{ 224, 0x58, 0x58, 0x58 }, {  36, 0x5f, 0x00, 0x00 },
    185 	{  37, 0x5f, 0x00, 0x5f }, {  38, 0x5f, 0x00, 0x87 },
    186 	{  39, 0x5f, 0x00, 0xaf }, {  40, 0x5f, 0x00, 0xd7 },
    187 	{  41, 0x5f, 0x00, 0xff }, {  42, 0x5f, 0x5f, 0x00 },
    188 	{  43, 0x5f, 0x5f, 0x5f }, {  44, 0x5f, 0x5f, 0x87 },
    189 	{  45, 0x5f, 0x5f, 0xaf }, {  46, 0x5f, 0x5f, 0xd7 },
    190 	{  47, 0x5f, 0x5f, 0xff }, {  48, 0x5f, 0x87, 0x00 },
    191 	{  49, 0x5f, 0x87, 0x5f }, {  50, 0x5f, 0x87, 0x87 },
    192 	{  51, 0x5f, 0x87, 0xaf }, {  52, 0x5f, 0x87, 0xd7 },
    193 	{  53, 0x5f, 0x87, 0xff }, {  54, 0x5f, 0xaf, 0x00 },
    194 	{  55, 0x5f, 0xaf, 0x5f }, {  56, 0x5f, 0xaf, 0x87 },
    195 	{  57, 0x5f, 0xaf, 0xaf }, {  58, 0x5f, 0xaf, 0xd7 },
    196 	{  59, 0x5f, 0xaf, 0xff }, {  60, 0x5f, 0xd7, 0x00 },
    197 	{  61, 0x5f, 0xd7, 0x5f }, {  62, 0x5f, 0xd7, 0x87 },
    198 	{  63, 0x5f, 0xd7, 0xaf }, {  64, 0x5f, 0xd7, 0xd7 },
    199 	{  65, 0x5f, 0xd7, 0xff }, {  66, 0x5f, 0xff, 0x00 },
    200 	{  67, 0x5f, 0xff, 0x5f }, {  68, 0x5f, 0xff, 0x87 },
    201 	{  69, 0x5f, 0xff, 0xaf }, {  70, 0x5f, 0xff, 0xd7 },
    202 	{  71, 0x5f, 0xff, 0xff }, { 225, 0x62, 0x62, 0x62 },
    203 	{ 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
    204 	{ 228, 0x80, 0x80, 0x80 }, {  72, 0x87, 0x00, 0x00 },
    205 	{  73, 0x87, 0x00, 0x5f }, {  74, 0x87, 0x00, 0x87 },
    206 	{  75, 0x87, 0x00, 0xaf }, {  76, 0x87, 0x00, 0xd7 },
    207 	{  77, 0x87, 0x00, 0xff }, {  78, 0x87, 0x5f, 0x00 },
    208 	{  79, 0x87, 0x5f, 0x5f }, {  80, 0x87, 0x5f, 0x87 },
    209 	{  81, 0x87, 0x5f, 0xaf }, {  82, 0x87, 0x5f, 0xd7 },
    210 	{  83, 0x87, 0x5f, 0xff }, {  84, 0x87, 0x87, 0x00 },
    211 	{  85, 0x87, 0x87, 0x5f }, {  86, 0x87, 0x87, 0x87 },
    212 	{  87, 0x87, 0x87, 0xaf }, {  88, 0x87, 0x87, 0xd7 },
    213 	{  89, 0x87, 0x87, 0xff }, {  90, 0x87, 0xaf, 0x00 },
    214 	{  91, 0x87, 0xaf, 0x5f }, {  92, 0x87, 0xaf, 0x87 },
    215 	{  93, 0x87, 0xaf, 0xaf }, {  94, 0x87, 0xaf, 0xd7 },
    216 	{  95, 0x87, 0xaf, 0xff }, {  96, 0x87, 0xd7, 0x00 },
    217 	{  97, 0x87, 0xd7, 0x5f }, {  98, 0x87, 0xd7, 0x87 },
    218 	{  99, 0x87, 0xd7, 0xaf }, { 100, 0x87, 0xd7, 0xd7 },
    219 	{ 101, 0x87, 0xd7, 0xff }, { 102, 0x87, 0xff, 0x00 },
    220 	{ 103, 0x87, 0xff, 0x5f }, { 104, 0x87, 0xff, 0x87 },
    221 	{ 105, 0x87, 0xff, 0xaf }, { 106, 0x87, 0xff, 0xd7 },
    222 	{ 107, 0x87, 0xff, 0xff }, { 229, 0x8a, 0x8a, 0x8a },
    223 	{ 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
    224 	{ 232, 0xa8, 0xa8, 0xa8 }, { 108, 0xaf, 0x00, 0x00 },
    225 	{ 109, 0xaf, 0x00, 0x5f }, { 110, 0xaf, 0x00, 0x87 },
    226 	{ 111, 0xaf, 0x00, 0xaf }, { 112, 0xaf, 0x00, 0xd7 },
    227 	{ 113, 0xaf, 0x00, 0xff }, { 114, 0xaf, 0x5f, 0x00 },
    228 	{ 115, 0xaf, 0x5f, 0x5f }, { 116, 0xaf, 0x5f, 0x87 },
    229 	{ 117, 0xaf, 0x5f, 0xaf }, { 118, 0xaf, 0x5f, 0xd7 },
    230 	{ 119, 0xaf, 0x5f, 0xff }, { 120, 0xaf, 0x87, 0x00 },
    231 	{ 121, 0xaf, 0x87, 0x5f }, { 122, 0xaf, 0x87, 0x87 },
    232 	{ 123, 0xaf, 0x87, 0xaf }, { 124, 0xaf, 0x87, 0xd7 },
    233 	{ 125, 0xaf, 0x87, 0xff }, { 126, 0xaf, 0xaf, 0x00 },
    234 	{ 127, 0xaf, 0xaf, 0x5f }, { 128, 0xaf, 0xaf, 0x87 },
    235 	{ 129, 0xaf, 0xaf, 0xaf }, { 130, 0xaf, 0xaf, 0xd7 },
    236 	{ 131, 0xaf, 0xaf, 0xff }, { 132, 0xaf, 0xd7, 0x00 },
    237 	{ 133, 0xaf, 0xd7, 0x5f }, { 134, 0xaf, 0xd7, 0x87 },
    238 	{ 135, 0xaf, 0xd7, 0xaf }, { 136, 0xaf, 0xd7, 0xd7 },
    239 	{ 137, 0xaf, 0xd7, 0xff }, { 138, 0xaf, 0xff, 0x00 },
    240 	{ 139, 0xaf, 0xff, 0x5f }, { 140, 0xaf, 0xff, 0x87 },
    241 	{ 141, 0xaf, 0xff, 0xaf }, { 142, 0xaf, 0xff, 0xd7 },
    242 	{ 143, 0xaf, 0xff, 0xff }, { 233, 0xb2, 0xb2, 0xb2 },
    243 	{ 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
    244 	{ 236, 0xd0, 0xd0, 0xd0 }, { 144, 0xd7, 0x00, 0x00 },
    245 	{ 145, 0xd7, 0x00, 0x5f }, { 146, 0xd7, 0x00, 0x87 },
    246 	{ 147, 0xd7, 0x00, 0xaf }, { 148, 0xd7, 0x00, 0xd7 },
    247 	{ 149, 0xd7, 0x00, 0xff }, { 150, 0xd7, 0x5f, 0x00 },
    248 	{ 151, 0xd7, 0x5f, 0x5f }, { 152, 0xd7, 0x5f, 0x87 },
    249 	{ 153, 0xd7, 0x5f, 0xaf }, { 154, 0xd7, 0x5f, 0xd7 },
    250 	{ 155, 0xd7, 0x5f, 0xff }, { 156, 0xd7, 0x87, 0x00 },
    251 	{ 157, 0xd7, 0x87, 0x5f }, { 158, 0xd7, 0x87, 0x87 },
    252 	{ 159, 0xd7, 0x87, 0xaf }, { 160, 0xd7, 0x87, 0xd7 },
    253 	{ 161, 0xd7, 0x87, 0xff }, { 162, 0xd7, 0xaf, 0x00 },
    254 	{ 163, 0xd7, 0xaf, 0x5f }, { 164, 0xd7, 0xaf, 0x87 },
    255 	{ 165, 0xd7, 0xaf, 0xaf }, { 166, 0xd7, 0xaf, 0xd7 },
    256 	{ 167, 0xd7, 0xaf, 0xff }, { 168, 0xd7, 0xd7, 0x00 },
    257 	{ 169, 0xd7, 0xd7, 0x5f }, { 170, 0xd7, 0xd7, 0x87 },
    258 	{ 171, 0xd7, 0xd7, 0xaf }, { 172, 0xd7, 0xd7, 0xd7 },
    259 	{ 173, 0xd7, 0xd7, 0xff }, { 174, 0xd7, 0xff, 0x00 },
    260 	{ 175, 0xd7, 0xff, 0x5f }, { 176, 0xd7, 0xff, 0x87 },
    261 	{ 177, 0xd7, 0xff, 0xaf }, { 178, 0xd7, 0xff, 0xd7 },
    262 	{ 179, 0xd7, 0xff, 0xff }, { 237, 0xda, 0xda, 0xda },
    263 	{ 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
    264 	{ 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
    265 	{ 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
    266 	{ 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
    267 	{ 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
    268 	{ 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
    269 	{ 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
    270 	{ 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
    271 	{ 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
    272 	{ 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
    273 	{ 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
    274 	{ 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
    275 	{ 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
    276 	{ 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
    277 	{ 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
    278 	{ 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
    279 	{ 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
    280 	{ 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
    281 	{ 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
    282 };
    283 
    284 int	colour_cmp_rgb(const void *, const void *);
    285 
    286 /* Compare function for bsearch(). */
    287 int
    288 colour_cmp_rgb(const void *lhs0, const void *rhs0)
    289 {
    290 	const struct colour_rgb *lhs = lhs0, *rhs = rhs0;
    291 
    292 	if (lhs->r < rhs->r)
    293 		return (-1);
    294 	if (lhs->r > rhs->r)
    295 		return (1);
    296 
    297 	if (lhs->g < rhs->g)
    298 		return (-1);
    299 	if (lhs->g > rhs->g)
    300 		return (1);
    301 
    302 	if (lhs->b < rhs->b)
    303 		return (-1);
    304 	if (lhs->b > rhs->b)
    305 		return (1);
    306 
    307 	return (0);
    308 }
    309 
    310 /* Work out the nearest colour from the 256 colour set. */
    311 int
    312 colour_find_rgb(u_char r, u_char g, u_char b)
    313 {
    314 	struct colour_rgb	rgb = { .r = r, .g = g, .b = b }, *found;
    315 	u_int			distance, lowest, colour, i;
    316 	int			dr, dg, db;
    317 
    318 	found = bsearch(&rgb, colour_to_256, nitems(colour_to_256),
    319 	    sizeof colour_to_256[0], colour_cmp_rgb);
    320 	if (found != NULL)
    321 		return (16 + found->i);
    322 
    323 	colour = 16;
    324 	lowest = UINT_MAX;
    325 	for (i = 0; i < 240; i++) {
    326 		dr = (int)colour_from_256[i].r - r;
    327 		dg = (int)colour_from_256[i].g - g;
    328 		db = (int)colour_from_256[i].b - b;
    329 
    330 		distance = dr * dr + dg * dg + db * db;
    331 		if (distance < lowest) {
    332 			lowest = distance;
    333 			colour = 16 + i;
    334 		}
    335 	}
    336 	return (colour);
    337 }
    338 
    339 /* Set grid cell foreground colour. */
    340 void
    341 colour_set_fg(struct grid_cell *gc, int c)
    342 {
    343 	if (c & 0x100)
    344 		gc->flags |= GRID_FLAG_FG256;
    345 	gc->fg = c;
    346 }
    347 
    348 /* Set grid cell background colour. */
    349 void
    350 colour_set_bg(struct grid_cell *gc, int c)
    351 {
    352 	if (c & 0x100)
    353 		gc->flags |= GRID_FLAG_BG256;
    354 	gc->bg = c;
    355 }
    356 
    357 /* Convert colour to a string. */
    358 const char *
    359 colour_tostring(int c)
    360 {
    361 	static char	s[32];
    362 
    363 	if (c & 0x100) {
    364 		xsnprintf(s, sizeof s, "colour%d", c & ~0x100);
    365 		return (s);
    366 	}
    367 
    368 	switch (c) {
    369 	case 0:
    370 		return ("black");
    371 	case 1:
    372 		return ("red");
    373 	case 2:
    374 		return ("green");
    375 	case 3:
    376 		return ("yellow");
    377 	case 4:
    378 		return ("blue");
    379 	case 5:
    380 		return ("magenta");
    381 	case 6:
    382 		return ("cyan");
    383 	case 7:
    384 		return ("white");
    385 	case 8:
    386 		return ("default");
    387 	case 90:
    388 		return ("brightblack");
    389 	case 91:
    390 		return ("brightred");
    391 	case 92:
    392 		return ("brightgreen");
    393 	case 93:
    394 		return ("brightyellow");
    395 	case 94:
    396 		return ("brightblue");
    397 	case 95:
    398 		return ("brightmagenta");
    399 	case 96:
    400 		return ("brightcyan");
    401 	case 97:
    402 		return ("brightwhite");
    403 	}
    404 	return (NULL);
    405 }
    406 
    407 /* Convert colour from string. */
    408 int
    409 colour_fromstring(const char *s)
    410 {
    411 	const char	*errstr;
    412 	const char	*cp;
    413 	int		 n;
    414 	u_char		 r, g, b;
    415 
    416 	if (*s == '#' && strlen(s) == 7) {
    417 		for (cp = s + 1; isxdigit((u_char) *cp); cp++)
    418 			;
    419 		if (*cp != '\0')
    420 			return (-1);
    421 		n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &r, &g, &b);
    422 		if (n != 3)
    423 			return (-1);
    424 		return (colour_find_rgb(r, g, b) | 0x100);
    425 	}
    426 
    427 	if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
    428 		n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr);
    429 		if (errstr != NULL)
    430 			return (-1);
    431 		return (n | 0x100);
    432 	}
    433 
    434 	if (strcasecmp(s, "black") == 0 || strcmp(s, "0") == 0)
    435 		return (0);
    436 	if (strcasecmp(s, "red") == 0 || strcmp(s, "1") == 0)
    437 		return (1);
    438 	if (strcasecmp(s, "green") == 0 || strcmp(s, "2") == 0)
    439 		return (2);
    440 	if (strcasecmp(s, "yellow") == 0 || strcmp(s, "3") == 0)
    441 		return (3);
    442 	if (strcasecmp(s, "blue") == 0 || strcmp(s, "4") == 0)
    443 		return (4);
    444 	if (strcasecmp(s, "magenta") == 0 || strcmp(s, "5") == 0)
    445 		return (5);
    446 	if (strcasecmp(s, "cyan") == 0 || strcmp(s, "6") == 0)
    447 		return (6);
    448 	if (strcasecmp(s, "white") == 0 || strcmp(s, "7") == 0)
    449 		return (7);
    450 	if (strcasecmp(s, "default") == 0 || strcmp(s, "8") == 0)
    451 		return (8);
    452 	if (strcasecmp(s, "brightblack") == 0 || strcmp(s, "90") == 0)
    453 		return (90);
    454 	if (strcasecmp(s, "brightred") == 0 || strcmp(s, "91") == 0)
    455 		return (91);
    456 	if (strcasecmp(s, "brightgreen") == 0 || strcmp(s, "92") == 0)
    457 		return (92);
    458 	if (strcasecmp(s, "brightyellow") == 0 || strcmp(s, "93") == 0)
    459 		return (93);
    460 	if (strcasecmp(s, "brightblue") == 0 || strcmp(s, "94") == 0)
    461 		return (94);
    462 	if (strcasecmp(s, "brightmagenta") == 0 || strcmp(s, "95") == 0)
    463 		return (95);
    464 	if (strcasecmp(s, "brightcyan") == 0 || strcmp(s, "96") == 0)
    465 		return (96);
    466 	if (strcasecmp(s, "brightwhite") == 0 || strcmp(s, "97") == 0)
    467 		return (97);
    468 	return (-1);
    469 }
    470 
    471 /* Convert 256 colour palette to 16. */
    472 u_char
    473 colour_256to16(u_char c)
    474 {
    475 	static const u_char table[256] = {
    476 		 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    477 		 0,  4,  4,  4, 12, 12,  2,  6,  4,  4, 12, 12,  2,  2,  6,  4,
    478 		12, 12,  2,  2,  2,  6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
    479 		10, 10, 10, 14,  1,  5,  4,  4, 12, 12,  3,  8,  4,  4, 12, 12,
    480 		 2,  2,  6,  4, 12, 12,  2,  2,  2,  6, 12, 12, 10, 10, 10, 10,
    481 		14, 12, 10, 10, 10, 10, 10, 14,  1,  1,  5,  4, 12, 12,  1,  1,
    482 		 5,  4, 12, 12,  3,  3,  8,  4, 12, 12,  2,  2,  2,  6, 12, 12,
    483 		10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,  1,  1,  1,  5,
    484 		12, 12,  1,  1,  1,  5, 12, 12,  1,  1,  1,  5, 12, 12,  3,  3,
    485 		 3,  7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,
    486 		 9,  9,  9,  9, 13, 12,  9,  9,  9,  9, 13, 12,  9,  9,  9,  9,
    487 		13, 12,  9,  9,  9,  9, 13, 12, 11, 11, 11, 11,  7, 12, 10, 10,
    488 		10, 10, 10, 14,  9,  9,  9,  9,  9, 13,  9,  9,  9,  9,  9, 13,
    489 		 9,  9,  9,  9,  9, 13,  9,  9,  9,  9,  9, 13,  9,  9,  9,  9,
    490 		 9, 13, 11, 11, 11, 11, 11, 15,  0,  0,  0,  0,  0,  0,  8,  8,
    491 		 8,  8,  8,  8,  7,  7,  7,  7,  7,  7, 15, 15, 15, 15, 15, 15
    492 	};
    493 
    494 	return (table[c]);
    495 }
    496