1/* $OpenBSD$ */
2
3/*
4 * Copyright (c) 2007 Nicholas Marriott <[email protected]>
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 <limits.h>
25#include <resolv.h>
26#include <stdlib.h>
27#include <string.h>
28#include <termios.h>
29#include <unistd.h>
30
31#include "tmux.h"
32
33/*
34 * Handle keys input from the outside terminal. tty_default_*_keys[] are a base
35 * table of supported keys which are looked up in terminfo(5) and translated
36 * into a ternary tree.
37 */
38
39static void tty_keys_add1(struct tty_key **, const char *, key_code);
40static void tty_keys_add(struct tty *, const char *, key_code);
41static void tty_keys_free1(struct tty_key *);
42static struct tty_key *tty_keys_find1(struct tty_key *, const char *, size_t,
43 size_t *);
44static struct tty_key *tty_keys_find(struct tty *, const char *, size_t,
45 size_t *);
46static int tty_keys_next1(struct tty *, const char *, size_t, key_code *,
47 size_t *, int);
48static void tty_keys_callback(int, short, void *);
49static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *,
50 struct mouse_event *);
51static int tty_keys_clipboard(struct tty *, const char *, size_t,
52 size_t *);
53static int tty_keys_device_attributes(struct tty *, const char *, size_t,
54 size_t *);
55static int tty_keys_device_status_report(struct tty *, const char *,
56 size_t, size_t *);
57
58/* Default raw keys. */
59struct tty_default_key_raw {
60 const char *string;
61 key_code key;
62};
63static const struct tty_default_key_raw tty_default_raw_keys[] = {
64 /*
65 * Numeric keypad. Just use the vt100 escape sequences here and always
66 * put the terminal into keypad_xmit mode. Translation of numbers
67 * mode/applications mode is done in input-keys.c.
68 */
69 { "\033Oo", KEYC_KP_SLASH },
70 { "\033Oj", KEYC_KP_STAR },
71 { "\033Om", KEYC_KP_MINUS },
72 { "\033Ow", KEYC_KP_SEVEN },
73 { "\033Ox", KEYC_KP_EIGHT },
74 { "\033Oy", KEYC_KP_NINE },
75 { "\033Ok", KEYC_KP_PLUS },
76 { "\033Ot", KEYC_KP_FOUR },
77 { "\033Ou", KEYC_KP_FIVE },
78 { "\033Ov", KEYC_KP_SIX },
79 { "\033Oq", KEYC_KP_ONE },
80 { "\033Or", KEYC_KP_TWO },
81 { "\033Os", KEYC_KP_THREE },
82 { "\033OM", KEYC_KP_ENTER },
83 { "\033Op", KEYC_KP_ZERO },
84 { "\033On", KEYC_KP_PERIOD },
85
86 /* Arrow keys. */
87 { "\033OA", KEYC_UP },
88 { "\033OB", KEYC_DOWN },
89 { "\033OC", KEYC_RIGHT },
90 { "\033OD", KEYC_LEFT },
91
92 { "\033[A", KEYC_UP },
93 { "\033[B", KEYC_DOWN },
94 { "\033[C", KEYC_RIGHT },
95 { "\033[D", KEYC_LEFT },
96
97 /* Other (xterm) "cursor" keys. */
98 { "\033OH", KEYC_HOME },
99 { "\033OF", KEYC_END },
100
101 { "\033[H", KEYC_HOME },
102 { "\033[F", KEYC_END },
103
104 /* rxvt-style arrow + modifier keys. */
105 { "\033Oa", KEYC_UP|KEYC_CTRL },
106 { "\033Ob", KEYC_DOWN|KEYC_CTRL },
107 { "\033Oc", KEYC_RIGHT|KEYC_CTRL },
108 { "\033Od", KEYC_LEFT|KEYC_CTRL },
109
110 { "\033[a", KEYC_UP|KEYC_SHIFT },
111 { "\033[b", KEYC_DOWN|KEYC_SHIFT },
112 { "\033[c", KEYC_RIGHT|KEYC_SHIFT },
113 { "\033[d", KEYC_LEFT|KEYC_SHIFT },
114
115 /* rxvt-style function + modifier keys (C = ^, S = $, C-S = @). */
116 { "\033[11^", KEYC_F1|KEYC_CTRL },
117 { "\033[12^", KEYC_F2|KEYC_CTRL },
118 { "\033[13^", KEYC_F3|KEYC_CTRL },
119 { "\033[14^", KEYC_F4|KEYC_CTRL },
120 { "\033[15^", KEYC_F5|KEYC_CTRL },
121 { "\033[17^", KEYC_F6|KEYC_CTRL },
122 { "\033[18^", KEYC_F7|KEYC_CTRL },
123 { "\033[19^", KEYC_F8|KEYC_CTRL },
124 { "\033[20^", KEYC_F9|KEYC_CTRL },
125 { "\033[21^", KEYC_F10|KEYC_CTRL },
126 { "\033[23^", KEYC_F11|KEYC_CTRL },
127 { "\033[24^", KEYC_F12|KEYC_CTRL },
128 { "\033[2^", KEYC_IC|KEYC_CTRL },
129 { "\033[3^", KEYC_DC|KEYC_CTRL },
130 { "\033[7^", KEYC_HOME|KEYC_CTRL },
131 { "\033[8^", KEYC_END|KEYC_CTRL },
132 { "\033[6^", KEYC_NPAGE|KEYC_CTRL },
133 { "\033[5^", KEYC_PPAGE|KEYC_CTRL },
134
135 { "\033[11$", KEYC_F1|KEYC_SHIFT },
136 { "\033[12$", KEYC_F2|KEYC_SHIFT },
137 { "\033[13$", KEYC_F3|KEYC_SHIFT },
138 { "\033[14$", KEYC_F4|KEYC_SHIFT },
139 { "\033[15$", KEYC_F5|KEYC_SHIFT },
140 { "\033[17$", KEYC_F6|KEYC_SHIFT },
141 { "\033[18$", KEYC_F7|KEYC_SHIFT },
142 { "\033[19$", KEYC_F8|KEYC_SHIFT },
143 { "\033[20$", KEYC_F9|KEYC_SHIFT },
144 { "\033[21$", KEYC_F10|KEYC_SHIFT },
145 { "\033[23$", KEYC_F11|KEYC_SHIFT },
146 { "\033[24$", KEYC_F12|KEYC_SHIFT },
147 { "\033[2$", KEYC_IC|KEYC_SHIFT },
148 { "\033[3$", KEYC_DC|KEYC_SHIFT },
149 { "\033[7$", KEYC_HOME|KEYC_SHIFT },
150 { "\033[8$", KEYC_END|KEYC_SHIFT },
151 { "\033[6$", KEYC_NPAGE|KEYC_SHIFT },
152 { "\033[5$", KEYC_PPAGE|KEYC_SHIFT },
153
154 { "\033[11@", KEYC_F1|KEYC_CTRL|KEYC_SHIFT },
155 { "\033[12@", KEYC_F2|KEYC_CTRL|KEYC_SHIFT },
156 { "\033[13@", KEYC_F3|KEYC_CTRL|KEYC_SHIFT },
157 { "\033[14@", KEYC_F4|KEYC_CTRL|KEYC_SHIFT },
158 { "\033[15@", KEYC_F5|KEYC_CTRL|KEYC_SHIFT },
159 { "\033[17@", KEYC_F6|KEYC_CTRL|KEYC_SHIFT },
160 { "\033[18@", KEYC_F7|KEYC_CTRL|KEYC_SHIFT },
161 { "\033[19@", KEYC_F8|KEYC_CTRL|KEYC_SHIFT },
162 { "\033[20@", KEYC_F9|KEYC_CTRL|KEYC_SHIFT },
163 { "\033[21@", KEYC_F10|KEYC_CTRL|KEYC_SHIFT },
164 { "\033[23@", KEYC_F11|KEYC_CTRL|KEYC_SHIFT },
165 { "\033[24@", KEYC_F12|KEYC_CTRL|KEYC_SHIFT },
166 { "\033[2@", KEYC_IC|KEYC_CTRL|KEYC_SHIFT },
167 { "\033[3@", KEYC_DC|KEYC_CTRL|KEYC_SHIFT },
168 { "\033[7@", KEYC_HOME|KEYC_CTRL|KEYC_SHIFT },
169 { "\033[8@", KEYC_END|KEYC_CTRL|KEYC_SHIFT },
170 { "\033[6@", KEYC_NPAGE|KEYC_CTRL|KEYC_SHIFT },
171 { "\033[5@", KEYC_PPAGE|KEYC_CTRL|KEYC_SHIFT },
172
173 /* Focus tracking. */
174 { "\033[I", KEYC_FOCUS_IN },
175 { "\033[O", KEYC_FOCUS_OUT },
176
177 /* Paste keys. */
178 { "\033[200~", KEYC_PASTE_START },
179 { "\033[201~", KEYC_PASTE_END },
180};
181
182/*
183 * Default terminfo(5) keys. Any keys that have builtin modifiers
184 * (that is, where the key itself contains the modifiers) has the
185 * KEYC_XTERM flag set so a leading escape is not treated as meta (and
186 * probably removed).
187 */
188struct tty_default_key_code {
189 enum tty_code_code code;
190 key_code key;
191};
192static const struct tty_default_key_code tty_default_code_keys[] = {
193 /* Function keys. */
194 { TTYC_KF1, KEYC_F1 },
195 { TTYC_KF2, KEYC_F2 },
196 { TTYC_KF3, KEYC_F3 },
197 { TTYC_KF4, KEYC_F4 },
198 { TTYC_KF5, KEYC_F5 },
199 { TTYC_KF6, KEYC_F6 },
200 { TTYC_KF7, KEYC_F7 },
201 { TTYC_KF8, KEYC_F8 },
202 { TTYC_KF9, KEYC_F9 },
203 { TTYC_KF10, KEYC_F10 },
204 { TTYC_KF11, KEYC_F11 },
205 { TTYC_KF12, KEYC_F12 },
206
207 { TTYC_KF13, KEYC_F1|KEYC_SHIFT|KEYC_XTERM },
208 { TTYC_KF14, KEYC_F2|KEYC_SHIFT|KEYC_XTERM },
209 { TTYC_KF15, KEYC_F3|KEYC_SHIFT|KEYC_XTERM },
210 { TTYC_KF16, KEYC_F4|KEYC_SHIFT|KEYC_XTERM },
211 { TTYC_KF17, KEYC_F5|KEYC_SHIFT|KEYC_XTERM },
212 { TTYC_KF18, KEYC_F6|KEYC_SHIFT|KEYC_XTERM },
213 { TTYC_KF19, KEYC_F7|KEYC_SHIFT|KEYC_XTERM },
214 { TTYC_KF20, KEYC_F8|KEYC_SHIFT|KEYC_XTERM },
215 { TTYC_KF21, KEYC_F9|KEYC_SHIFT|KEYC_XTERM },
216 { TTYC_KF22, KEYC_F10|KEYC_SHIFT|KEYC_XTERM },
217 { TTYC_KF23, KEYC_F11|KEYC_SHIFT|KEYC_XTERM },
218 { TTYC_KF24, KEYC_F12|KEYC_SHIFT|KEYC_XTERM },
219
220 { TTYC_KF25, KEYC_F1|KEYC_CTRL|KEYC_XTERM },
221 { TTYC_KF26, KEYC_F2|KEYC_CTRL|KEYC_XTERM },
222 { TTYC_KF27, KEYC_F3|KEYC_CTRL|KEYC_XTERM },
223 { TTYC_KF28, KEYC_F4|KEYC_CTRL|KEYC_XTERM },
224 { TTYC_KF29, KEYC_F5|KEYC_CTRL|KEYC_XTERM },
225 { TTYC_KF30, KEYC_F6|KEYC_CTRL|KEYC_XTERM },
226 { TTYC_KF31, KEYC_F7|KEYC_CTRL|KEYC_XTERM },
227 { TTYC_KF32, KEYC_F8|KEYC_CTRL|KEYC_XTERM },
228 { TTYC_KF33, KEYC_F9|KEYC_CTRL|KEYC_XTERM },
229 { TTYC_KF34, KEYC_F10|KEYC_CTRL|KEYC_XTERM },
230 { TTYC_KF35, KEYC_F11|KEYC_CTRL|KEYC_XTERM },
231 { TTYC_KF36, KEYC_F12|KEYC_CTRL|KEYC_XTERM },
232
233 { TTYC_KF37, KEYC_F1|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
234 { TTYC_KF38, KEYC_F2|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
235 { TTYC_KF39, KEYC_F3|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
236 { TTYC_KF40, KEYC_F4|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
237 { TTYC_KF41, KEYC_F5|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
238 { TTYC_KF42, KEYC_F6|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
239 { TTYC_KF43, KEYC_F7|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
240 { TTYC_KF44, KEYC_F8|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
241 { TTYC_KF45, KEYC_F9|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
242 { TTYC_KF46, KEYC_F10|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
243 { TTYC_KF47, KEYC_F11|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
244 { TTYC_KF48, KEYC_F12|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
245
246 { TTYC_KF49, KEYC_F1|KEYC_ESCAPE|KEYC_XTERM },
247 { TTYC_KF50, KEYC_F2|KEYC_ESCAPE|KEYC_XTERM },
248 { TTYC_KF51, KEYC_F3|KEYC_ESCAPE|KEYC_XTERM },
249 { TTYC_KF52, KEYC_F4|KEYC_ESCAPE|KEYC_XTERM },
250 { TTYC_KF53, KEYC_F5|KEYC_ESCAPE|KEYC_XTERM },
251 { TTYC_KF54, KEYC_F6|KEYC_ESCAPE|KEYC_XTERM },
252 { TTYC_KF55, KEYC_F7|KEYC_ESCAPE|KEYC_XTERM },
253 { TTYC_KF56, KEYC_F8|KEYC_ESCAPE|KEYC_XTERM },
254 { TTYC_KF57, KEYC_F9|KEYC_ESCAPE|KEYC_XTERM },
255 { TTYC_KF58, KEYC_F10|KEYC_ESCAPE|KEYC_XTERM },
256 { TTYC_KF59, KEYC_F11|KEYC_ESCAPE|KEYC_XTERM },
257 { TTYC_KF60, KEYC_F12|KEYC_ESCAPE|KEYC_XTERM },
258
259 { TTYC_KF61, KEYC_F1|KEYC_ESCAPE|KEYC_SHIFT|KEYC_XTERM },
260 { TTYC_KF62, KEYC_F2|KEYC_ESCAPE|KEYC_SHIFT|KEYC_XTERM },
261 { TTYC_KF63, KEYC_F3|KEYC_ESCAPE|KEYC_SHIFT|KEYC_XTERM },
262
263 { TTYC_KICH1, KEYC_IC },
264 { TTYC_KDCH1, KEYC_DC },
265 { TTYC_KHOME, KEYC_HOME },
266 { TTYC_KEND, KEYC_END },
267 { TTYC_KNP, KEYC_NPAGE },
268 { TTYC_KPP, KEYC_PPAGE },
269 { TTYC_KCBT, KEYC_BTAB },
270
271 /* Arrow keys from terminfo. */
272 { TTYC_KCUU1, KEYC_UP },
273 { TTYC_KCUD1, KEYC_DOWN },
274 { TTYC_KCUB1, KEYC_LEFT },
275 { TTYC_KCUF1, KEYC_RIGHT },
276
277 /* Key and modifier capabilities. */
278 { TTYC_KDC2, KEYC_DC|KEYC_SHIFT|KEYC_XTERM },
279 { TTYC_KDC3, KEYC_DC|KEYC_ESCAPE|KEYC_XTERM },
280 { TTYC_KDC4, KEYC_DC|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
281 { TTYC_KDC5, KEYC_DC|KEYC_CTRL|KEYC_XTERM },
282 { TTYC_KDC6, KEYC_DC|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
283 { TTYC_KDC7, KEYC_DC|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
284 { TTYC_KIND, KEYC_DOWN|KEYC_SHIFT|KEYC_XTERM },
285 { TTYC_KDN2, KEYC_DOWN|KEYC_SHIFT|KEYC_XTERM },
286 { TTYC_KDN3, KEYC_DOWN|KEYC_ESCAPE|KEYC_XTERM },
287 { TTYC_KDN4, KEYC_DOWN|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
288 { TTYC_KDN5, KEYC_DOWN|KEYC_CTRL|KEYC_XTERM },
289 { TTYC_KDN6, KEYC_DOWN|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
290 { TTYC_KDN7, KEYC_DOWN|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
291 { TTYC_KEND2, KEYC_END|KEYC_SHIFT|KEYC_XTERM },
292 { TTYC_KEND3, KEYC_END|KEYC_ESCAPE|KEYC_XTERM },
293 { TTYC_KEND4, KEYC_END|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
294 { TTYC_KEND5, KEYC_END|KEYC_CTRL|KEYC_XTERM },
295 { TTYC_KEND6, KEYC_END|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
296 { TTYC_KEND7, KEYC_END|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
297 { TTYC_KHOM2, KEYC_HOME|KEYC_SHIFT|KEYC_XTERM },
298 { TTYC_KHOM3, KEYC_HOME|KEYC_ESCAPE|KEYC_XTERM },
299 { TTYC_KHOM4, KEYC_HOME|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
300 { TTYC_KHOM5, KEYC_HOME|KEYC_CTRL|KEYC_XTERM },
301 { TTYC_KHOM6, KEYC_HOME|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
302 { TTYC_KHOM7, KEYC_HOME|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
303 { TTYC_KIC2, KEYC_IC|KEYC_SHIFT|KEYC_XTERM },
304 { TTYC_KIC3, KEYC_IC|KEYC_ESCAPE|KEYC_XTERM },
305 { TTYC_KIC4, KEYC_IC|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
306 { TTYC_KIC5, KEYC_IC|KEYC_CTRL|KEYC_XTERM },
307 { TTYC_KIC6, KEYC_IC|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
308 { TTYC_KIC7, KEYC_IC|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
309 { TTYC_KLFT2, KEYC_LEFT|KEYC_SHIFT|KEYC_XTERM },
310 { TTYC_KLFT3, KEYC_LEFT|KEYC_ESCAPE|KEYC_XTERM },
311 { TTYC_KLFT4, KEYC_LEFT|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
312 { TTYC_KLFT5, KEYC_LEFT|KEYC_CTRL|KEYC_XTERM },
313 { TTYC_KLFT6, KEYC_LEFT|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
314 { TTYC_KLFT7, KEYC_LEFT|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
315 { TTYC_KNXT2, KEYC_NPAGE|KEYC_SHIFT|KEYC_XTERM },
316 { TTYC_KNXT3, KEYC_NPAGE|KEYC_ESCAPE|KEYC_XTERM },
317 { TTYC_KNXT4, KEYC_NPAGE|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
318 { TTYC_KNXT5, KEYC_NPAGE|KEYC_CTRL|KEYC_XTERM },
319 { TTYC_KNXT6, KEYC_NPAGE|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
320 { TTYC_KNXT7, KEYC_NPAGE|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
321 { TTYC_KPRV2, KEYC_PPAGE|KEYC_SHIFT|KEYC_XTERM },
322 { TTYC_KPRV3, KEYC_PPAGE|KEYC_ESCAPE|KEYC_XTERM },
323 { TTYC_KPRV4, KEYC_PPAGE|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
324 { TTYC_KPRV5, KEYC_PPAGE|KEYC_CTRL|KEYC_XTERM },
325 { TTYC_KPRV6, KEYC_PPAGE|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
326 { TTYC_KPRV7, KEYC_PPAGE|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
327 { TTYC_KRIT2, KEYC_RIGHT|KEYC_SHIFT|KEYC_XTERM },
328 { TTYC_KRIT3, KEYC_RIGHT|KEYC_ESCAPE|KEYC_XTERM },
329 { TTYC_KRIT4, KEYC_RIGHT|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
330 { TTYC_KRIT5, KEYC_RIGHT|KEYC_CTRL|KEYC_XTERM },
331 { TTYC_KRIT6, KEYC_RIGHT|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
332 { TTYC_KRIT7, KEYC_RIGHT|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
333 { TTYC_KRI, KEYC_UP|KEYC_SHIFT|KEYC_XTERM },
334 { TTYC_KUP2, KEYC_UP|KEYC_SHIFT|KEYC_XTERM },
335 { TTYC_KUP3, KEYC_UP|KEYC_ESCAPE|KEYC_XTERM },
336 { TTYC_KUP4, KEYC_UP|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM },
337 { TTYC_KUP5, KEYC_UP|KEYC_CTRL|KEYC_XTERM },
338 { TTYC_KUP6, KEYC_UP|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM },
339 { TTYC_KUP7, KEYC_UP|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM },
340};
341
342/* Add key to tree. */
343static void
344tty_keys_add(struct tty *tty, const char *s, key_code key)
345{
346 struct tty_key *tk;
347 size_t size;
348 const char *keystr;
349
350 keystr = key_string_lookup_key(key);
351 if ((tk = tty_keys_find(tty, s, strlen(s), &size)) == NULL) {
352 log_debug("new key %s: 0x%llx (%s)", s, key, keystr);
353 tty_keys_add1(&tty->key_tree, s, key);
354 } else {
355 log_debug("replacing key %s: 0x%llx (%s)", s, key, keystr);
356 tk->key = key;
357 }
358}
359
360/* Add next node to the tree. */
361static void
362tty_keys_add1(struct tty_key **tkp, const char *s, key_code key)
363{
364 struct tty_key *tk;
365
366 /* Allocate a tree entry if there isn't one already. */
367 tk = *tkp;
368 if (tk == NULL) {
369 tk = *tkp = xcalloc(1, sizeof *tk);
370 tk->ch = *s;
371 tk->key = KEYC_UNKNOWN;
372 }
373
374 /* Find the next entry. */
375 if (*s == tk->ch) {
376 /* Move forward in string. */
377 s++;
378
379 /* If this is the end of the string, no more is necessary. */
380 if (*s == '\0') {
381 tk->key = key;
382 return;
383 }
384
385 /* Use the child tree for the next character. */
386 tkp = &tk->next;
387 } else {
388 if (*s < tk->ch)
389 tkp = &tk->left;
390 else if (*s > tk->ch)
391 tkp = &tk->right;
392 }
393
394 /* And recurse to add it. */
395 tty_keys_add1(tkp, s, key);
396}
397
398/* Initialise a key tree from the table. */
399void
400tty_keys_build(struct tty *tty)
401{
402 const struct tty_default_key_raw *tdkr;
403 const struct tty_default_key_code *tdkc;
404 u_int i;
405 const char *s;
406 struct options_entry *o;
407 struct options_array_item *a;
408 union options_value *ov;
409
410 if (tty->key_tree != NULL)
411 tty_keys_free(tty);
412 tty->key_tree = NULL;
413
414 for (i = 0; i < nitems(tty_default_raw_keys); i++) {
415 tdkr = &tty_default_raw_keys[i];
416
417 s = tdkr->string;
418 if (*s != '\0')
419 tty_keys_add(tty, s, tdkr->key);
420 }
421 for (i = 0; i < nitems(tty_default_code_keys); i++) {
422 tdkc = &tty_default_code_keys[i];
423
424 s = tty_term_string(tty->term, tdkc->code);
425 if (*s != '\0')
426 tty_keys_add(tty, s, tdkc->key);
427
428 }
429
430 o = options_get(global_options, "user-keys");
431 if (o != NULL) {
432 a = options_array_first(o);
433 while (a != NULL) {
434 i = options_array_item_index(a);
435 ov = options_array_item_value(a);
436 tty_keys_add(tty, ov->string, KEYC_USER + i);
437 a = options_array_next(a);
438 }
439 }
440}
441
442/* Free the entire key tree. */
443void
444tty_keys_free(struct tty *tty)
445{
446 tty_keys_free1(tty->key_tree);
447}
448
449/* Free a single key. */
450static void
451tty_keys_free1(struct tty_key *tk)
452{
453 if (tk->next != NULL)
454 tty_keys_free1(tk->next);
455 if (tk->left != NULL)
456 tty_keys_free1(tk->left);
457 if (tk->right != NULL)
458 tty_keys_free1(tk->right);
459 free(tk);
460}
461
462/* Lookup a key in the tree. */
463static struct tty_key *
464tty_keys_find(struct tty *tty, const char *buf, size_t len, size_t *size)
465{
466 *size = 0;
467 return (tty_keys_find1(tty->key_tree, buf, len, size));
468}
469
470/* Find the next node. */
471static struct tty_key *
472tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size)
473{
474 /* If no data, no match. */
475 if (len == 0)
476 return (NULL);
477
478 /* If the node is NULL, this is the end of the tree. No match. */
479 if (tk == NULL)
480 return (NULL);
481
482 /* Pick the next in the sequence. */
483 if (tk->ch == *buf) {
484 /* Move forward in the string. */
485 buf++; len--;
486 (*size)++;
487
488 /* At the end of the string, return the current node. */
489 if (len == 0 || (tk->next == NULL && tk->key != KEYC_UNKNOWN))
490 return (tk);
491
492 /* Move into the next tree for the following character. */
493 tk = tk->next;
494 } else {
495 if (*buf < tk->ch)
496 tk = tk->left;
497 else if (*buf > tk->ch)
498 tk = tk->right;
499 }
500
501 /* Move to the next in the tree. */
502 return (tty_keys_find1(tk, buf, len, size));
503}
504
505/* Look up part of the next key. */
506static int
507tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
508 size_t *size, int expired)
509{
510 struct client *c = tty->client;
511 struct tty_key *tk, *tk1;
512 struct utf8_data ud;
513 enum utf8_state more;
514 u_int i;
515 wchar_t wc;
516 int n;
517
518 log_debug("%s: next key is %zu (%.*s) (expired=%d)", c->name, len,
519 (int)len, buf, expired);
520
521 /* Is this a known key? */
522 tk = tty_keys_find(tty, buf, len, size);
523 if (tk != NULL && tk->key != KEYC_UNKNOWN) {
524 tk1 = tk;
525 do
526 log_debug("%s: keys in list: %#llx", c->name, tk1->key);
527 while ((tk1 = tk1->next) != NULL);
528 if (tk->next != NULL && !expired)
529 return (1);
530 *key = tk->key;
531 return (0);
532 }
533
534 /* Is this an an xterm(1) key? */
535 n = xterm_keys_find(buf, len, size, key);
536 if (n == 0)
537 return (0);
538 if (n == 1 && !expired)
539 return (1);
540
541 /* Is this valid UTF-8? */
542 more = utf8_open(&ud, (u_char)*buf);
543 if (more == UTF8_MORE) {
544 *size = ud.size;
545 if (len < ud.size) {
546 if (!expired)
547 return (1);
548 return (-1);
549 }
550 for (i = 1; i < ud.size; i++)
551 more = utf8_append(&ud, (u_char)buf[i]);
552 if (more != UTF8_DONE)
553 return (-1);
554
555 if (utf8_combine(&ud, &wc) != UTF8_DONE)
556 return (-1);
557 *key = wc;
558
559 log_debug("%s: UTF-8 key %.*s %#llx", c->name, (int)ud.size,
560 buf, *key);
561 return (0);
562 }
563
564 return (-1);
565}
566
567/* Process at least one key in the buffer. Return 0 if no keys present. */
568int
569tty_keys_next(struct tty *tty)
570{
571 struct client *c = tty->client;
572 struct timeval tv;
573 const char *buf;
574 size_t len, size;
575 cc_t bspace;
576 int delay, expired = 0, n;
577 key_code key;
578 struct mouse_event m = { 0 };
579 struct key_event *event;
580
581 gettimeofday(&tv, NULL);
582
583 /* Get key buffer. */
584 buf = EVBUFFER_DATA(tty->in);
585 len = EVBUFFER_LENGTH(tty->in);
586 if (len == 0)
587 return (0);
588 log_debug("%s: keys are %zu (%.*s)", c->name, len, (int)len, buf);
589
590 /* Is this a clipboard response? */
591 switch (tty_keys_clipboard(tty, buf, len, &size)) {
592 case 0: /* yes */
593 key = KEYC_UNKNOWN;
594 goto complete_key;
595 case -1: /* no, or not valid */
596 break;
597 case 1: /* partial */
598 goto partial_key;
599 }
600
601 /* Is this a device attributes response? */
602 switch (tty_keys_device_attributes(tty, buf, len, &size)) {
603 case 0: /* yes */
604 key = KEYC_UNKNOWN;
605 goto complete_key;
606 case -1: /* no, or not valid */
607 break;
608 case 1: /* partial */
609 goto partial_key;
610 }
611
612 /* Is this a device status report response? */
613 switch (tty_keys_device_status_report(tty, buf, len, &size)) {
614 case 0: /* yes */
615 key = KEYC_UNKNOWN;
616 goto complete_key;
617 case -1: /* no, or not valid */
618 break;
619 case 1: /* partial */
620 goto partial_key;
621 }
622
623 /* Is this a mouse key press? */
624 switch (tty_keys_mouse(tty, buf, len, &size, &m)) {
625 case 0: /* yes */
626 key = KEYC_MOUSE;
627 goto complete_key;
628 case -1: /* no, or not valid */
629 break;
630 case -2: /* yes, but we don't care. */
631 key = KEYC_MOUSE;
632 goto discard_key;
633 case 1: /* partial */
634 goto partial_key;
635 }
636
637first_key:
638 /* Try to lookup complete key. */
639 n = tty_keys_next1(tty, buf, len, &key, &size, expired);
640 if (n == 0) /* found */
641 goto complete_key;
642 if (n == 1)
643 goto partial_key;
644
645 /*
646 * If not a complete key, look for key with an escape prefix (meta
647 * modifier).
648 */
649 if (*buf == '\033' && len > 1) {
650 /* Look for a key without the escape. */
651 n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired);
652 if (n == 0) { /* found */
653 if (key & KEYC_XTERM) {
654 /*
655 * We want the escape key as well as the xterm
656 * key, because the xterm sequence implicitly
657 * includes the escape (so if we see
658 * \033\033[1;3D we know it is an Escape
659 * followed by M-Left, not just M-Left).
660 */
661 key = '\033';
662 size = 1;
663 goto complete_key;
664 }
665 key |= KEYC_ESCAPE;
666 size++;
667 goto complete_key;
668 }
669 if (n == 1) /* partial */
670 goto partial_key;
671 }
672
673 /*
674 * At this point, we know the key is not partial (with or without
675 * escape). So pass it through even if the timer has not expired.
676 */
677 if (*buf == '\033' && len >= 2) {
678 key = (u_char)buf[1] | KEYC_ESCAPE;
679 size = 2;
680 } else {
681 key = (u_char)buf[0];
682 size = 1;
683 }
684 goto complete_key;
685
686partial_key:
687 log_debug("%s: partial key %.*s", c->name, (int)len, buf);
688
689 /* If timer is going, check for expiration. */
690 if (tty->flags & TTY_TIMER) {
691 if (evtimer_initialized(&tty->key_timer) &&
692 !evtimer_pending(&tty->key_timer, NULL)) {
693 expired = 1;
694 goto first_key;
695 }
696 return (0);
697 }
698
699 /* Get the time period. */
700 delay = options_get_number(global_options, "escape-time");
701 tv.tv_sec = delay / 1000;
702 tv.tv_usec = (delay % 1000) * 1000L;
703
704 /* Start the timer. */
705 if (event_initialized(&tty->key_timer))
706 evtimer_del(&tty->key_timer);
707 evtimer_set(&tty->key_timer, tty_keys_callback, tty);
708 evtimer_add(&tty->key_timer, &tv);
709
710 tty->flags |= TTY_TIMER;
711 return (0);
712
713complete_key:
714 log_debug("%s: complete key %.*s %#llx", c->name, (int)size, buf, key);
715
716 /*
717 * Check for backspace key using termios VERASE - the terminfo
718 * kbs entry is extremely unreliable, so cannot be safely
719 * used. termios should have a better idea.
720 */
721 bspace = tty->tio.c_cc[VERASE];
722 if (bspace != _POSIX_VDISABLE && (key & KEYC_MASK_KEY) == bspace)
723 key = (key & KEYC_MASK_MOD) | KEYC_BSPACE;
724
725 /* Remove data from buffer. */
726 evbuffer_drain(tty->in, size);
727
728 /* Remove key timer. */
729 if (event_initialized(&tty->key_timer))
730 evtimer_del(&tty->key_timer);
731 tty->flags &= ~TTY_TIMER;
732
733 /* Check for focus events. */
734 if (key == KEYC_FOCUS_OUT) {
735 tty->client->flags &= ~CLIENT_FOCUSED;
736 return (1);
737 } else if (key == KEYC_FOCUS_IN) {
738 tty->client->flags |= CLIENT_FOCUSED;
739 return (1);
740 }
741
742 /* Fire the key. */
743 if (key != KEYC_UNKNOWN) {
744 event = xmalloc(sizeof *event);
745 event->key = key;
746 memcpy(&event->m, &m, sizeof event->m);
747 if (!server_client_handle_key(c, event))
748 free(event);
749 }
750
751 return (1);
752
753discard_key:
754 log_debug("%s: discard key %.*s %#llx", c->name, (int)size, buf, key);
755
756 /* Remove data from buffer. */
757 evbuffer_drain(tty->in, size);
758
759 return (1);
760}
761
762/* Key timer callback. */
763static void
764tty_keys_callback(__unused int fd, __unused short events, void *data)
765{
766 struct tty *tty = data;
767
768 if (tty->flags & TTY_TIMER) {
769 while (tty_keys_next(tty))
770 ;
771 }
772}
773
774/*
775 * Handle mouse key input. Returns 0 for success, -1 for failure, 1 for partial
776 * (probably a mouse sequence but need more data).
777 */
778static int
779tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size,
780 struct mouse_event *m)
781{
782 struct client *c = tty->client;
783 u_int i, x, y, b, sgr_b;
784 u_char sgr_type, ch;
785
786 /*
787 * Standard mouse sequences are \033[M followed by three characters
788 * indicating button, X and Y, all based at 32 with 1,1 top-left.
789 *
790 * UTF-8 mouse sequences are similar but the three are expressed as
791 * UTF-8 characters.
792 *
793 * SGR extended mouse sequences are \033[< followed by three numbers in
794 * decimal and separated by semicolons indicating button, X and Y. A
795 * trailing 'M' is click or scroll and trailing 'm' release. All are
796 * based at 0 with 1,1 top-left.
797 */
798
799 *size = 0;
800 x = y = b = sgr_b = 0;
801 sgr_type = ' ';
802
803 /* First two bytes are always \033[. */
804 if (buf[0] != '\033')
805 return (-1);
806 if (len == 1)
807 return (1);
808 if (buf[1] != '[')
809 return (-1);
810 if (len == 2)
811 return (1);
812
813 /*
814 * Third byte is M in old standard (and UTF-8 extension which we do not
815 * support), < in SGR extension.
816 */
817 if (buf[2] == 'M') {
818 /* Read the three inputs. */
819 *size = 3;
820 for (i = 0; i < 3; i++) {
821 if (len <= *size)
822 return (1);
823 ch = (u_char)buf[(*size)++];
824 if (i == 0)
825 b = ch;
826 else if (i == 1)
827 x = ch;
828 else
829 y = ch;
830 }
831 log_debug("%s: mouse input: %.*s", c->name, (int)*size, buf);
832
833 /* Check and return the mouse input. */
834 if (b < 32)
835 return (-1);
836 b -= 32;
837 if (x >= 33)
838 x -= 33;
839 else
840 x = 256 - x;
841 if (y >= 33)
842 y -= 33;
843 else
844 y = 256 - y;
845 } else if (buf[2] == '<') {
846 /* Read the three inputs. */
847 *size = 3;
848 while (1) {
849 if (len <= *size)
850 return (1);
851 ch = (u_char)buf[(*size)++];
852 if (ch == ';')
853 break;
854 if (ch < '0' || ch > '9')
855 return (-1);
856 sgr_b = 10 * sgr_b + (ch - '0');
857 }
858 while (1) {
859 if (len <= *size)
860 return (1);
861 ch = (u_char)buf[(*size)++];
862 if (ch == ';')
863 break;
864 if (ch < '0' || ch > '9')
865 return (-1);
866 x = 10 * x + (ch - '0');
867 }
868 while (1) {
869 if (len <= *size)
870 return (1);
871 ch = (u_char)buf[(*size)++];
872 if (ch == 'M' || ch == 'm')
873 break;
874 if (ch < '0' || ch > '9')
875 return (-1);
876 y = 10 * y + (ch - '0');
877 }
878 log_debug("%s: mouse input (SGR): %.*s", c->name, (int)*size,
879 buf);
880
881 /* Check and return the mouse input. */
882 if (x < 1 || y < 1)
883 return (-1);
884 x--;
885 y--;
886 b = sgr_b;
887
888 /* Type is M for press, m for release. */
889 sgr_type = ch;
890 if (sgr_type == 'm')
891 b |= 3;
892
893 /*
894 * Some terminals (like PuTTY 0.63) mistakenly send
895 * button-release events for scroll-wheel button-press event.
896 * Discard it before it reaches any program running inside
897 * tmux.
898 */
899 if (sgr_type == 'm' && (sgr_b & 64))
900 return (-2);
901 } else
902 return (-1);
903
904 /* Fill mouse event. */
905 m->lx = tty->mouse_last_x;
906 m->x = x;
907 m->ly = tty->mouse_last_y;
908 m->y = y;
909 m->lb = tty->mouse_last_b;
910 m->b = b;
911 m->sgr_type = sgr_type;
912 m->sgr_b = sgr_b;
913
914 /* Update last mouse state. */
915 tty->mouse_last_x = x;
916 tty->mouse_last_y = y;
917 tty->mouse_last_b = b;
918
919 return (0);
920}
921
922/*
923 * Handle OSC 52 clipboard input. Returns 0 for success, -1 for failure, 1 for
924 * partial.
925 */
926static int
927tty_keys_clipboard(__unused struct tty *tty, const char *buf, size_t len,
928 size_t *size)
929{
930 size_t end, terminator, needed;
931 char *copy, *out;
932 int outlen;
933
934 *size = 0;
935
936 /* First three bytes are always \033]52;. */
937 if (buf[0] != '\033')
938 return (-1);
939 if (len == 1)
940 return (1);
941 if (buf[1] != ']')
942 return (-1);
943 if (len == 2)
944 return (1);
945 if (buf[2] != '5')
946 return (-1);
947 if (len == 3)
948 return (1);
949 if (buf[3] != '2')
950 return (-1);
951 if (len == 4)
952 return (1);
953 if (buf[4] != ';')
954 return (-1);
955 if (len == 5)
956 return (1);
957
958 /* Find the terminator if any. */
959 for (end = 5; end < len; end++) {
960 if (buf[end] == '\007') {
961 terminator = 1;
962 break;
963 }
964 if (end > 5 && buf[end - 1] == '\033' && buf[end] == '\\') {
965 terminator = 2;
966 break;
967 }
968 }
969 if (end == len)
970 return (1);
971 *size = end + terminator;
972
973 /* Skip the initial part. */
974 buf += 5;
975 end -= 5;
976
977 /* Get the second argument. */
978 while (end != 0 && *buf != ';') {
979 buf++;
980 end--;
981 }
982 if (end == 0 || end == 1)
983 return (0);
984 buf++;
985 end--;
986
987 /* It has to be a string so copy it. */
988 copy = xmalloc(end + 1);
989 memcpy(copy, buf, end);
990 copy[end] = '\0';
991
992 /* Convert from base64. */
993 needed = (end / 4) * 3;
994 out = xmalloc(needed);
995 if ((outlen = b64_pton(copy, out, len)) == -1) {
996 free(out);
997 free(copy);
998 return (0);
999 }
1000 free(copy);
1001
1002 /* Create a new paste buffer. */
1003 log_debug("%s: %.*s", __func__, outlen, out);
1004 paste_add(NULL, out, outlen);
1005
1006 return (0);
1007}
1008
1009/*
1010 * Handle device attributes input. Returns 0 for success, -1 for failure, 1 for
1011 * partial.
1012 */
1013static int
1014tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
1015 size_t *size)
1016{
1017 struct client *c = tty->client;
1018 u_int i, n = 0;
1019 char tmp[64], *endptr, p[32] = { 0 }, *cp, *next;
1020 int flags = 0;
1021
1022 *size = 0;
1023 if (tty->flags & TTY_HAVEDA)
1024 return (-1);
1025
1026 /* First three bytes are always \033[?. */
1027 if (buf[0] != '\033')
1028 return (-1);
1029 if (len == 1)
1030 return (1);
1031 if (buf[1] != '[')
1032 return (-1);
1033 if (len == 2)
1034 return (1);
1035 if (buf[2] != '?')
1036 return (-1);
1037 if (len == 3)
1038 return (1);
1039
1040 /* Copy the rest up to a 'c'. */
1041 for (i = 0; i < (sizeof tmp) - 1 && buf[3 + i] != 'c'; i++) {
1042 if (3 + i == len)
1043 return (1);
1044 tmp[i] = buf[3 + i];
1045 }
1046 if (i == (sizeof tmp) - 1)
1047 return (-1);
1048 tmp[i] = '\0';
1049 *size = 4 + i;
1050
1051 /* Convert version numbers. */
1052 cp = tmp;
1053 while ((next = strsep(&cp, ";")) != NULL) {
1054 p[n] = strtoul(next, &endptr, 10);
1055 if (*endptr != '\0')
1056 p[n] = 0;
1057 n++;
1058 }
1059
1060 /* Set terminal flags. */
1061 switch (p[0]) {
1062 case 64: /* VT420 */
1063 flags |= (TERM_DECFRA|TERM_DECSLRM);
1064 break;
1065 }
1066 for (i = 1; i < n; i++)
1067 log_debug("%s: DA feature: %d", c->name, p[i]);
1068 log_debug("%s: received DA %.*s", c->name, (int)*size, buf);
1069
1070 tty_set_flags(tty, flags);
1071 tty->flags |= TTY_HAVEDA;
1072
1073 return (0);
1074}
1075
1076/*
1077 * Handle device status report input. Returns 0 for success, -1 for failure, 1
1078 * for partial.
1079 */
1080static int
1081tty_keys_device_status_report(struct tty *tty, const char *buf, size_t len,
1082 size_t *size)
1083{
1084 struct client *c = tty->client;
1085 u_int i;
1086 char tmp[64];
1087 int flags = 0;
1088
1089 *size = 0;
1090 if (tty->flags & TTY_HAVEDSR)
1091 return (-1);
1092
1093 /* First three bytes are always \033[. */
1094 if (buf[0] != '\033')
1095 return (-1);
1096 if (len == 1)
1097 return (1);
1098 if (buf[1] != '[')
1099 return (-1);
1100 if (len == 2)
1101 return (1);
1102 if (buf[2] != 'I' && buf[2] != 'T')
1103 return (-1);
1104 if (len == 3)
1105 return (1);
1106
1107 /* Copy the rest up to a 'n'. */
1108 for (i = 0; i < (sizeof tmp) - 1 && buf[2 + i] != 'n'; i++) {
1109 if (2 + i == len)
1110 return (1);
1111 tmp[i] = buf[2 + i];
1112 }
1113 if (i == (sizeof tmp) - 1)
1114 return (-1);
1115 tmp[i] = '\0';
1116 *size = 3 + i;
1117
1118 /* Set terminal flags. */
1119 if (strncmp(tmp, "ITERM2 ", 7) == 0)
1120 flags |= (TERM_DECSLRM|TERM_256COLOURS|TERM_RGBCOLOURS);
1121 if (strncmp(tmp, "TMUX ", 5) == 0)
1122 flags |= (TERM_256COLOURS|TERM_RGBCOLOURS);
1123 log_debug("%s: received DSR %.*s", c->name, (int)*size, buf);
1124
1125 tty_set_flags(tty, flags);
1126 tty->flags |= TTY_HAVEDSR;
1127
1128 return (0);
1129}
1130