1 /* $OpenBSD$ */ 2 3 /* 4 * Copyright (c) 2008 Nicholas Marriott <nicm@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