1 /* $OpenBSD$ */ 2 3 /* 4 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott (at) gmail.com> 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 #include <sys/time.h> 21 22 #include <netinet/in.h> 23 24 #include <ctype.h> 25 #include <limits.h> 26 #include <resolv.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <termios.h> 30 #include <unistd.h> 31 32 #include "tmux.h" 33 34 /* 35 * Handle keys input from the outside terminal. tty_default_*_keys[] are a base 36 * table of supported keys which are looked up in terminfo(5) and translated 37 * into a ternary tree. 38 */ 39 40 static void tty_keys_add1(struct tty_key **, const char *, key_code); 41 static void tty_keys_add(struct tty *, const char *, key_code); 42 static void tty_keys_free1(struct tty_key *); 43 static struct tty_key *tty_keys_find1(struct tty_key *, const char *, size_t, 44 size_t *); 45 static struct tty_key *tty_keys_find(struct tty *, const char *, size_t, 46 size_t *); 47 static int tty_keys_next1(struct tty *, const char *, size_t, key_code *, 48 size_t *, int); 49 static void tty_keys_callback(int, short, void *); 50 static int tty_keys_extended_key(struct tty *, const char *, size_t, 51 size_t *, key_code *); 52 static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *, 53 struct mouse_event *); 54 static int tty_keys_clipboard(struct tty *, const char *, size_t, 55 size_t *); 56 static int tty_keys_device_attributes(struct tty *, const char *, size_t, 57 size_t *); 58 static int tty_keys_device_attributes2(struct tty *, const char *, size_t, 59 size_t *); 60 static int tty_keys_extended_device_attributes(struct tty *, const char *, 61 size_t, size_t *); 62 static int tty_keys_palette(struct tty *, const char *, size_t, size_t *); 63 64 /* A key tree entry. */ 65 struct tty_key { 66 char ch; 67 key_code key; 68 69 struct tty_key *left; 70 struct tty_key *right; 71 72 struct tty_key *next; 73 }; 74 75 /* Default raw keys. */ 76 struct tty_default_key_raw { 77 const char *string; 78 key_code key; 79 }; 80 static const struct tty_default_key_raw tty_default_raw_keys[] = { 81 /* Application escape. */ 82 { "\033O[", '\033' }, 83 84 /* 85 * Numeric keypad. Just use the vt100 escape sequences here and always 86 * put the terminal into keypad_xmit mode. Translation of numbers 87 * mode/applications mode is done in input-keys.c. 88 */ 89 { "\033Oo", KEYC_KP_SLASH|KEYC_KEYPAD }, 90 { "\033Oj", KEYC_KP_STAR|KEYC_KEYPAD }, 91 { "\033Om", KEYC_KP_MINUS|KEYC_KEYPAD }, 92 { "\033Ow", KEYC_KP_SEVEN|KEYC_KEYPAD }, 93 { "\033Ox", KEYC_KP_EIGHT|KEYC_KEYPAD }, 94 { "\033Oy", KEYC_KP_NINE|KEYC_KEYPAD }, 95 { "\033Ok", KEYC_KP_PLUS|KEYC_KEYPAD }, 96 { "\033Ot", KEYC_KP_FOUR|KEYC_KEYPAD }, 97 { "\033Ou", KEYC_KP_FIVE|KEYC_KEYPAD }, 98 { "\033Ov", KEYC_KP_SIX|KEYC_KEYPAD }, 99 { "\033Oq", KEYC_KP_ONE|KEYC_KEYPAD }, 100 { "\033Or", KEYC_KP_TWO|KEYC_KEYPAD }, 101 { "\033Os", KEYC_KP_THREE|KEYC_KEYPAD }, 102 { "\033OM", KEYC_KP_ENTER|KEYC_KEYPAD }, 103 { "\033Op", KEYC_KP_ZERO|KEYC_KEYPAD }, 104 { "\033On", KEYC_KP_PERIOD|KEYC_KEYPAD }, 105 106 /* Arrow keys. */ 107 { "\033OA", KEYC_UP|KEYC_CURSOR }, 108 { "\033OB", KEYC_DOWN|KEYC_CURSOR }, 109 { "\033OC", KEYC_RIGHT|KEYC_CURSOR }, 110 { "\033OD", KEYC_LEFT|KEYC_CURSOR }, 111 112 { "\033[A", KEYC_UP|KEYC_CURSOR }, 113 { "\033[B", KEYC_DOWN|KEYC_CURSOR }, 114 { "\033[C", KEYC_RIGHT|KEYC_CURSOR }, 115 { "\033[D", KEYC_LEFT|KEYC_CURSOR }, 116 117 /* 118 * Meta arrow keys. These do not get the IMPLIED_META flag so they 119 * don't match the xterm-style meta keys in the output tree - Escape+Up 120 * should stay as Escape+Up and not become M-Up. 121 */ 122 { "\033\033OA", KEYC_UP|KEYC_CURSOR|KEYC_META }, 123 { "\033\033OB", KEYC_DOWN|KEYC_CURSOR|KEYC_META }, 124 { "\033\033OC", KEYC_RIGHT|KEYC_CURSOR|KEYC_META }, 125 { "\033\033OD", KEYC_LEFT|KEYC_CURSOR|KEYC_META }, 126 127 { "\033\033[A", KEYC_UP|KEYC_CURSOR|KEYC_META }, 128 { "\033\033[B", KEYC_DOWN|KEYC_CURSOR|KEYC_META }, 129 { "\033\033[C", KEYC_RIGHT|KEYC_CURSOR|KEYC_META }, 130 { "\033\033[D", KEYC_LEFT|KEYC_CURSOR|KEYC_META }, 131 132 /* Other xterm keys. */ 133 { "\033OH", KEYC_HOME }, 134 { "\033OF", KEYC_END }, 135 136 { "\033\033OH", KEYC_HOME|KEYC_META|KEYC_IMPLIED_META }, 137 { "\033\033OF", KEYC_END|KEYC_META|KEYC_IMPLIED_META }, 138 139 { "\033[H", KEYC_HOME }, 140 { "\033[F", KEYC_END }, 141 142 { "\033\033[H", KEYC_HOME|KEYC_META|KEYC_IMPLIED_META }, 143 { "\033\033[F", KEYC_END|KEYC_META|KEYC_IMPLIED_META }, 144 145 /* rxvt arrow keys. */ 146 { "\033Oa", KEYC_UP|KEYC_CTRL }, 147 { "\033Ob", KEYC_DOWN|KEYC_CTRL }, 148 { "\033Oc", KEYC_RIGHT|KEYC_CTRL }, 149 { "\033Od", KEYC_LEFT|KEYC_CTRL }, 150 151 { "\033[a", KEYC_UP|KEYC_SHIFT }, 152 { "\033[b", KEYC_DOWN|KEYC_SHIFT }, 153 { "\033[c", KEYC_RIGHT|KEYC_SHIFT }, 154 { "\033[d", KEYC_LEFT|KEYC_SHIFT }, 155 156 /* rxvt function keys. */ 157 { "\033[11~", KEYC_F1 }, 158 { "\033[12~", KEYC_F2 }, 159 { "\033[13~", KEYC_F3 }, 160 { "\033[14~", KEYC_F4 }, 161 { "\033[15~", KEYC_F5 }, 162 { "\033[17~", KEYC_F6 }, 163 { "\033[18~", KEYC_F7 }, 164 { "\033[19~", KEYC_F8 }, 165 { "\033[20~", KEYC_F9 }, 166 { "\033[21~", KEYC_F10 }, 167 168 { "\033[23~", KEYC_F1|KEYC_SHIFT }, 169 { "\033[24~", KEYC_F2|KEYC_SHIFT }, 170 { "\033[25~", KEYC_F3|KEYC_SHIFT }, 171 { "\033[26~", KEYC_F4|KEYC_SHIFT }, 172 { "\033[28~", KEYC_F5|KEYC_SHIFT }, 173 { "\033[29~", KEYC_F6|KEYC_SHIFT }, 174 { "\033[31~", KEYC_F7|KEYC_SHIFT }, 175 { "\033[32~", KEYC_F8|KEYC_SHIFT }, 176 { "\033[33~", KEYC_F9|KEYC_SHIFT }, 177 { "\033[34~", KEYC_F10|KEYC_SHIFT }, 178 { "\033[23$", KEYC_F11|KEYC_SHIFT }, 179 { "\033[24$", KEYC_F12|KEYC_SHIFT }, 180 181 { "\033[11^", KEYC_F1|KEYC_CTRL }, 182 { "\033[12^", KEYC_F2|KEYC_CTRL }, 183 { "\033[13^", KEYC_F3|KEYC_CTRL }, 184 { "\033[14^", KEYC_F4|KEYC_CTRL }, 185 { "\033[15^", KEYC_F5|KEYC_CTRL }, 186 { "\033[17^", KEYC_F6|KEYC_CTRL }, 187 { "\033[18^", KEYC_F7|KEYC_CTRL }, 188 { "\033[19^", KEYC_F8|KEYC_CTRL }, 189 { "\033[20^", KEYC_F9|KEYC_CTRL }, 190 { "\033[21^", KEYC_F10|KEYC_CTRL }, 191 { "\033[23^", KEYC_F11|KEYC_CTRL }, 192 { "\033[24^", KEYC_F12|KEYC_CTRL }, 193 194 { "\033[11@", KEYC_F1|KEYC_CTRL|KEYC_SHIFT }, 195 { "\033[12@", KEYC_F2|KEYC_CTRL|KEYC_SHIFT }, 196 { "\033[13@", KEYC_F3|KEYC_CTRL|KEYC_SHIFT }, 197 { "\033[14@", KEYC_F4|KEYC_CTRL|KEYC_SHIFT }, 198 { "\033[15@", KEYC_F5|KEYC_CTRL|KEYC_SHIFT }, 199 { "\033[17@", KEYC_F6|KEYC_CTRL|KEYC_SHIFT }, 200 { "\033[18@", KEYC_F7|KEYC_CTRL|KEYC_SHIFT }, 201 { "\033[19@", KEYC_F8|KEYC_CTRL|KEYC_SHIFT }, 202 { "\033[20@", KEYC_F9|KEYC_CTRL|KEYC_SHIFT }, 203 { "\033[21@", KEYC_F10|KEYC_CTRL|KEYC_SHIFT }, 204 { "\033[23@", KEYC_F11|KEYC_CTRL|KEYC_SHIFT }, 205 { "\033[24@", KEYC_F12|KEYC_CTRL|KEYC_SHIFT }, 206 207 /* Focus tracking. */ 208 { "\033[I", KEYC_FOCUS_IN }, 209 { "\033[O", KEYC_FOCUS_OUT }, 210 211 /* Paste keys. */ 212 { "\033[200~", KEYC_PASTE_START|KEYC_IMPLIED_META }, 213 { "\033[201~", KEYC_PASTE_END|KEYC_IMPLIED_META }, 214 215 /* Extended keys. */ 216 { "\033[1;5Z", '\011'|KEYC_CTRL|KEYC_SHIFT }, 217 218 /* Theme reporting. */ 219 { "\033[?997;1n", KEYC_REPORT_DARK_THEME }, 220 { "\033[?997;2n", KEYC_REPORT_LIGHT_THEME }, 221 }; 222 223 /* Default xterm keys. */ 224 struct tty_default_key_xterm { 225 const char *template; 226 key_code key; 227 }; 228 static const struct tty_default_key_xterm tty_default_xterm_keys[] = { 229 { "\033[1;_P", KEYC_F1 }, 230 { "\033O1;_P", KEYC_F1 }, 231 { "\033O_P", KEYC_F1 }, 232 { "\033[1;_Q", KEYC_F2 }, 233 { "\033O1;_Q", KEYC_F2 }, 234 { "\033O_Q", KEYC_F2 }, 235 { "\033[1;_R", KEYC_F3 }, 236 { "\033O1;_R", KEYC_F3 }, 237 { "\033O_R", KEYC_F3 }, 238 { "\033[1;_S", KEYC_F4 }, 239 { "\033O1;_S", KEYC_F4 }, 240 { "\033O_S", KEYC_F4 }, 241 { "\033[15;_~", KEYC_F5 }, 242 { "\033[17;_~", KEYC_F6 }, 243 { "\033[18;_~", KEYC_F7 }, 244 { "\033[19;_~", KEYC_F8 }, 245 { "\033[20;_~", KEYC_F9 }, 246 { "\033[21;_~", KEYC_F10 }, 247 { "\033[23;_~", KEYC_F11 }, 248 { "\033[24;_~", KEYC_F12 }, 249 { "\033[1;_A", KEYC_UP }, 250 { "\033[1;_B", KEYC_DOWN }, 251 { "\033[1;_C", KEYC_RIGHT }, 252 { "\033[1;_D", KEYC_LEFT }, 253 { "\033[1;_H", KEYC_HOME }, 254 { "\033[1;_F", KEYC_END }, 255 { "\033[5;_~", KEYC_PPAGE }, 256 { "\033[6;_~", KEYC_NPAGE }, 257 { "\033[2;_~", KEYC_IC }, 258 { "\033[3;_~", KEYC_DC }, 259 }; 260 static const key_code tty_default_xterm_modifiers[] = { 261 0, 262 0, 263 KEYC_SHIFT, 264 KEYC_META|KEYC_IMPLIED_META, 265 KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META, 266 KEYC_CTRL, 267 KEYC_SHIFT|KEYC_CTRL, 268 KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL, 269 KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL, 270 KEYC_META|KEYC_IMPLIED_META 271 }; 272 273 /* 274 * Default terminfo(5) keys. Any keys that have builtin modifiers (that is, 275 * where the key itself contains the modifiers) has the KEYC_XTERM flag set so 276 * a leading escape is not treated as meta (and probably removed). 277 */ 278 struct tty_default_key_code { 279 enum tty_code_code code; 280 key_code key; 281 }; 282 static const struct tty_default_key_code tty_default_code_keys[] = { 283 /* Function keys. */ 284 { TTYC_KF1, KEYC_F1 }, 285 { TTYC_KF2, KEYC_F2 }, 286 { TTYC_KF3, KEYC_F3 }, 287 { TTYC_KF4, KEYC_F4 }, 288 { TTYC_KF5, KEYC_F5 }, 289 { TTYC_KF6, KEYC_F6 }, 290 { TTYC_KF7, KEYC_F7 }, 291 { TTYC_KF8, KEYC_F8 }, 292 { TTYC_KF9, KEYC_F9 }, 293 { TTYC_KF10, KEYC_F10 }, 294 { TTYC_KF11, KEYC_F11 }, 295 { TTYC_KF12, KEYC_F12 }, 296 297 { TTYC_KF13, KEYC_F1|KEYC_SHIFT }, 298 { TTYC_KF14, KEYC_F2|KEYC_SHIFT }, 299 { TTYC_KF15, KEYC_F3|KEYC_SHIFT }, 300 { TTYC_KF16, KEYC_F4|KEYC_SHIFT }, 301 { TTYC_KF17, KEYC_F5|KEYC_SHIFT }, 302 { TTYC_KF18, KEYC_F6|KEYC_SHIFT }, 303 { TTYC_KF19, KEYC_F7|KEYC_SHIFT }, 304 { TTYC_KF20, KEYC_F8|KEYC_SHIFT }, 305 { TTYC_KF21, KEYC_F9|KEYC_SHIFT }, 306 { TTYC_KF22, KEYC_F10|KEYC_SHIFT }, 307 { TTYC_KF23, KEYC_F11|KEYC_SHIFT }, 308 { TTYC_KF24, KEYC_F12|KEYC_SHIFT }, 309 310 { TTYC_KF25, KEYC_F1|KEYC_CTRL }, 311 { TTYC_KF26, KEYC_F2|KEYC_CTRL }, 312 { TTYC_KF27, KEYC_F3|KEYC_CTRL }, 313 { TTYC_KF28, KEYC_F4|KEYC_CTRL }, 314 { TTYC_KF29, KEYC_F5|KEYC_CTRL }, 315 { TTYC_KF30, KEYC_F6|KEYC_CTRL }, 316 { TTYC_KF31, KEYC_F7|KEYC_CTRL }, 317 { TTYC_KF32, KEYC_F8|KEYC_CTRL }, 318 { TTYC_KF33, KEYC_F9|KEYC_CTRL }, 319 { TTYC_KF34, KEYC_F10|KEYC_CTRL }, 320 { TTYC_KF35, KEYC_F11|KEYC_CTRL }, 321 { TTYC_KF36, KEYC_F12|KEYC_CTRL }, 322 323 { TTYC_KF37, KEYC_F1|KEYC_SHIFT|KEYC_CTRL }, 324 { TTYC_KF38, KEYC_F2|KEYC_SHIFT|KEYC_CTRL }, 325 { TTYC_KF39, KEYC_F3|KEYC_SHIFT|KEYC_CTRL }, 326 { TTYC_KF40, KEYC_F4|KEYC_SHIFT|KEYC_CTRL }, 327 { TTYC_KF41, KEYC_F5|KEYC_SHIFT|KEYC_CTRL }, 328 { TTYC_KF42, KEYC_F6|KEYC_SHIFT|KEYC_CTRL }, 329 { TTYC_KF43, KEYC_F7|KEYC_SHIFT|KEYC_CTRL }, 330 { TTYC_KF44, KEYC_F8|KEYC_SHIFT|KEYC_CTRL }, 331 { TTYC_KF45, KEYC_F9|KEYC_SHIFT|KEYC_CTRL }, 332 { TTYC_KF46, KEYC_F10|KEYC_SHIFT|KEYC_CTRL }, 333 { TTYC_KF47, KEYC_F11|KEYC_SHIFT|KEYC_CTRL }, 334 { TTYC_KF48, KEYC_F12|KEYC_SHIFT|KEYC_CTRL }, 335 336 { TTYC_KF49, KEYC_F1|KEYC_META|KEYC_IMPLIED_META }, 337 { TTYC_KF50, KEYC_F2|KEYC_META|KEYC_IMPLIED_META }, 338 { TTYC_KF51, KEYC_F3|KEYC_META|KEYC_IMPLIED_META }, 339 { TTYC_KF52, KEYC_F4|KEYC_META|KEYC_IMPLIED_META }, 340 { TTYC_KF53, KEYC_F5|KEYC_META|KEYC_IMPLIED_META }, 341 { TTYC_KF54, KEYC_F6|KEYC_META|KEYC_IMPLIED_META }, 342 { TTYC_KF55, KEYC_F7|KEYC_META|KEYC_IMPLIED_META }, 343 { TTYC_KF56, KEYC_F8|KEYC_META|KEYC_IMPLIED_META }, 344 { TTYC_KF57, KEYC_F9|KEYC_META|KEYC_IMPLIED_META }, 345 { TTYC_KF58, KEYC_F10|KEYC_META|KEYC_IMPLIED_META }, 346 { TTYC_KF59, KEYC_F11|KEYC_META|KEYC_IMPLIED_META }, 347 { TTYC_KF60, KEYC_F12|KEYC_META|KEYC_IMPLIED_META }, 348 349 { TTYC_KF61, KEYC_F1|KEYC_META|KEYC_IMPLIED_META|KEYC_SHIFT }, 350 { TTYC_KF62, KEYC_F2|KEYC_META|KEYC_IMPLIED_META|KEYC_SHIFT }, 351 { TTYC_KF63, KEYC_F3|KEYC_META|KEYC_IMPLIED_META|KEYC_SHIFT }, 352 353 { TTYC_KICH1, KEYC_IC }, 354 { TTYC_KDCH1, KEYC_DC }, 355 { TTYC_KHOME, KEYC_HOME }, 356 { TTYC_KEND, KEYC_END }, 357 { TTYC_KNP, KEYC_NPAGE }, 358 { TTYC_KPP, KEYC_PPAGE }, 359 { TTYC_KCBT, KEYC_BTAB }, 360 361 /* Arrow keys from terminfo. */ 362 { TTYC_KCUU1, KEYC_UP|KEYC_CURSOR }, 363 { TTYC_KCUD1, KEYC_DOWN|KEYC_CURSOR }, 364 { TTYC_KCUB1, KEYC_LEFT|KEYC_CURSOR }, 365 { TTYC_KCUF1, KEYC_RIGHT|KEYC_CURSOR }, 366 367 /* Key and modifier capabilities. */ 368 { TTYC_KDC2, KEYC_DC|KEYC_SHIFT }, 369 { TTYC_KDC3, KEYC_DC|KEYC_META|KEYC_IMPLIED_META }, 370 { TTYC_KDC4, KEYC_DC|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 371 { TTYC_KDC5, KEYC_DC|KEYC_CTRL }, 372 { TTYC_KDC6, KEYC_DC|KEYC_SHIFT|KEYC_CTRL }, 373 { TTYC_KDC7, KEYC_DC|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 374 { TTYC_KIND, KEYC_DOWN|KEYC_SHIFT }, 375 { TTYC_KDN2, KEYC_DOWN|KEYC_SHIFT }, 376 { TTYC_KDN3, KEYC_DOWN|KEYC_META|KEYC_IMPLIED_META }, 377 { TTYC_KDN4, KEYC_DOWN|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 378 { TTYC_KDN5, KEYC_DOWN|KEYC_CTRL }, 379 { TTYC_KDN6, KEYC_DOWN|KEYC_SHIFT|KEYC_CTRL }, 380 { TTYC_KDN7, KEYC_DOWN|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 381 { TTYC_KEND2, KEYC_END|KEYC_SHIFT }, 382 { TTYC_KEND3, KEYC_END|KEYC_META|KEYC_IMPLIED_META }, 383 { TTYC_KEND4, KEYC_END|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 384 { TTYC_KEND5, KEYC_END|KEYC_CTRL }, 385 { TTYC_KEND6, KEYC_END|KEYC_SHIFT|KEYC_CTRL }, 386 { TTYC_KEND7, KEYC_END|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 387 { TTYC_KHOM2, KEYC_HOME|KEYC_SHIFT }, 388 { TTYC_KHOM3, KEYC_HOME|KEYC_META|KEYC_IMPLIED_META }, 389 { TTYC_KHOM4, KEYC_HOME|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 390 { TTYC_KHOM5, KEYC_HOME|KEYC_CTRL }, 391 { TTYC_KHOM6, KEYC_HOME|KEYC_SHIFT|KEYC_CTRL }, 392 { TTYC_KHOM7, KEYC_HOME|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 393 { TTYC_KIC2, KEYC_IC|KEYC_SHIFT }, 394 { TTYC_KIC3, KEYC_IC|KEYC_META|KEYC_IMPLIED_META }, 395 { TTYC_KIC4, KEYC_IC|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 396 { TTYC_KIC5, KEYC_IC|KEYC_CTRL }, 397 { TTYC_KIC6, KEYC_IC|KEYC_SHIFT|KEYC_CTRL }, 398 { TTYC_KIC7, KEYC_IC|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 399 { TTYC_KLFT2, KEYC_LEFT|KEYC_SHIFT }, 400 { TTYC_KLFT3, KEYC_LEFT|KEYC_META|KEYC_IMPLIED_META }, 401 { TTYC_KLFT4, KEYC_LEFT|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 402 { TTYC_KLFT5, KEYC_LEFT|KEYC_CTRL }, 403 { TTYC_KLFT6, KEYC_LEFT|KEYC_SHIFT|KEYC_CTRL }, 404 { TTYC_KLFT7, KEYC_LEFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 405 { TTYC_KNXT2, KEYC_NPAGE|KEYC_SHIFT }, 406 { TTYC_KNXT3, KEYC_NPAGE|KEYC_META|KEYC_IMPLIED_META }, 407 { TTYC_KNXT4, KEYC_NPAGE|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 408 { TTYC_KNXT5, KEYC_NPAGE|KEYC_CTRL }, 409 { TTYC_KNXT6, KEYC_NPAGE|KEYC_SHIFT|KEYC_CTRL }, 410 { TTYC_KNXT7, KEYC_NPAGE|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 411 { TTYC_KPRV2, KEYC_PPAGE|KEYC_SHIFT }, 412 { TTYC_KPRV3, KEYC_PPAGE|KEYC_META|KEYC_IMPLIED_META }, 413 { TTYC_KPRV4, KEYC_PPAGE|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 414 { TTYC_KPRV5, KEYC_PPAGE|KEYC_CTRL }, 415 { TTYC_KPRV6, KEYC_PPAGE|KEYC_SHIFT|KEYC_CTRL }, 416 { TTYC_KPRV7, KEYC_PPAGE|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 417 { TTYC_KRIT2, KEYC_RIGHT|KEYC_SHIFT }, 418 { TTYC_KRIT3, KEYC_RIGHT|KEYC_META|KEYC_IMPLIED_META }, 419 { TTYC_KRIT4, KEYC_RIGHT|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 420 { TTYC_KRIT5, KEYC_RIGHT|KEYC_CTRL }, 421 { TTYC_KRIT6, KEYC_RIGHT|KEYC_SHIFT|KEYC_CTRL }, 422 { TTYC_KRIT7, KEYC_RIGHT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 423 { TTYC_KRI, KEYC_UP|KEYC_SHIFT }, 424 { TTYC_KUP2, KEYC_UP|KEYC_SHIFT }, 425 { TTYC_KUP3, KEYC_UP|KEYC_META|KEYC_IMPLIED_META }, 426 { TTYC_KUP4, KEYC_UP|KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META }, 427 { TTYC_KUP5, KEYC_UP|KEYC_CTRL }, 428 { TTYC_KUP6, KEYC_UP|KEYC_SHIFT|KEYC_CTRL }, 429 { TTYC_KUP7, KEYC_UP|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL }, 430 }; 431 432 /* Add key to tree. */ 433 static void 434 tty_keys_add(struct tty *tty, const char *s, key_code key) 435 { 436 struct tty_key *tk; 437 size_t size; 438 const char *keystr; 439 440 keystr = key_string_lookup_key(key, 1); 441 if ((tk = tty_keys_find(tty, s, strlen(s), &size)) == NULL) { 442 log_debug("new key %s: 0x%llx (%s)", s, key, keystr); 443 tty_keys_add1(&tty->key_tree, s, key); 444 } else { 445 log_debug("replacing key %s: 0x%llx (%s)", s, key, keystr); 446 tk->key = key; 447 } 448 } 449 450 /* Add next node to the tree. */ 451 static void 452 tty_keys_add1(struct tty_key **tkp, const char *s, key_code key) 453 { 454 struct tty_key *tk; 455 456 /* Allocate a tree entry if there isn't one already. */ 457 tk = *tkp; 458 if (tk == NULL) { 459 tk = *tkp = xcalloc(1, sizeof *tk); 460 tk->ch = *s; 461 tk->key = KEYC_UNKNOWN; 462 } 463 464 /* Find the next entry. */ 465 if (*s == tk->ch) { 466 /* Move forward in string. */ 467 s++; 468 469 /* If this is the end of the string, no more is necessary. */ 470 if (*s == '\0') { 471 tk->key = key; 472 return; 473 } 474 475 /* Use the child tree for the next character. */ 476 tkp = &tk->next; 477 } else { 478 if (*s < tk->ch) 479 tkp = &tk->left; 480 else if (*s > tk->ch) 481 tkp = &tk->right; 482 } 483 484 /* And recurse to add it. */ 485 tty_keys_add1(tkp, s, key); 486 } 487 488 /* Initialise a key tree from the table. */ 489 void 490 tty_keys_build(struct tty *tty) 491 { 492 const struct tty_default_key_raw *tdkr; 493 const struct tty_default_key_xterm *tdkx; 494 const struct tty_default_key_code *tdkc; 495 u_int i, j; 496 const char *s; 497 struct options_entry *o; 498 struct options_array_item *a; 499 union options_value *ov; 500 char copy[16]; 501 key_code key; 502 503 if (tty->key_tree != NULL) 504 tty_keys_free(tty); 505 tty->key_tree = NULL; 506 507 for (i = 0; i < nitems(tty_default_xterm_keys); i++) { 508 tdkx = &tty_default_xterm_keys[i]; 509 for (j = 2; j < nitems(tty_default_xterm_modifiers); j++) { 510 strlcpy(copy, tdkx->template, sizeof copy); 511 copy[strcspn(copy, "_")] = '0' + j; 512 513 key = tdkx->key|tty_default_xterm_modifiers[j]; 514 tty_keys_add(tty, copy, key); 515 } 516 } 517 for (i = 0; i < nitems(tty_default_raw_keys); i++) { 518 tdkr = &tty_default_raw_keys[i]; 519 520 s = tdkr->string; 521 if (*s != '\0') 522 tty_keys_add(tty, s, tdkr->key); 523 } 524 for (i = 0; i < nitems(tty_default_code_keys); i++) { 525 tdkc = &tty_default_code_keys[i]; 526 527 s = tty_term_string(tty->term, tdkc->code); 528 if (*s != '\0') 529 tty_keys_add(tty, s, tdkc->key); 530 531 } 532 533 o = options_get(global_options, "user-keys"); 534 if (o != NULL) { 535 a = options_array_first(o); 536 while (a != NULL) { 537 i = options_array_item_index(a); 538 ov = options_array_item_value(a); 539 tty_keys_add(tty, ov->string, KEYC_USER + i); 540 a = options_array_next(a); 541 } 542 } 543 } 544 545 /* Free the entire key tree. */ 546 void 547 tty_keys_free(struct tty *tty) 548 { 549 tty_keys_free1(tty->key_tree); 550 } 551 552 /* Free a single key. */ 553 static void 554 tty_keys_free1(struct tty_key *tk) 555 { 556 if (tk->next != NULL) 557 tty_keys_free1(tk->next); 558 if (tk->left != NULL) 559 tty_keys_free1(tk->left); 560 if (tk->right != NULL) 561 tty_keys_free1(tk->right); 562 free(tk); 563 } 564 565 /* Lookup a key in the tree. */ 566 static struct tty_key * 567 tty_keys_find(struct tty *tty, const char *buf, size_t len, size_t *size) 568 { 569 *size = 0; 570 return (tty_keys_find1(tty->key_tree, buf, len, size)); 571 } 572 573 /* Find the next node. */ 574 static struct tty_key * 575 tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size) 576 { 577 /* If no data, no match. */ 578 if (len == 0) 579 return (NULL); 580 581 /* If the node is NULL, this is the end of the tree. No match. */ 582 if (tk == NULL) 583 return (NULL); 584 585 /* Pick the next in the sequence. */ 586 if (tk->ch == *buf) { 587 /* Move forward in the string. */ 588 buf++; len--; 589 (*size)++; 590 591 /* At the end of the string, return the current node. */ 592 if (len == 0 || (tk->next == NULL && tk->key != KEYC_UNKNOWN)) 593 return (tk); 594 595 /* Move into the next tree for the following character. */ 596 tk = tk->next; 597 } else { 598 if (*buf < tk->ch) 599 tk = tk->left; 600 else if (*buf > tk->ch) 601 tk = tk->right; 602 } 603 604 /* Move to the next in the tree. */ 605 return (tty_keys_find1(tk, buf, len, size)); 606 } 607 608 /* Look up part of the next key. */ 609 static int 610 tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key, 611 size_t *size, int expired) 612 { 613 struct client *c = tty->client; 614 struct tty_key *tk, *tk1; 615 struct utf8_data ud; 616 enum utf8_state more; 617 utf8_char uc; 618 u_int i; 619 620 log_debug("%s: next key is %zu (%.*s) (expired=%d)", c->name, len, 621 (int)len, buf, expired); 622 623 /* Is this a known key? */ 624 tk = tty_keys_find(tty, buf, len, size); 625 if (tk != NULL && tk->key != KEYC_UNKNOWN) { 626 tk1 = tk; 627 do 628 log_debug("%s: keys in list: %#llx", c->name, tk1->key); 629 while ((tk1 = tk1->next) != NULL); 630 if (tk->next != NULL && !expired) 631 return (1); 632 *key = tk->key; 633 return (0); 634 } 635 636 /* Is this valid UTF-8? */ 637 more = utf8_open(&ud, (u_char)*buf); 638 if (more == UTF8_MORE) { 639 *size = ud.size; 640 if (len < ud.size) { 641 if (!expired) 642 return (1); 643 return (-1); 644 } 645 for (i = 1; i < ud.size; i++) 646 more = utf8_append(&ud, (u_char)buf[i]); 647 if (more != UTF8_DONE) 648 return (-1); 649 650 if (utf8_from_data(&ud, &uc) != UTF8_DONE) 651 return (-1); 652 *key = uc; 653 654 log_debug("%s: UTF-8 key %.*s %#llx", c->name, (int)ud.size, 655 ud.data, *key); 656 return (0); 657 } 658 659 return (-1); 660 } 661 662 /* Process window size change escape sequences. */ 663 static int 664 tty_keys_winsz(struct tty *tty, const char *buf, size_t len, size_t *size) 665 { 666 struct client *c = tty->client; 667 size_t end; 668 char tmp[64]; 669 u_int sx, sy, xpixel, ypixel, char_x, char_y; 670 671 *size = 0; 672 673 /* If we did not request this, ignore it. */ 674 if (!(tty->flags & TTY_WINSIZEQUERY)) 675 return (-1); 676 677 /* First two bytes are always \033[. */ 678 if (buf[0] != '\033') 679 return (-1); 680 if (len == 1) 681 return (1); 682 if (buf[1] != '[') 683 return (-1); 684 if (len == 2) 685 return (1); 686 687 /* 688 * Stop at either 't' or anything that isn't a 689 * number or ';'. 690 */ 691 for (end = 2; end < len && end != sizeof tmp; end++) { 692 if (buf[end] == 't') 693 break; 694 if (!isdigit((u_char)buf[end]) && buf[end] != ';') 695 break; 696 } 697 if (end == len) 698 return (1); 699 if (end == sizeof tmp || buf[end] != 't') 700 return (-1); 701 702 /* Copy to the buffer. */ 703 memcpy(tmp, buf + 2, end - 2); 704 tmp[end - 2] = '\0'; 705 706 /* Try to parse the window size sequence. */ 707 if (sscanf(tmp, "8;%u;%u", &sy, &sx) == 2) { 708 /* Window size in characters. */ 709 tty_set_size(tty, sx, sy, tty->xpixel, tty->ypixel); 710 711 *size = end + 1; 712 return (0); 713 } else if (sscanf(tmp, "4;%u;%u", &ypixel, &xpixel) == 2) { 714 /* Window size in pixels. */ 715 char_x = (xpixel && tty->sx) ? xpixel / tty->sx : 0; 716 char_y = (ypixel && tty->sy) ? ypixel / tty->sy : 0; 717 tty_set_size(tty, tty->sx, tty->sy, char_x, char_y); 718 tty_invalidate(tty); 719 720 tty->flags &= ~TTY_WINSIZEQUERY; 721 *size = end + 1; 722 return (0); 723 } 724 725 log_debug("%s: unrecognized window size sequence: %s", c->name, tmp); 726 return (-1); 727 } 728 729 730 /* Process at least one key in the buffer. Return 0 if no keys present. */ 731 int 732 tty_keys_next(struct tty *tty) 733 { 734 struct client *c = tty->client; 735 struct timeval tv; 736 const char *buf; 737 size_t len, size; 738 cc_t bspace; 739 int delay, expired = 0, n; 740 key_code key, onlykey; 741 struct mouse_event m = { 0 }; 742 struct key_event *event; 743 744 /* Get key buffer. */ 745 buf = (const char *)EVBUFFER_DATA(tty->in); 746 len = EVBUFFER_LENGTH(tty->in); 747 if (len == 0) 748 return (0); 749 log_debug("%s: keys are %zu (%.*s)", c->name, len, (int)len, buf); 750 751 /* Is this a clipboard response? */ 752 switch (tty_keys_clipboard(tty, buf, len, &size)) { 753 case 0: /* yes */ 754 key = KEYC_UNKNOWN; 755 goto complete_key; 756 case -1: /* no, or not valid */ 757 break; 758 case 1: /* partial */ 759 goto partial_key; 760 } 761 762 /* Is this a primary device attributes response? */ 763 switch (tty_keys_device_attributes(tty, buf, len, &size)) { 764 case 0: /* yes */ 765 key = KEYC_UNKNOWN; 766 goto complete_key; 767 case -1: /* no, or not valid */ 768 break; 769 case 1: /* partial */ 770 goto partial_key; 771 } 772 773 /* Is this a secondary device attributes response? */ 774 switch (tty_keys_device_attributes2(tty, buf, len, &size)) { 775 case 0: /* yes */ 776 key = KEYC_UNKNOWN; 777 goto complete_key; 778 case -1: /* no, or not valid */ 779 break; 780 case 1: /* partial */ 781 goto partial_key; 782 } 783 784 /* Is this an extended device attributes response? */ 785 switch (tty_keys_extended_device_attributes(tty, buf, len, &size)) { 786 case 0: /* yes */ 787 key = KEYC_UNKNOWN; 788 goto complete_key; 789 case -1: /* no, or not valid */ 790 break; 791 case 1: /* partial */ 792 goto partial_key; 793 } 794 795 /* Is this a colours response? */ 796 switch (tty_keys_colours(tty, buf, len, &size, &tty->fg, &tty->bg)) { 797 case 0: /* yes */ 798 key = KEYC_UNKNOWN; 799 session_theme_changed(c->session); 800 goto complete_key; 801 case -1: /* no, or not valid */ 802 break; 803 case 1: /* partial */ 804 session_theme_changed(c->session); 805 goto partial_key; 806 } 807 808 /* Is this a palette response? */ 809 switch (tty_keys_palette(tty, buf, len, &size)) { 810 case 0: /* yes */ 811 key = KEYC_UNKNOWN; 812 goto complete_key; 813 case -1: /* no, or not valid */ 814 break; 815 case 1: /* partial */ 816 goto partial_key; 817 } 818 819 /* Is this a mouse key press? */ 820 switch (tty_keys_mouse(tty, buf, len, &size, &m)) { 821 case 0: /* yes */ 822 key = KEYC_MOUSE; 823 goto complete_key; 824 case -1: /* no, or not valid */ 825 break; 826 case -2: /* yes, but we don't care. */ 827 key = KEYC_MOUSE; 828 goto discard_key; 829 case 1: /* partial */ 830 goto partial_key; 831 } 832 833 /* Is this an extended key press? */ 834 switch (tty_keys_extended_key(tty, buf, len, &size, &key)) { 835 case 0: /* yes */ 836 goto complete_key; 837 case -1: /* no, or not valid */ 838 break; 839 case 1: /* partial */ 840 goto partial_key; 841 } 842 843 /* Check for window size query */ 844 switch (tty_keys_winsz(tty, buf, len, &size)) { 845 case 0: /* yes */ 846 key = KEYC_UNKNOWN; 847 goto complete_key; 848 case -1: /* no, or not valid */ 849 break; 850 case 1: /* partial */ 851 goto partial_key; 852 } 853 854 first_key: 855 /* Try to lookup complete key. */ 856 n = tty_keys_next1(tty, buf, len, &key, &size, expired); 857 if (n == 0) /* found */ 858 goto complete_key; 859 if (n == 1) 860 goto partial_key; 861 862 /* 863 * If not a complete key, look for key with an escape prefix (meta 864 * modifier). 865 */ 866 if (*buf == '\033' && len > 1) { 867 /* Look for a key without the escape. */ 868 n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired); 869 if (n == 0) { /* found */ 870 if (key & KEYC_IMPLIED_META) { 871 /* 872 * We want the escape key as well as the xterm 873 * key, because the xterm sequence implicitly 874 * includes the escape (so if we see 875 * \033\033[1;3D we know it is an Escape 876 * followed by M-Left, not just M-Left). 877 */ 878 key = '\033'; 879 size = 1; 880 goto complete_key; 881 } 882 key |= KEYC_META; 883 size++; 884 goto complete_key; 885 } 886 if (n == 1) /* partial */ 887 goto partial_key; 888 } 889 890 /* 891 * At this point, we know the key is not partial (with or without 892 * escape). So pass it through even if the timer has not expired. 893 */ 894 if (*buf == '\033' && len >= 2) { 895 key = (u_char)buf[1] | KEYC_META; 896 size = 2; 897 } else { 898 key = (u_char)buf[0]; 899 size = 1; 900 } 901 902 /* C-Space is special. */ 903 if ((key & KEYC_MASK_KEY) == C0_NUL) 904 key = ' ' | KEYC_CTRL | (key & KEYC_META); 905 906 /* 907 * Check for backspace key using termios VERASE - the terminfo 908 * kbs entry is extremely unreliable, so cannot be safely 909 * used. termios should have a better idea. 910 */ 911 bspace = tty->tio.c_cc[VERASE]; 912 if (bspace != _POSIX_VDISABLE && key == bspace) { 913 log_debug("%s: key %#llx is backspace", c->name, key); 914 key = KEYC_BSPACE; 915 } 916 917 /* 918 * Fix up all C0 control codes that don't have a dedicated key into 919 * corresponding Ctrl keys. Convert characters in the A-Z range into 920 * lowercase, so ^A becomes a|CTRL. 921 */ 922 onlykey = key & KEYC_MASK_KEY; 923 if (onlykey < 0x20 && 924 onlykey != C0_HT && 925 onlykey != C0_CR && 926 onlykey != C0_ESC) { 927 onlykey |= 0x40; 928 if (onlykey >= 'A' && onlykey <= 'Z') 929 onlykey |= 0x20; 930 key = onlykey | KEYC_CTRL | (key & KEYC_META); 931 } 932 933 goto complete_key; 934 935 partial_key: 936 log_debug("%s: partial key %.*s", c->name, (int)len, buf); 937 938 /* If timer is going, check for expiration. */ 939 if (tty->flags & TTY_TIMER) { 940 if (evtimer_initialized(&tty->key_timer) && 941 !evtimer_pending(&tty->key_timer, NULL)) { 942 expired = 1; 943 goto first_key; 944 } 945 return (0); 946 } 947 948 /* Get the time period. */ 949 delay = options_get_number(global_options, "escape-time"); 950 if (delay == 0) 951 delay = 1; 952 if ((tty->flags & (TTY_WAITFG|TTY_WAITBG) || 953 (tty->flags & TTY_ALL_REQUEST_FLAGS) != TTY_ALL_REQUEST_FLAGS)) { 954 log_debug("%s: increasing delay for active query", c->name); 955 if (delay < 500) 956 delay = 500; 957 } 958 tv.tv_sec = delay / 1000; 959 tv.tv_usec = (delay % 1000) * 1000L; 960 961 /* Start the timer. */ 962 if (event_initialized(&tty->key_timer)) 963 evtimer_del(&tty->key_timer); 964 evtimer_set(&tty->key_timer, tty_keys_callback, tty); 965 evtimer_add(&tty->key_timer, &tv); 966 967 tty->flags |= TTY_TIMER; 968 return (0); 969 970 complete_key: 971 log_debug("%s: complete key %.*s %#llx", c->name, (int)size, buf, key); 972 973 /* Remove key timer. */ 974 if (event_initialized(&tty->key_timer)) 975 evtimer_del(&tty->key_timer); 976 tty->flags &= ~TTY_TIMER; 977 978 /* Check for focus events. */ 979 if (key == KEYC_FOCUS_OUT) { 980 c->flags &= ~CLIENT_FOCUSED; 981 window_update_focus(c->session->curw->window); 982 notify_client("client-focus-out", c); 983 } else if (key == KEYC_FOCUS_IN) { 984 c->flags |= CLIENT_FOCUSED; 985 notify_client("client-focus-in", c); 986 window_update_focus(c->session->curw->window); 987 } 988 989 /* Fire the key. */ 990 if (key != KEYC_UNKNOWN) { 991 event = xcalloc(1, sizeof *event); 992 event->key = key; 993 memcpy(&event->m, &m, sizeof event->m); 994 995 event->buf = xmalloc(size); 996 event->len = size; 997 memcpy (event->buf, buf, event->len); 998 999 if (!server_client_handle_key(c, event)) { 1000 free(event->buf); 1001 free(event); 1002 } 1003 } 1004 1005 /* Remove data from buffer. */ 1006 evbuffer_drain(tty->in, size); 1007 1008 return (1); 1009 1010 discard_key: 1011 log_debug("%s: discard key %.*s %#llx", c->name, (int)size, buf, key); 1012 1013 /* Remove data from buffer. */ 1014 evbuffer_drain(tty->in, size); 1015 1016 return (1); 1017 } 1018 1019 /* Key timer callback. */ 1020 static void 1021 tty_keys_callback(__unused int fd, __unused short events, void *data) 1022 { 1023 struct tty *tty = data; 1024 1025 if (tty->flags & TTY_TIMER) { 1026 while (tty_keys_next(tty)) 1027 ; 1028 } 1029 } 1030 1031 /* 1032 * Handle extended key input. This has two forms: \033[27;m;k~ and \033[k;mu, 1033 * where k is key as a number and m is a modifier. Returns 0 for success, -1 1034 * for failure, 1 for partial; 1035 */ 1036 static int 1037 tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, 1038 size_t *size, key_code *key) 1039 { 1040 struct client *c = tty->client; 1041 size_t end; 1042 u_int number, modifiers; 1043 char tmp[64]; 1044 cc_t bspace; 1045 key_code nkey, onlykey; 1046 struct utf8_data ud; 1047 utf8_char uc; 1048 1049 *size = 0; 1050 1051 /* First two bytes are always \033[. */ 1052 if (buf[0] != '\033') 1053 return (-1); 1054 if (len == 1) 1055 return (1); 1056 if (buf[1] != '[') 1057 return (-1); 1058 if (len == 2) 1059 return (1); 1060 1061 /* 1062 * Look for a terminator. Stop at either '~' or anything that isn't a 1063 * number or ';'. 1064 */ 1065 for (end = 2; end < len && end != sizeof tmp; end++) { 1066 if (buf[end] == '~') 1067 break; 1068 if (!isdigit((u_char)buf[end]) && buf[end] != ';') 1069 break; 1070 } 1071 if (end == len) 1072 return (1); 1073 if (end == sizeof tmp || (buf[end] != '~' && buf[end] != 'u')) 1074 return (-1); 1075 1076 /* Copy to the buffer. */ 1077 memcpy(tmp, buf + 2, end - 2); 1078 tmp[end - 2] = '\0'; 1079 1080 /* Try to parse either form of key. */ 1081 if (buf[end] == '~') { 1082 if (sscanf(tmp, "27;%u;%u", &modifiers, &number) != 2) 1083 return (-1); 1084 } else { 1085 if (sscanf(tmp ,"%u;%u", &number, &modifiers) != 2) 1086 return (-1); 1087 } 1088 *size = end + 1; 1089 1090 /* Store the key. */ 1091 bspace = tty->tio.c_cc[VERASE]; 1092 if (bspace != _POSIX_VDISABLE && number == bspace) 1093 nkey = KEYC_BSPACE; 1094 else 1095 nkey = number; 1096 1097 /* Convert UTF-32 codepoint into internal representation. */ 1098 if (nkey != KEYC_BSPACE && nkey & ~0x7f) { 1099 if (utf8_fromwc(nkey, &ud) == UTF8_DONE && 1100 utf8_from_data(&ud, &uc) == UTF8_DONE) 1101 nkey = uc; 1102 else 1103 return (-1); 1104 } 1105 1106 /* Update the modifiers. */ 1107 if (modifiers > 0) { 1108 modifiers--; 1109 if (modifiers & 1) 1110 nkey |= KEYC_SHIFT; 1111 if (modifiers & 2) 1112 nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Alt */ 1113 if (modifiers & 4) 1114 nkey |= KEYC_CTRL; 1115 if (modifiers & 8) 1116 nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Meta */ 1117 } 1118 1119 /* Convert S-Tab into Backtab. */ 1120 if ((nkey & KEYC_MASK_KEY) == '\011' && (nkey & KEYC_SHIFT)) 1121 nkey = KEYC_BTAB | (nkey & ~KEYC_MASK_KEY & ~KEYC_SHIFT); 1122 1123 /* 1124 * Deal with the Shift modifier when present alone. The problem is that 1125 * in mode 2 some terminals would report shifted keys, like S-a, as 1126 * just A, and some as S-A. 1127 * 1128 * Because we need an unambiguous internal representation, and because 1129 * restoring the Shift modifier when it's missing would require knowing 1130 * the keyboard layout, and because S-A would cause a lot of issues 1131 * downstream, we choose to lose the Shift for all printable 1132 * characters. 1133 * 1134 * That still leaves some ambiguity, such as C-S-A vs. C-A, but that's 1135 * OK, and applications can handle that. 1136 */ 1137 onlykey = nkey & KEYC_MASK_KEY; 1138 if (((onlykey > 0x20 && onlykey < 0x7f) || 1139 KEYC_IS_UNICODE(nkey)) && 1140 (nkey & KEYC_MASK_MODIFIERS) == KEYC_SHIFT) 1141 nkey &= ~KEYC_SHIFT; 1142 1143 if (log_get_level() != 0) { 1144 log_debug("%s: extended key %.*s is %llx (%s)", c->name, 1145 (int)*size, buf, nkey, key_string_lookup_key(nkey, 1)); 1146 } 1147 1148 *key = nkey; 1149 return (0); 1150 } 1151 1152 /* 1153 * Handle mouse key input. Returns 0 for success, -1 for failure, 1 for partial 1154 * (probably a mouse sequence but need more data), -2 if an invalid mouse 1155 * sequence. 1156 */ 1157 static int 1158 tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size, 1159 struct mouse_event *m) 1160 { 1161 struct client *c = tty->client; 1162 u_int i, x, y, b, sgr_b; 1163 u_char sgr_type, ch; 1164 1165 /* 1166 * Standard mouse sequences are \033[M followed by three characters 1167 * indicating button, X and Y, all based at 32 with 1,1 top-left. 1168 * 1169 * UTF-8 mouse sequences are similar but the three are expressed as 1170 * UTF-8 characters. 1171 * 1172 * SGR extended mouse sequences are \033[< followed by three numbers in 1173 * decimal and separated by semicolons indicating button, X and Y. A 1174 * trailing 'M' is click or scroll and trailing 'm' release. All are 1175 * based at 0 with 1,1 top-left. 1176 */ 1177 1178 *size = 0; 1179 x = y = b = sgr_b = 0; 1180 sgr_type = ' '; 1181 1182 /* First two bytes are always \033[. */ 1183 if (buf[0] != '\033') 1184 return (-1); 1185 if (len == 1) 1186 return (1); 1187 if (buf[1] != '[') 1188 return (-1); 1189 if (len == 2) 1190 return (1); 1191 1192 /* 1193 * Third byte is M in old standard (and UTF-8 extension which we do not 1194 * support), < in SGR extension. 1195 */ 1196 if (buf[2] == 'M') { 1197 /* Read the three inputs. */ 1198 *size = 3; 1199 for (i = 0; i < 3; i++) { 1200 if (len <= *size) 1201 return (1); 1202 ch = (u_char)buf[(*size)++]; 1203 if (i == 0) 1204 b = ch; 1205 else if (i == 1) 1206 x = ch; 1207 else 1208 y = ch; 1209 } 1210 log_debug("%s: mouse input: %.*s", c->name, (int)*size, buf); 1211 1212 /* Check and return the mouse input. */ 1213 if (b < MOUSE_PARAM_BTN_OFF || 1214 x < MOUSE_PARAM_POS_OFF || 1215 y < MOUSE_PARAM_POS_OFF) 1216 return (-2); 1217 b -= MOUSE_PARAM_BTN_OFF; 1218 x -= MOUSE_PARAM_POS_OFF; 1219 y -= MOUSE_PARAM_POS_OFF; 1220 } else if (buf[2] == '<') { 1221 /* Read the three inputs. */ 1222 *size = 3; 1223 while (1) { 1224 if (len <= *size) 1225 return (1); 1226 ch = (u_char)buf[(*size)++]; 1227 if (ch == ';') 1228 break; 1229 if (ch < '0' || ch > '9') 1230 return (-1); 1231 sgr_b = 10 * sgr_b + (ch - '0'); 1232 } 1233 while (1) { 1234 if (len <= *size) 1235 return (1); 1236 ch = (u_char)buf[(*size)++]; 1237 if (ch == ';') 1238 break; 1239 if (ch < '0' || ch > '9') 1240 return (-1); 1241 x = 10 * x + (ch - '0'); 1242 } 1243 while (1) { 1244 if (len <= *size) 1245 return (1); 1246 ch = (u_char)buf[(*size)++]; 1247 if (ch == 'M' || ch == 'm') 1248 break; 1249 if (ch < '0' || ch > '9') 1250 return (-1); 1251 y = 10 * y + (ch - '0'); 1252 } 1253 log_debug("%s: mouse input (SGR): %.*s", c->name, (int)*size, 1254 buf); 1255 1256 /* Check and return the mouse input. */ 1257 if (x < 1 || y < 1) 1258 return (-2); 1259 x--; 1260 y--; 1261 b = sgr_b; 1262 1263 /* Type is M for press, m for release. */ 1264 sgr_type = ch; 1265 if (sgr_type == 'm') 1266 b = 3; 1267 1268 /* 1269 * Some terminals (like PuTTY 0.63) mistakenly send 1270 * button-release events for scroll-wheel button-press event. 1271 * Discard it before it reaches any program running inside 1272 * tmux. 1273 */ 1274 if (sgr_type == 'm' && MOUSE_WHEEL(sgr_b)) 1275 return (-2); 1276 } else 1277 return (-1); 1278 1279 /* Fill mouse event. */ 1280 m->lx = tty->mouse_last_x; 1281 m->x = x; 1282 m->ly = tty->mouse_last_y; 1283 m->y = y; 1284 m->lb = tty->mouse_last_b; 1285 m->b = b; 1286 m->sgr_type = sgr_type; 1287 m->sgr_b = sgr_b; 1288 1289 /* Update last mouse state. */ 1290 tty->mouse_last_x = x; 1291 tty->mouse_last_y = y; 1292 tty->mouse_last_b = b; 1293 1294 return (0); 1295 } 1296 1297 /* 1298 * Handle OSC 52 clipboard input. Returns 0 for success, -1 for failure, 1 for 1299 * partial. 1300 */ 1301 static int 1302 tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size) 1303 { 1304 struct client *c = tty->client; 1305 struct window_pane *wp; 1306 size_t end, terminator = 0, needed; 1307 char *copy, *out; 1308 int outlen; 1309 u_int i; 1310 1311 *size = 0; 1312 1313 /* First five bytes are always \033]52;. */ 1314 if (buf[0] != '\033') 1315 return (-1); 1316 if (len == 1) 1317 return (1); 1318 if (buf[1] != ']') 1319 return (-1); 1320 if (len == 2) 1321 return (1); 1322 if (buf[2] != '5') 1323 return (-1); 1324 if (len == 3) 1325 return (1); 1326 if (buf[3] != '2') 1327 return (-1); 1328 if (len == 4) 1329 return (1); 1330 if (buf[4] != ';') 1331 return (-1); 1332 if (len == 5) 1333 return (1); 1334 1335 /* Find the terminator if any. */ 1336 terminator = 0; /* XXX: appease gcc (this value is never used) */ 1337 for (end = 5; end < len; end++) { 1338 if (buf[end] == '\007') { 1339 terminator = 1; 1340 break; 1341 } 1342 if (end > 5 && buf[end - 1] == '\033' && buf[end] == '\\') { 1343 terminator = 2; 1344 break; 1345 } 1346 } 1347 if (end == len) 1348 return (1); 1349 *size = end + 1; 1350 1351 /* Skip the initial part. */ 1352 buf += 5; 1353 end -= 5; 1354 1355 /* Adjust end so that it points to the start of the terminator. */ 1356 end -= terminator - 1; 1357 1358 /* Get the second argument. */ 1359 while (end != 0 && *buf != ';') { 1360 buf++; 1361 end--; 1362 } 1363 if (end == 0 || end == 1) 1364 return (0); 1365 buf++; 1366 end--; 1367 1368 /* If we did not request this, ignore it. */ 1369 if (~tty->flags & TTY_OSC52QUERY) 1370 return (0); 1371 tty->flags &= ~TTY_OSC52QUERY; 1372 evtimer_del(&tty->clipboard_timer); 1373 1374 /* It has to be a string so copy it. */ 1375 copy = xmalloc(end + 1); 1376 memcpy(copy, buf, end); 1377 copy[end] = '\0'; 1378 1379 /* Convert from base64. */ 1380 needed = (end / 4) * 3; 1381 out = xmalloc(needed); 1382 if ((outlen = b64_pton(copy, (u_char *)out, len)) == -1) { 1383 free(out); 1384 free(copy); 1385 return (0); 1386 } 1387 free(copy); 1388 1389 /* Create a new paste buffer and forward to panes. */ 1390 log_debug("%s: %.*s", __func__, outlen, out); 1391 if (c->flags & CLIENT_CLIPBOARDBUFFER) { 1392 paste_add(NULL, out, outlen); 1393 c->flags &= ~CLIENT_CLIPBOARDBUFFER; 1394 } 1395 for (i = 0; i < c->clipboard_npanes; i++) { 1396 wp = window_pane_find_by_id(c->clipboard_panes[i]); 1397 if (wp != NULL) 1398 input_reply_clipboard(wp->event, out, outlen, "\033\\"); 1399 } 1400 free(c->clipboard_panes); 1401 c->clipboard_panes = NULL; 1402 c->clipboard_npanes = 0; 1403 1404 return (0); 1405 } 1406 1407 /* 1408 * Handle primary device attributes input. Returns 0 for success, -1 for 1409 * failure, 1 for partial. 1410 */ 1411 static int 1412 tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len, 1413 size_t *size) 1414 { 1415 struct client *c = tty->client; 1416 int *features = &c->term_features; 1417 u_int i, n = 0; 1418 char tmp[128], *endptr, p[32] = { 0 }, *cp, *next; 1419 1420 *size = 0; 1421 if (tty->flags & TTY_HAVEDA) 1422 return (-1); 1423 1424 /* First three bytes are always \033[?. */ 1425 if (buf[0] != '\033') 1426 return (-1); 1427 if (len == 1) 1428 return (1); 1429 if (buf[1] != '[') 1430 return (-1); 1431 if (len == 2) 1432 return (1); 1433 if (buf[2] != '?') 1434 return (-1); 1435 if (len == 3) 1436 return (1); 1437 1438 /* Copy the rest up to a c. */ 1439 for (i = 0; i < sizeof tmp; i++) { 1440 if (3 + i == len) 1441 return (1); 1442 if (buf[3 + i] >= 'a' && buf[3 + i] <= 'z') 1443 break; 1444 tmp[i] = buf[3 + i]; 1445 } 1446 if (i == sizeof tmp) 1447 return (-1); 1448 if (buf[3 + i] != 'c') 1449 return (-1); 1450 tmp[i] = '\0'; 1451 *size = 4 + i; 1452 1453 /* Convert all arguments to numbers. */ 1454 cp = tmp; 1455 while ((next = strsep(&cp, ";")) != NULL) { 1456 p[n] = strtoul(next, &endptr, 10); 1457 if (*endptr != '\0') 1458 p[n] = 0; 1459 if (++n == nitems(p)) 1460 break; 1461 } 1462 1463 /* Add terminal features. */ 1464 switch (p[0]) { 1465 case 61: /* level 1 */ 1466 case 62: /* level 2 */ 1467 case 63: /* level 3 */ 1468 case 64: /* level 4 */ 1469 case 65: /* level 5 */ 1470 for (i = 1; i < n; i++) { 1471 log_debug("%s: DA feature: %d", c->name, p[i]); 1472 if (p[i] == 4) 1473 tty_add_features(features, "sixel", ","); 1474 if (p[i] == 21) 1475 tty_add_features(features, "margins", ","); 1476 if (p[i] == 28) 1477 tty_add_features(features, "rectfill", ","); 1478 if (p[i] == 52) 1479 tty_add_features(features, "clipboard", ","); 1480 } 1481 break; 1482 } 1483 log_debug("%s: received primary DA %.*s", c->name, (int)*size, buf); 1484 1485 tty_update_features(tty); 1486 tty->flags |= TTY_HAVEDA; 1487 1488 return (0); 1489 } 1490 1491 /* 1492 * Handle secondary device attributes input. Returns 0 for success, -1 for 1493 * failure, 1 for partial. 1494 */ 1495 static int 1496 tty_keys_device_attributes2(struct tty *tty, const char *buf, size_t len, 1497 size_t *size) 1498 { 1499 struct client *c = tty->client; 1500 int *features = &c->term_features; 1501 u_int i, n = 0; 1502 char tmp[128], *endptr, p[32] = { 0 }, *cp, *next; 1503 1504 *size = 0; 1505 if (tty->flags & TTY_HAVEDA2) 1506 return (-1); 1507 1508 /* First three bytes are always \033[>. */ 1509 if (buf[0] != '\033') 1510 return (-1); 1511 if (len == 1) 1512 return (1); 1513 if (buf[1] != '[') 1514 return (-1); 1515 if (len == 2) 1516 return (1); 1517 if (buf[2] != '>') 1518 return (-1); 1519 if (len == 3) 1520 return (1); 1521 1522 /* Copy the rest up to a c. */ 1523 for (i = 0; i < sizeof tmp; i++) { 1524 if (3 + i == len) 1525 return (1); 1526 if (buf[3 + i] >= 'a' && buf[3 + i] <= 'z') 1527 break; 1528 tmp[i] = buf[3 + i]; 1529 } 1530 if (i == sizeof tmp) 1531 return (-1); 1532 if (buf[3 + i] != 'c') 1533 return (-1); 1534 tmp[i] = '\0'; 1535 *size = 4 + i; 1536 1537 /* Convert all arguments to numbers. */ 1538 cp = tmp; 1539 while ((next = strsep(&cp, ";")) != NULL) { 1540 p[n] = strtoul(next, &endptr, 10); 1541 if (*endptr != '\0') 1542 p[n] = 0; 1543 if (++n == nitems(p)) 1544 break; 1545 } 1546 1547 /* 1548 * Add terminal features. We add DECSLRM and DECFRA for some 1549 * identification codes here, notably 64 will catch VT520, even though 1550 * we can't use level 5 from DA because of VTE. 1551 */ 1552 switch (p[0]) { 1553 case 'M': /* mintty */ 1554 tty_default_features(features, "mintty", 0); 1555 break; 1556 case 'T': /* tmux */ 1557 tty_default_features(features, "tmux", 0); 1558 break; 1559 case 'U': /* rxvt-unicode */ 1560 tty_default_features(features, "rxvt-unicode", 0); 1561 break; 1562 } 1563 log_debug("%s: received secondary DA %.*s", c->name, (int)*size, buf); 1564 1565 tty_update_features(tty); 1566 tty->flags |= TTY_HAVEDA2; 1567 1568 return (0); 1569 } 1570 1571 /* 1572 * Handle extended device attributes input. Returns 0 for success, -1 for 1573 * failure, 1 for partial. 1574 */ 1575 static int 1576 tty_keys_extended_device_attributes(struct tty *tty, const char *buf, 1577 size_t len, size_t *size) 1578 { 1579 struct client *c = tty->client; 1580 int *features = &c->term_features; 1581 u_int i; 1582 char tmp[128]; 1583 1584 *size = 0; 1585 if (tty->flags & TTY_HAVEXDA) 1586 return (-1); 1587 1588 /* First four bytes are always \033P>|. */ 1589 if (buf[0] != '\033') 1590 return (-1); 1591 if (len == 1) 1592 return (1); 1593 if (buf[1] != 'P') 1594 return (-1); 1595 if (len == 2) 1596 return (1); 1597 if (buf[2] != '>') 1598 return (-1); 1599 if (len == 3) 1600 return (1); 1601 if (buf[3] != '|') 1602 return (-1); 1603 if (len == 4) 1604 return (1); 1605 1606 /* Copy the rest up to \033\. */ 1607 for (i = 0; i < (sizeof tmp) - 1; i++) { 1608 if (4 + i == len) 1609 return (1); 1610 if (buf[4 + i - 1] == '\033' && buf[4 + i] == '\\') 1611 break; 1612 tmp[i] = buf[4 + i]; 1613 } 1614 if (i == (sizeof tmp) - 1) 1615 return (-1); 1616 tmp[i - 1] = '\0'; 1617 *size = 5 + i; 1618 1619 /* Add terminal features. */ 1620 if (strncmp(tmp, "iTerm2 ", 7) == 0) 1621 tty_default_features(features, "iTerm2", 0); 1622 else if (strncmp(tmp, "tmux ", 5) == 0) 1623 tty_default_features(features, "tmux", 0); 1624 else if (strncmp(tmp, "XTerm(", 6) == 0) 1625 tty_default_features(features, "XTerm", 0); 1626 else if (strncmp(tmp, "mintty ", 7) == 0) 1627 tty_default_features(features, "mintty", 0); 1628 else if (strncmp(tmp, "foot(", 5) == 0) 1629 tty_default_features(features, "foot", 0); 1630 log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf); 1631 1632 free(c->term_type); 1633 c->term_type = xstrdup(tmp); 1634 1635 tty_update_features(tty); 1636 tty->flags |= TTY_HAVEXDA; 1637 1638 return (0); 1639 } 1640 1641 /* 1642 * Handle foreground or background input. Returns 0 for success, -1 for 1643 * failure, 1 for partial. 1644 */ 1645 int 1646 tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size, 1647 int *fg, int *bg) 1648 { 1649 struct client *c = tty->client; 1650 u_int i; 1651 char tmp[128]; 1652 int n; 1653 1654 *size = 0; 1655 1656 /* First four bytes are always \033]1 and 0 or 1 and ;. */ 1657 if (buf[0] != '\033') 1658 return (-1); 1659 if (len == 1) 1660 return (1); 1661 if (buf[1] != ']') 1662 return (-1); 1663 if (len == 2) 1664 return (1); 1665 if (buf[2] != '1') 1666 return (-1); 1667 if (len == 3) 1668 return (1); 1669 if (buf[3] != '0' && buf[3] != '1') 1670 return (-1); 1671 if (len == 4) 1672 return (1); 1673 if (buf[4] != ';') 1674 return (-1); 1675 if (len == 5) 1676 return (1); 1677 1678 /* Copy the rest up to \033\ or \007. */ 1679 for (i = 0; i < (sizeof tmp) - 1; i++) { 1680 if (5 + i == len) 1681 return (1); 1682 if (buf[5 + i - 1] == '\033' && buf[5 + i] == '\\') 1683 break; 1684 if (buf[5 + i] == '\007') 1685 break; 1686 tmp[i] = buf[5 + i]; 1687 } 1688 if (i == (sizeof tmp) - 1) 1689 return (-1); 1690 if (tmp[i - 1] == '\033') 1691 tmp[i - 1] = '\0'; 1692 else 1693 tmp[i] = '\0'; 1694 *size = 6 + i; 1695 1696 n = colour_parseX11(tmp); 1697 if (n != -1 && buf[3] == '0') { 1698 if (c != NULL) 1699 log_debug("%s fg is %s", c->name, colour_tostring(n)); 1700 else 1701 log_debug("fg is %s", colour_tostring(n)); 1702 *fg = n; 1703 tty->flags &= ~TTY_WAITFG; 1704 } else if (n != -1) { 1705 if (c != NULL) 1706 log_debug("%s bg is %s", c->name, colour_tostring(n)); 1707 else 1708 log_debug("bg is %s", colour_tostring(n)); 1709 *bg = n; 1710 tty->flags &= ~TTY_WAITBG; 1711 } 1712 1713 return (0); 1714 } 1715 1716 /* Handle OSC 4 palette colour responses. */ 1717 static int 1718 tty_keys_palette(struct tty *tty, const char *buf, size_t len, size_t *size) 1719 { 1720 struct client *c = tty->client; 1721 u_int i, start; 1722 char tmp[128], *endptr; 1723 int idx; 1724 struct input_request_palette_data pd; 1725 1726 *size = 0; 1727 1728 /* First three bytes are always \033]4. */ 1729 if (buf[0] != '\033') 1730 return (-1); 1731 if (len == 1) 1732 return (1); 1733 if (buf[1] != ']') 1734 return (-1); 1735 if (len == 2) 1736 return (1); 1737 if (buf[2] != '4') 1738 return (-1); 1739 if (len == 3) 1740 return (1); 1741 if (buf[3] != ';') 1742 return (-1); 1743 if (len == 4) 1744 return (1); 1745 1746 /* Parse index. */ 1747 idx = strtol(buf + 4, &endptr, 10); 1748 if (endptr == buf + 4 || *endptr != ';') 1749 return (-1); 1750 if (idx < 0 || idx > 255) 1751 return (-1); 1752 1753 /* Copy the rest up to \033\ or \007. */ 1754 start = (endptr - buf) + 1; 1755 for (i = start; i < len && i - start < sizeof tmp; i++) { 1756 if (buf[i - 1] == '\033' && buf[i] == '\\') 1757 break; 1758 if (buf[i] == '\007') 1759 break; 1760 tmp[i - start] = buf[i]; 1761 } 1762 if (i - start == sizeof tmp) 1763 return (-1); 1764 if (i > 0 && buf[i - 1] == '\033') 1765 tmp[i - start - 1] = '\0'; 1766 else 1767 tmp[i - start] = '\0'; 1768 *size = i + 1; 1769 1770 /* Work out the colour. */ 1771 pd.c = colour_parseX11(tmp); 1772 if (pd.c == -1) 1773 return (0); 1774 pd.idx = idx; 1775 input_request_reply(c, INPUT_REQUEST_PALETTE, &pd); 1776 1777 return (0); 1778 } 1779