This source file includes following definitions.
- select_cmp_by_fd_set
- select_cmp_by_fd
- add_selects
- check_selects
- try_channels
- create_sequence
- define_sequences
- init_key_x11
- getch_with_delay
- xmouse_get_event
- get_modifier
- push_char
- correct_key_code
- getch_with_timeout
- learn_store_key
- k_dispose
- key_code_comparator_by_name
- key_code_comparator_by_code
- sort_key_conv_tab
- lookup_keyname
- lookup_keycode
- init_key
- init_key_input_fd
- done_key
- add_select_channel
- delete_select_channel
- channels_up
- channels_down
- tty_keyname_to_keycode
- tty_keycode_to_keyname
- define_sequence
- is_idle
- get_key_code
- tty_get_event
- tty_getch
- learn_key
- numeric_keypad_mode
- application_keypad_mode
- enable_bracketed_paste
- disable_bracketed_paste
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <config.h>
37
38 #include <ctype.h>
39 #include <errno.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #ifdef HAVE_SYS_SELECT_H
44 #include <sys/select.h>
45 #else
46 #include <sys/time.h>
47 #include <sys/types.h>
48 #include <unistd.h>
49 #endif
50
51 #include "lib/global.h"
52
53 #include "lib/vfs/vfs.h"
54
55 #include "tty.h"
56 #include "tty-internal.h"
57 #include "mouse.h"
58 #include "key.h"
59
60 #include "lib/widget.h"
61
62 #ifdef HAVE_TEXTMODE_X11_SUPPORT
63 #include "x11conn.h"
64 #endif
65
66 #ifdef __linux__
67 #if defined(__GLIBC__) && (__GLIBC__ < 2)
68 #include <linux/termios.h>
69 #else
70 #include <termios.h>
71 #endif
72 #ifdef HAVE_SYS_IOCTL_H
73 #include <sys/ioctl.h>
74 #endif
75 #endif
76
77 #ifdef __CYGWIN__
78 #include <termios.h>
79 #ifdef HAVE_SYS_IOCTL_H
80 #include <sys/ioctl.h>
81 #endif
82 #endif
83
84 #ifdef __QNXNTO__
85 #include <dlfcn.h>
86 #include <Ph.h>
87 #include <sys/dcmd_chr.h>
88 #endif
89
90
91
92 int mou_auto_repeat = 100;
93 int double_click_speed = 250;
94 gboolean old_esc_mode = TRUE;
95
96 int old_esc_mode_timeout = G_USEC_PER_SEC;
97 gboolean use_8th_bit_as_meta = FALSE;
98
99 gboolean bracketed_pasting_in_progress = FALSE;
100
101
102
103
104
105 const key_code_name_t key_name_conv_tab[] = {
106 {ESC_CHAR, "escape", N_("Escape"), "Esc"},
107
108
109 {KEY_F (1), "f1", N_("Function key 1"), "F1"},
110 {KEY_F (2), "f2", N_("Function key 2"), "F2"},
111 {KEY_F (3), "f3", N_("Function key 3"), "F3"},
112 {KEY_F (4), "f4", N_("Function key 4"), "F4"},
113 {KEY_F (5), "f5", N_("Function key 5"), "F5"},
114 {KEY_F (6), "f6", N_("Function key 6"), "F6"},
115 {KEY_F (7), "f7", N_("Function key 7"), "F7"},
116 {KEY_F (8), "f8", N_("Function key 8"), "F8"},
117 {KEY_F (9), "f9", N_("Function key 9"), "F9"},
118 {KEY_F (10), "f10", N_("Function key 10"), "F10"},
119 {KEY_F (11), "f11", N_("Function key 11"), "F11"},
120 {KEY_F (12), "f12", N_("Function key 12"), "F12"},
121 {KEY_F (13), "f13", N_("Function key 13"), "F13"},
122 {KEY_F (14), "f14", N_("Function key 14"), "F14"},
123 {KEY_F (15), "f15", N_("Function key 15"), "F15"},
124 {KEY_F (16), "f16", N_("Function key 16"), "F16"},
125 {KEY_F (17), "f17", N_("Function key 17"), "F17"},
126 {KEY_F (18), "f18", N_("Function key 18"), "F18"},
127 {KEY_F (19), "f19", N_("Function key 19"), "F19"},
128 {KEY_F (20), "f20", N_("Function key 20"), "F20"},
129 {ALT ('\t'), "complete", N_("Completion/M-tab"), "Meta-Tab"},
130 {KEY_BTAB, "backtab", N_("BackTab/S-tab"), "Shift-Tab"},
131 {KEY_BACKSPACE, "backspace", N_("Backspace"), "Backspace"},
132 {KEY_UP, "up", N_("Up arrow"), "Up"},
133 {KEY_DOWN, "down", N_("Down arrow"), "Down"},
134 {KEY_LEFT, "left", N_("Left arrow"), "Left"},
135 {KEY_RIGHT, "right", N_("Right arrow"), "Right"},
136 {KEY_IC, "insert", N_("Insert"), "Ins"},
137 {KEY_DC, "delete", N_("Delete"), "Del"},
138 {KEY_HOME, "home", N_("Home"), "Home"},
139 {KEY_END, "end", N_("End key"), "End"},
140 {KEY_PPAGE, "pgup", N_("Page Up"), "PgUp"},
141 {KEY_NPAGE, "pgdn", N_("Page Down"), "PgDn"},
142 {(int) '/', "kpslash", N_("/ on keypad"), "/"},
143 {KEY_KP_MULTIPLY, "kpasterisk", N_("* on keypad"), "*"},
144 {KEY_KP_SUBTRACT, "kpminus", N_("- on keypad"), "-"},
145 {KEY_KP_ADD, "kpplus", N_("+ on keypad"), "+"},
146
147
148 {KEY_LEFT, "kpleft", N_("Left arrow keypad"), "Left"},
149 {KEY_RIGHT, "kpright", N_("Right arrow keypad"), "Right"},
150 {KEY_UP, "kpup", N_("Up arrow keypad"), "Up"},
151 {KEY_DOWN, "kpdown", N_("Down arrow keypad"), "Down"},
152 {KEY_HOME, "kphome", N_("Home on keypad"), "Home"},
153 {KEY_END, "kpend", N_("End on keypad"), "End"},
154 {KEY_NPAGE, "kpnpage", N_("Page Down keypad"), "PgDn"},
155 {KEY_PPAGE, "kpppage", N_("Page Up keypad"), "PgUp"},
156 {KEY_IC, "kpinsert", N_("Insert on keypad"), "Ins"},
157 {KEY_DC, "kpdelete", N_("Delete on keypad"), "Del"},
158 {(int) '\n', "kpenter", N_("Enter on keypad"), "Enter"},
159 {KEY_F (21), "f21", N_("Function key 21"), "F21"},
160 {KEY_F (22), "f22", N_("Function key 22"), "F22"},
161 {KEY_F (23), "f23", N_("Function key 23"), "F23"},
162 {KEY_F (24), "f24", N_("Function key 24"), "F24"},
163 {KEY_A1, "a1", N_("A1 key"), "A1"},
164 {KEY_C1, "c1", N_("C1 key"), "C1"},
165
166
167 {ESC_CHAR, "esc", N_("Escape"), "Esc"},
168 {KEY_BACKSPACE, "bs", N_("Backspace"), "Bakspace"},
169 {KEY_IC, "ins", N_("Insert"), "Ins"},
170 {KEY_DC, "del", N_("Delete"), "Del"},
171 {(int) '*', "asterisk", N_("Asterisk"), "*"},
172 {(int) '-', "minus", N_("Minus"), "-"},
173 {(int) '+', "plus", N_("Plus"), "+"},
174 {(int) '.', "dot", N_("Dot"), "."},
175 {(int) '<', "lt", N_("Less than"), "<"},
176 {(int) '>', "gt", N_("Great than"), ">"},
177 {(int) '=', "equal", N_("Equal"), "="},
178 {(int) ',', "comma", N_("Comma"), ","},
179 {(int) '\'', "apostrophe", N_("Apostrophe"), "\'"},
180 {(int) ':', "colon", N_("Colon"), ":"},
181 {(int) ';', "semicolon", N_("Semicolon"), ";"},
182 {(int) '!', "exclamation", N_("Exclamation mark"), "!"},
183 {(int) '?', "question", N_("Question mark"), "?"},
184 {(int) '&', "ampersand", N_("Ampersand"), "&"},
185 {(int) '$', "dollar", N_("Dollar sign"), "$"},
186 {(int) '"', "quota", N_("Quotation mark"), "\""},
187 {(int) '%', "percent", N_("Percent sign"), "%"},
188 {(int) '^', "caret", N_("Caret"), "^"},
189 {(int) '~', "tilda", N_("Tilda"), "~"},
190 {(int) '`', "prime", N_("Prime"), "`"},
191 {(int) '_', "underline", N_("Underline"), "_"},
192 {(int) '_', "understrike", N_("Understrike"), "_"},
193 {(int) '|', "pipe", N_("Pipe"), "|"},
194 {(int) '(', "lparenthesis", N_("Left parenthesis"), "("},
195 {(int) ')', "rparenthesis", N_("Right parenthesis"), ")"},
196 {(int) '[', "lbracket", N_("Left bracket"), "["},
197 {(int) ']', "rbracket", N_("Right bracket"), "]"},
198 {(int) '{', "lbrace", N_("Left brace"), "{"},
199 {(int) '}', "rbrace", N_("Right brace"), "}"},
200 {(int) '\n', "enter", N_("Enter"), "Enter"},
201 {(int) '\t', "tab", N_("Tab key"), "Tab"},
202 {(int) ' ', "space", N_("Space key"), "Space"},
203 {(int) '/', "slash", N_("Slash key"), "/"},
204 {(int) '\\', "backslash", N_("Backslash key"), "\\"},
205 {(int) '#', "number", N_("Number sign #"), "#"},
206 {(int) '#', "hash", N_("Number sign #"), "#"},
207
208 {(int) '@', "at", N_("At sign"), "@"},
209
210
211 {KEY_M_CTRL, "control", N_("Ctrl"), "C"},
212 {KEY_M_CTRL, "ctrl", N_("Ctrl"), "C"},
213 {KEY_M_ALT, "meta", N_("Alt"), "M"},
214 {KEY_M_ALT, "alt", N_("Alt"), "M"},
215 {KEY_M_ALT, "ralt", N_("Alt"), "M"},
216 {KEY_M_SHIFT, "shift", N_("Shift"), "S"},
217
218 {0, NULL, NULL, NULL}
219 };
220
221
222
223 #define MC_USEC_PER_MSEC 1000
224
225
226 #define SEQ_BUFFER_LEN 33
227
228
229
230
231 typedef enum
232 {
233 SHIFT_PRESSED = (1 << 0),
234 ALTR_PRESSED = (1 << 1),
235 CONTROL_PRESSED = (1 << 2),
236 ALTL_PRESSED = (1 << 3)
237 } mod_pressed_t;
238
239 typedef struct key_def
240 {
241 char ch;
242 int code;
243 struct key_def *next;
244 struct key_def *child;
245 int action;
246
247
248 } key_def;
249
250 typedef struct
251 {
252 int code;
253 const char *seq;
254 int action;
255 } key_define_t;
256
257
258 typedef struct
259 {
260 int fd;
261 select_fn callback;
262 void *info;
263 } select_t;
264
265 typedef enum KeySortType
266 {
267 KEY_NOSORT = 0,
268 KEY_SORTBYNAME,
269 KEY_SORTBYCODE
270 } KeySortType;
271
272 #ifdef __QNXNTO__
273 typedef int (*ph_dv_f) (void *, void *);
274 typedef int (*ph_ov_f) (void *);
275 typedef int (*ph_pqc_f) (unsigned short, PhCursorInfo_t *);
276 #endif
277
278
279
280
281
282 static key_define_t mc_default_keys[] = {
283 {ESC_CHAR, ESC_STR, MCKEY_ESCAPE},
284 {ESC_CHAR, ESC_STR ESC_STR, MCKEY_NOACTION},
285 {MCKEY_BRACKETED_PASTING_START, ESC_STR "[200~", MCKEY_NOACTION},
286 {MCKEY_BRACKETED_PASTING_END, ESC_STR "[201~", MCKEY_NOACTION},
287 {0, NULL, MCKEY_NOACTION},
288 };
289
290
291 static key_define_t xterm_key_defines[] = {
292 {KEY_F (1), ESC_STR "OP", MCKEY_NOACTION},
293 {KEY_F (2), ESC_STR "OQ", MCKEY_NOACTION},
294 {KEY_F (3), ESC_STR "OR", MCKEY_NOACTION},
295 {KEY_F (4), ESC_STR "OS", MCKEY_NOACTION},
296 {KEY_F (1), ESC_STR "[11~", MCKEY_NOACTION},
297 {KEY_F (2), ESC_STR "[12~", MCKEY_NOACTION},
298 {KEY_F (3), ESC_STR "[13~", MCKEY_NOACTION},
299 {KEY_F (4), ESC_STR "[14~", MCKEY_NOACTION},
300 {KEY_F (5), ESC_STR "[15~", MCKEY_NOACTION},
301 {KEY_F (6), ESC_STR "[17~", MCKEY_NOACTION},
302 {KEY_F (7), ESC_STR "[18~", MCKEY_NOACTION},
303 {KEY_F (8), ESC_STR "[19~", MCKEY_NOACTION},
304 {KEY_F (9), ESC_STR "[20~", MCKEY_NOACTION},
305 {KEY_F (10), ESC_STR "[21~", MCKEY_NOACTION},
306
307
308 {KEY_M_SHIFT | KEY_UP, ESC_STR "O2A", MCKEY_NOACTION},
309 {KEY_M_SHIFT | KEY_DOWN, ESC_STR "O2B", MCKEY_NOACTION},
310 {KEY_M_SHIFT | KEY_RIGHT, ESC_STR "O2C", MCKEY_NOACTION},
311 {KEY_M_SHIFT | KEY_LEFT, ESC_STR "O2D", MCKEY_NOACTION},
312
313
314 {KEY_M_SHIFT | KEY_UP, ESC_STR "[1;2A", MCKEY_NOACTION},
315 {KEY_M_SHIFT | KEY_DOWN, ESC_STR "[1;2B", MCKEY_NOACTION},
316 {KEY_M_SHIFT | KEY_RIGHT, ESC_STR "[1;2C", MCKEY_NOACTION},
317 {KEY_M_SHIFT | KEY_LEFT, ESC_STR "[1;2D", MCKEY_NOACTION},
318
319
320 {KEY_M_CTRL | KEY_PPAGE, ESC_STR "[5;5~", MCKEY_NOACTION},
321 {KEY_M_CTRL | KEY_NPAGE, ESC_STR "[6;5~", MCKEY_NOACTION},
322 {KEY_M_CTRL | KEY_IC, ESC_STR "[2;5~", MCKEY_NOACTION},
323 {KEY_M_CTRL | KEY_DC, ESC_STR "[3;5~", MCKEY_NOACTION},
324 {KEY_M_CTRL | KEY_HOME, ESC_STR "[1;5H", MCKEY_NOACTION},
325 {KEY_M_CTRL | KEY_END, ESC_STR "[1;5F", MCKEY_NOACTION},
326 {KEY_M_SHIFT | KEY_HOME, ESC_STR "[1;2H", MCKEY_NOACTION},
327 {KEY_M_SHIFT | KEY_END, ESC_STR "[1;2F", MCKEY_NOACTION},
328 {KEY_M_CTRL | KEY_UP, ESC_STR "[1;5A", MCKEY_NOACTION},
329 {KEY_M_CTRL | KEY_DOWN, ESC_STR "[1;5B", MCKEY_NOACTION},
330 {KEY_M_CTRL | KEY_RIGHT, ESC_STR "[1;5C", MCKEY_NOACTION},
331 {KEY_M_CTRL | KEY_LEFT, ESC_STR "[1;5D", MCKEY_NOACTION},
332 {KEY_M_SHIFT | KEY_IC, ESC_STR "[2;2~", MCKEY_NOACTION},
333 {KEY_M_SHIFT | KEY_DC, ESC_STR "[3;2~", MCKEY_NOACTION},
334 {KEY_M_SHIFT | KEY_M_CTRL | KEY_UP, ESC_STR "[1;6A", MCKEY_NOACTION},
335 {KEY_M_SHIFT | KEY_M_CTRL | KEY_DOWN, ESC_STR "[1;6B", MCKEY_NOACTION},
336 {KEY_M_SHIFT | KEY_M_CTRL | KEY_RIGHT, ESC_STR "[1;6C", MCKEY_NOACTION},
337 {KEY_M_SHIFT | KEY_M_CTRL | KEY_LEFT, ESC_STR "[1;6D", MCKEY_NOACTION},
338 {KEY_M_SHIFT | '\t', ESC_STR "[Z", MCKEY_NOACTION},
339
340
341 {KEY_M_SHIFT | KEY_M_CTRL | KEY_UP, ESC_STR "[[1;6A", MCKEY_NOACTION},
342 {KEY_M_SHIFT | KEY_M_CTRL | KEY_DOWN, ESC_STR "[[1;6B", MCKEY_NOACTION},
343 {KEY_M_SHIFT | KEY_M_CTRL | KEY_RIGHT, ESC_STR "[[1;6C", MCKEY_NOACTION},
344 {KEY_M_SHIFT | KEY_M_CTRL | KEY_LEFT, ESC_STR "[[1;6D", MCKEY_NOACTION},
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369 {KEY_M_ALT | KEY_UP, ESC_STR "[1;3A", MCKEY_NOACTION},
370 {KEY_M_ALT | KEY_DOWN, ESC_STR "[1;3B", MCKEY_NOACTION},
371 {KEY_M_ALT | KEY_RIGHT, ESC_STR "[1;3C", MCKEY_NOACTION},
372 {KEY_M_ALT | KEY_LEFT, ESC_STR "[1;3D", MCKEY_NOACTION},
373 {KEY_M_ALT | KEY_PPAGE, ESC_STR "[5;3~", MCKEY_NOACTION},
374 {KEY_M_ALT | KEY_NPAGE, ESC_STR "[6;3~", MCKEY_NOACTION},
375 {KEY_M_ALT | KEY_HOME, ESC_STR "[1~", MCKEY_NOACTION},
376 {KEY_M_ALT | KEY_END, ESC_STR "[4~", MCKEY_NOACTION},
377 {KEY_M_CTRL | KEY_M_ALT | KEY_UP, ESC_STR "[1;7A", MCKEY_NOACTION},
378 {KEY_M_CTRL | KEY_M_ALT | KEY_DOWN, ESC_STR "[1;7B", MCKEY_NOACTION},
379 {KEY_M_CTRL | KEY_M_ALT | KEY_RIGHT, ESC_STR "[1;7C", MCKEY_NOACTION},
380 {KEY_M_CTRL | KEY_M_ALT | KEY_LEFT, ESC_STR "[1;7D", MCKEY_NOACTION},
381 {KEY_M_CTRL | KEY_M_ALT | KEY_PPAGE, ESC_STR "[5;7~", MCKEY_NOACTION},
382 {KEY_M_CTRL | KEY_M_ALT | KEY_NPAGE, ESC_STR "[6;7~", MCKEY_NOACTION},
383 {KEY_M_CTRL | KEY_M_ALT | KEY_HOME, ESC_STR "OH", MCKEY_NOACTION},
384 {KEY_M_CTRL | KEY_M_ALT | KEY_END, ESC_STR "OF", MCKEY_NOACTION},
385
386 {KEY_M_SHIFT | KEY_M_ALT | KEY_UP, ESC_STR "[1;4A", MCKEY_NOACTION},
387 {KEY_M_SHIFT | KEY_M_ALT | KEY_DOWN, ESC_STR "[1;4B", MCKEY_NOACTION},
388 {KEY_M_SHIFT | KEY_M_ALT | KEY_RIGHT, ESC_STR "[1;4C", MCKEY_NOACTION},
389 {KEY_M_SHIFT | KEY_M_ALT | KEY_LEFT, ESC_STR "[1;4D", MCKEY_NOACTION},
390
391
392 {KEY_M_SHIFT | KEY_UP, ESC_STR "[a", MCKEY_NOACTION},
393 {KEY_M_SHIFT | KEY_DOWN, ESC_STR "[b", MCKEY_NOACTION},
394 {KEY_M_SHIFT | KEY_RIGHT, ESC_STR "[c", MCKEY_NOACTION},
395 {KEY_M_SHIFT | KEY_LEFT, ESC_STR "[d", MCKEY_NOACTION},
396 {KEY_M_CTRL | KEY_UP, ESC_STR "Oa", MCKEY_NOACTION},
397 {KEY_M_CTRL | KEY_DOWN, ESC_STR "Ob", MCKEY_NOACTION},
398 {KEY_M_CTRL | KEY_RIGHT, ESC_STR "Oc", MCKEY_NOACTION},
399 {KEY_M_CTRL | KEY_LEFT, ESC_STR "Od", MCKEY_NOACTION},
400 {KEY_M_CTRL | KEY_PPAGE, ESC_STR "[5^", MCKEY_NOACTION},
401 {KEY_M_CTRL | KEY_NPAGE, ESC_STR "[6^", MCKEY_NOACTION},
402 {KEY_M_CTRL | KEY_HOME, ESC_STR "[7^", MCKEY_NOACTION},
403 {KEY_M_CTRL | KEY_END, ESC_STR "[8^", MCKEY_NOACTION},
404 {KEY_M_SHIFT | KEY_HOME, ESC_STR "[7$", MCKEY_NOACTION},
405 {KEY_M_SHIFT | KEY_END, ESC_STR "[8$", MCKEY_NOACTION},
406 {KEY_M_CTRL | KEY_IC, ESC_STR "[2^", MCKEY_NOACTION},
407 {KEY_M_CTRL | KEY_DC, ESC_STR "[3^", MCKEY_NOACTION},
408 {KEY_M_SHIFT | KEY_DC, ESC_STR "[3$", MCKEY_NOACTION},
409
410
411 {KEY_M_SHIFT | KEY_HOME, ESC_STR "O2H", MCKEY_NOACTION},
412 {KEY_M_SHIFT | KEY_END, ESC_STR "O2F", MCKEY_NOACTION},
413
414
415 {KEY_M_SHIFT | KEY_UP, ESC_STR "[2A", MCKEY_NOACTION},
416 {KEY_M_SHIFT | KEY_DOWN, ESC_STR "[2B", MCKEY_NOACTION},
417 {KEY_M_SHIFT | KEY_RIGHT, ESC_STR "[2C", MCKEY_NOACTION},
418 {KEY_M_SHIFT | KEY_LEFT, ESC_STR "[2D", MCKEY_NOACTION},
419 {KEY_M_CTRL | KEY_UP, ESC_STR "[5A", MCKEY_NOACTION},
420 {KEY_M_CTRL | KEY_DOWN, ESC_STR "[5B", MCKEY_NOACTION},
421 {KEY_M_CTRL | KEY_RIGHT, ESC_STR "[5C", MCKEY_NOACTION},
422 {KEY_M_CTRL | KEY_LEFT, ESC_STR "[5D", MCKEY_NOACTION},
423 {KEY_M_SHIFT | KEY_M_CTRL | KEY_UP, ESC_STR "[6A", MCKEY_NOACTION},
424 {KEY_M_SHIFT | KEY_M_CTRL | KEY_DOWN, ESC_STR "[6B", MCKEY_NOACTION},
425 {KEY_M_SHIFT | KEY_M_CTRL | KEY_RIGHT, ESC_STR "[6C", MCKEY_NOACTION},
426 {KEY_M_SHIFT | KEY_M_CTRL | KEY_LEFT, ESC_STR "[6D", MCKEY_NOACTION},
427
428
429 {KEY_M_CTRL | KEY_UP, ESC_STR "O5A", MCKEY_NOACTION},
430 {KEY_M_CTRL | KEY_DOWN, ESC_STR "O5B", MCKEY_NOACTION},
431 {KEY_M_CTRL | KEY_RIGHT, ESC_STR "O5C", MCKEY_NOACTION},
432 {KEY_M_CTRL | KEY_LEFT, ESC_STR "O5D", MCKEY_NOACTION},
433 {KEY_M_SHIFT | KEY_M_CTRL | KEY_UP, ESC_STR "O6A", MCKEY_NOACTION},
434 {KEY_M_SHIFT | KEY_M_CTRL | KEY_DOWN, ESC_STR "O6B", MCKEY_NOACTION},
435 {KEY_M_SHIFT | KEY_M_CTRL | KEY_RIGHT, ESC_STR "O6C", MCKEY_NOACTION},
436 {KEY_M_SHIFT | KEY_M_CTRL | KEY_LEFT, ESC_STR "O6D", MCKEY_NOACTION},
437
438
439 {KEY_M_SHIFT | KEY_PPAGE, ESC_STR "[5;2~", MCKEY_NOACTION},
440 {KEY_M_SHIFT | KEY_NPAGE, ESC_STR "[6;2~", MCKEY_NOACTION},
441
442
443 {KEY_M_SHIFT | KEY_PPAGE, ESC_STR "[[5;53~", MCKEY_NOACTION},
444 {KEY_M_SHIFT | KEY_NPAGE, ESC_STR "[[6;53~", MCKEY_NOACTION},
445
446
447 {KEY_IC, ESC_STR "Op", MCKEY_NOACTION},
448 {KEY_DC, ESC_STR "On", MCKEY_NOACTION},
449 {'/', ESC_STR "Oo", MCKEY_NOACTION},
450 {'\n', ESC_STR "OM", MCKEY_NOACTION},
451
452 {0, NULL, MCKEY_NOACTION},
453 };
454
455
456
457 static key_define_t qansi_key_defines[] = {
458
459 {KEY_M_CTRL | KEY_NPAGE, ESC_STR "[u", MCKEY_NOACTION},
460 {KEY_M_CTRL | KEY_PPAGE, ESC_STR "[v", MCKEY_NOACTION},
461 {KEY_M_CTRL | KEY_HOME, ESC_STR "[h", MCKEY_NOACTION},
462 {KEY_M_CTRL | KEY_END, ESC_STR "[y", MCKEY_NOACTION},
463 {KEY_M_CTRL | KEY_IC, ESC_STR "[`", MCKEY_NOACTION},
464 {KEY_M_CTRL | KEY_DC, ESC_STR "[p", MCKEY_NOACTION},
465 {KEY_M_CTRL | KEY_LEFT, ESC_STR "[d", MCKEY_NOACTION},
466 {KEY_M_CTRL | KEY_RIGHT, ESC_STR "[c", MCKEY_NOACTION},
467 {KEY_M_CTRL | KEY_DOWN, ESC_STR "[b", MCKEY_NOACTION},
468 {KEY_M_CTRL | KEY_UP, ESC_STR "[a", MCKEY_NOACTION},
469 {KEY_M_CTRL | KEY_KP_ADD, ESC_STR "[s", MCKEY_NOACTION},
470 {KEY_M_CTRL | KEY_KP_SUBTRACT, ESC_STR "[t", MCKEY_NOACTION},
471 {KEY_M_CTRL | '\t', ESC_STR "[z", MCKEY_NOACTION},
472 {KEY_M_SHIFT | '\t', ESC_STR "[Z", MCKEY_NOACTION},
473 {KEY_M_CTRL | KEY_F (1), ESC_STR "[1~", MCKEY_NOACTION},
474 {KEY_M_CTRL | KEY_F (2), ESC_STR "[2~", MCKEY_NOACTION},
475 {KEY_M_CTRL | KEY_F (3), ESC_STR "[3~", MCKEY_NOACTION},
476 {KEY_M_CTRL | KEY_F (4), ESC_STR "[4~", MCKEY_NOACTION},
477 {KEY_M_CTRL | KEY_F (5), ESC_STR "[5~", MCKEY_NOACTION},
478 {KEY_M_CTRL | KEY_F (6), ESC_STR "[6~", MCKEY_NOACTION},
479 {KEY_M_CTRL | KEY_F (7), ESC_STR "[7~", MCKEY_NOACTION},
480 {KEY_M_CTRL | KEY_F (8), ESC_STR "[8~", MCKEY_NOACTION},
481 {KEY_M_CTRL | KEY_F (9), ESC_STR "[9~", MCKEY_NOACTION},
482 {KEY_M_CTRL | KEY_F (10), ESC_STR "[10~", MCKEY_NOACTION},
483 {KEY_M_CTRL | KEY_F (11), ESC_STR "[11~", MCKEY_NOACTION},
484 {KEY_M_CTRL | KEY_F (12), ESC_STR "[12~", MCKEY_NOACTION},
485 {KEY_M_ALT | KEY_F (1), ESC_STR "[17~", MCKEY_NOACTION},
486 {KEY_M_ALT | KEY_F (2), ESC_STR "[18~", MCKEY_NOACTION},
487 {KEY_M_ALT | KEY_F (3), ESC_STR "[19~", MCKEY_NOACTION},
488 {KEY_M_ALT | KEY_F (4), ESC_STR "[20~", MCKEY_NOACTION},
489 {KEY_M_ALT | KEY_F (5), ESC_STR "[21~", MCKEY_NOACTION},
490 {KEY_M_ALT | KEY_F (6), ESC_STR "[22~", MCKEY_NOACTION},
491 {KEY_M_ALT | KEY_F (7), ESC_STR "[23~", MCKEY_NOACTION},
492 {KEY_M_ALT | KEY_F (8), ESC_STR "[24~", MCKEY_NOACTION},
493 {KEY_M_ALT | KEY_F (9), ESC_STR "[25~", MCKEY_NOACTION},
494 {KEY_M_ALT | KEY_F (10), ESC_STR "[26~", MCKEY_NOACTION},
495 {KEY_M_ALT | KEY_F (11), ESC_STR "[27~", MCKEY_NOACTION},
496 {KEY_M_ALT | KEY_F (12), ESC_STR "[28~", MCKEY_NOACTION},
497 {KEY_M_ALT | 'a', ESC_STR "Na", MCKEY_NOACTION},
498 {KEY_M_ALT | 'b', ESC_STR "Nb", MCKEY_NOACTION},
499 {KEY_M_ALT | 'c', ESC_STR "Nc", MCKEY_NOACTION},
500 {KEY_M_ALT | 'd', ESC_STR "Nd", MCKEY_NOACTION},
501 {KEY_M_ALT | 'e', ESC_STR "Ne", MCKEY_NOACTION},
502 {KEY_M_ALT | 'f', ESC_STR "Nf", MCKEY_NOACTION},
503 {KEY_M_ALT | 'g', ESC_STR "Ng", MCKEY_NOACTION},
504 {KEY_M_ALT | 'h', ESC_STR "Nh", MCKEY_NOACTION},
505 {KEY_M_ALT | 'i', ESC_STR "Ni", MCKEY_NOACTION},
506 {KEY_M_ALT | 'j', ESC_STR "Nj", MCKEY_NOACTION},
507 {KEY_M_ALT | 'k', ESC_STR "Nk", MCKEY_NOACTION},
508 {KEY_M_ALT | 'l', ESC_STR "Nl", MCKEY_NOACTION},
509 {KEY_M_ALT | 'm', ESC_STR "Nm", MCKEY_NOACTION},
510 {KEY_M_ALT | 'n', ESC_STR "Nn", MCKEY_NOACTION},
511 {KEY_M_ALT | 'o', ESC_STR "No", MCKEY_NOACTION},
512 {KEY_M_ALT | 'p', ESC_STR "Np", MCKEY_NOACTION},
513 {KEY_M_ALT | 'q', ESC_STR "Nq", MCKEY_NOACTION},
514 {KEY_M_ALT | 'r', ESC_STR "Nr", MCKEY_NOACTION},
515 {KEY_M_ALT | 's', ESC_STR "Ns", MCKEY_NOACTION},
516 {KEY_M_ALT | 't', ESC_STR "Nt", MCKEY_NOACTION},
517 {KEY_M_ALT | 'u', ESC_STR "Nu", MCKEY_NOACTION},
518 {KEY_M_ALT | 'v', ESC_STR "Nv", MCKEY_NOACTION},
519 {KEY_M_ALT | 'w', ESC_STR "Nw", MCKEY_NOACTION},
520 {KEY_M_ALT | 'x', ESC_STR "Nx", MCKEY_NOACTION},
521 {KEY_M_ALT | 'y', ESC_STR "Ny", MCKEY_NOACTION},
522 {KEY_M_ALT | 'z', ESC_STR "Nz", MCKEY_NOACTION},
523 {KEY_KP_SUBTRACT, ESC_STR "[S", MCKEY_NOACTION},
524 {KEY_KP_ADD, ESC_STR "[T", MCKEY_NOACTION},
525 {0, NULL, MCKEY_NOACTION},
526 };
527
528
529 static key_def *keys = NULL;
530
531 static int input_fd;
532 static int disabled_channels = 0;
533
534 static GSList *select_list = NULL;
535
536 static int seq_buffer[SEQ_BUFFER_LEN];
537 static int *seq_append = NULL;
538
539 static int *pending_keys = NULL;
540
541 #ifdef __QNXNTO__
542 ph_dv_f ph_attach;
543 ph_ov_f ph_input_group;
544 ph_pqc_f ph_query_cursor;
545 #endif
546
547 #ifdef HAVE_TEXTMODE_X11_SUPPORT
548 static Display *x11_display;
549 static Window x11_window;
550 #endif
551
552 static KeySortType has_been_sorted = KEY_NOSORT;
553
554
555 static const size_t key_conv_tab_size = G_N_ELEMENTS (key_name_conv_tab) - 1;
556
557
558 static const key_code_name_t *key_conv_tab_sorted[G_N_ELEMENTS (key_name_conv_tab) - 1];
559
560
561
562
563
564 static int
565 select_cmp_by_fd_set (gconstpointer a, gconstpointer b)
566 {
567 const select_t *s = (const select_t *) a;
568 const fd_set *f = (const fd_set *) b;
569
570 return (FD_ISSET (s->fd, f) ? 0 : 1);
571 }
572
573
574
575 static int
576 select_cmp_by_fd (gconstpointer a, gconstpointer b)
577 {
578 const select_t *s = (const select_t *) a;
579 const int fd = GPOINTER_TO_INT (b);
580
581 return (s->fd == fd ? 0 : 1);
582 }
583
584
585
586 static int
587 add_selects (fd_set *select_set)
588 {
589 int top_fd = 0;
590
591 if (disabled_channels == 0)
592 {
593 GSList *s;
594
595 for (s = select_list; s != NULL; s = g_slist_next (s))
596 {
597 select_t *p = (select_t *) s->data;
598
599 FD_SET (p->fd, select_set);
600 if (p->fd > top_fd)
601 top_fd = p->fd;
602 }
603 }
604
605 return top_fd;
606 }
607
608
609
610 static void
611 check_selects (fd_set *select_set)
612 {
613 while (disabled_channels == 0)
614 {
615 GSList *s;
616 select_t *p;
617
618 s = g_slist_find_custom (select_list, select_set, select_cmp_by_fd_set);
619 if (s == NULL)
620 break;
621
622 p = (select_t *) s->data;
623 FD_CLR (p->fd, select_set);
624 p->callback (p->fd, p->info);
625 }
626 }
627
628
629
630
631 static void
632 try_channels (gboolean set_timeout)
633 {
634 struct timeval time_out;
635 static fd_set select_set;
636
637 while (TRUE)
638 {
639 struct timeval *timeptr = NULL;
640 int maxfdp, v;
641
642 FD_ZERO (&select_set);
643 FD_SET (input_fd, &select_set);
644 maxfdp = MAX (add_selects (&select_set), input_fd);
645
646 if (set_timeout)
647 {
648 time_out.tv_sec = 0;
649 time_out.tv_usec = 100 * MC_USEC_PER_MSEC;
650 timeptr = &time_out;
651 }
652
653 v = select (maxfdp + 1, &select_set, NULL, NULL, timeptr);
654 if (v > 0)
655 {
656 check_selects (&select_set);
657 if (FD_ISSET (input_fd, &select_set))
658 break;
659 }
660 }
661 }
662
663
664
665 static key_def *
666 create_sequence (const char *seq, int code, int action)
667 {
668 key_def *base, *attach;
669
670 for (base = attach = NULL; *seq != '\0'; seq++)
671 {
672 key_def *p;
673
674 p = g_new (key_def, 1);
675 if (base == NULL)
676 base = p;
677 if (attach != NULL)
678 attach->child = p;
679
680 p->ch = *seq;
681 p->code = code;
682 p->child = NULL;
683 p->next = NULL;
684 p->action = seq[1] == '\0' ? action : MCKEY_NOACTION;
685 attach = p;
686 }
687 return base;
688 }
689
690
691
692 static void
693 define_sequences (const key_define_t *kd)
694 {
695 int i;
696
697 for (i = 0; kd[i].code != 0; i++)
698 define_sequence (kd[i].code, kd[i].seq, kd[i].action);
699 }
700
701
702
703 #ifdef HAVE_TEXTMODE_X11_SUPPORT
704 static void
705 init_key_x11 (void)
706 {
707 if (getenv ("DISPLAY") != NULL && !mc_global.tty.disable_x11)
708 {
709 x11_display = mc_XOpenDisplay (0);
710
711 if (x11_display != NULL)
712 x11_window = DefaultRootWindow (x11_display);
713 }
714 }
715 #endif
716
717
718
719
720 static int
721 getch_with_delay (void)
722 {
723 int c;
724
725
726
727 while (TRUE)
728 {
729 if (pending_keys == NULL)
730 try_channels (FALSE);
731
732
733 c = get_key_code (0);
734 if (c != -1)
735 break;
736
737
738 try_channels (TRUE);
739 }
740
741
742 return c;
743 }
744
745
746
747 static void
748 xmouse_get_event (Gpm_Event *ev, gboolean extended)
749 {
750 static gint64 tv1 = 0;
751 static int clicks = 0;
752 static int last_btn = 0;
753 int btn;
754
755
756
757 if (!extended)
758 {
759
760
761 btn = tty_lowlevel_getch () - 32;
762
763
764 ev->x = tty_lowlevel_getch () - 32;
765 ev->y = tty_lowlevel_getch () - 32;
766 }
767 else
768 {
769
770
771
772
773
774
775 char c;
776
777 btn = ev->x = ev->y = 0;
778 ev->type = 0;
779
780 while ((c = tty_lowlevel_getch ()) != ';')
781 {
782 if (c < '0' || c > '9')
783 return;
784 btn = 10 * btn + (c - '0');
785 }
786 while ((c = tty_lowlevel_getch ()) != ';')
787 {
788 if (c < '0' || c > '9')
789 return;
790 ev->x = 10 * ev->x + (c - '0');
791 }
792 while ((c = tty_lowlevel_getch ()) != 'M' && c != 'm')
793 {
794 if (c < '0' || c > '9')
795 return;
796 ev->y = 10 * ev->y + (c - '0');
797 }
798
799
800
801
802 if (c == 'm')
803 btn = 3;
804 }
805
806
807
808
809 if (btn == 3)
810 {
811 if (last_btn != 0)
812 {
813 if ((last_btn & (GPM_B_UP | GPM_B_DOWN)) != 0)
814 {
815
816
817
818 ev->type = 0;
819 tv1 = 0;
820 }
821 else
822 {
823 ev->type = GPM_UP | (GPM_SINGLE << clicks);
824 tv1 = g_get_monotonic_time ();
825 }
826 ev->buttons = 0;
827 last_btn = 0;
828 clicks = 0;
829 }
830 else
831 {
832
833 ev->type = 0;
834 }
835 }
836 else
837 {
838 gint64 tv2;
839
840 if (btn >= 32 && btn <= 34)
841 {
842 btn -= 32;
843 ev->type = GPM_DRAG;
844 }
845 else
846 ev->type = GPM_DOWN;
847
848 tv2 = g_get_monotonic_time ();
849 if (tv1 != 0 && tv2 - tv1 < (gint64) double_click_speed * MC_USEC_PER_MSEC)
850 {
851 clicks++;
852 clicks %= 3;
853 }
854 else
855 clicks = 0;
856
857 switch (btn)
858 {
859 case 0:
860 ev->buttons = GPM_B_LEFT;
861 break;
862 case 1:
863 ev->buttons = GPM_B_MIDDLE;
864 break;
865 case 2:
866 ev->buttons = GPM_B_RIGHT;
867 break;
868 case 64:
869 ev->buttons = GPM_B_UP;
870 clicks = 0;
871 break;
872 case 65:
873 ev->buttons = GPM_B_DOWN;
874 clicks = 0;
875 break;
876 default:
877
878 ev->type = 0;
879 ev->buttons = 0;
880 break;
881 }
882 last_btn = ev->buttons;
883 }
884 }
885
886
887
888
889
890
891
892
893
894
895 static int
896 get_modifier (void)
897 {
898 int result = 0;
899 #ifdef __QNXNTO__
900 static int in_photon = 0;
901 static int ph_ig = 0;
902 #endif
903
904 #ifdef HAVE_TEXTMODE_X11_SUPPORT
905 if (x11_window != 0)
906 {
907 Window root, child;
908 int root_x, root_y;
909 int win_x, win_y;
910 unsigned int mask;
911
912 mc_XQueryPointer (x11_display, x11_window, &root, &child, &root_x,
913 &root_y, &win_x, &win_y, &mask);
914
915 if ((mask & ShiftMask) != 0)
916 result |= KEY_M_SHIFT;
917 if ((mask & ControlMask) != 0)
918 result |= KEY_M_CTRL;
919 return result;
920 }
921 #endif
922
923 #ifdef __QNXNTO__
924 if (in_photon == 0)
925 {
926
927 in_photon = -1;
928
929 if (getenv ("PHOTON2_PATH") != NULL)
930 {
931
932 void *ph_handle;
933
934 ph_handle = dlopen ("/usr/lib/libph.so", RTLD_NOW);
935 if (ph_handle != NULL)
936 {
937 ph_attach = (ph_dv_f) dlsym (ph_handle, "PhAttach");
938 ph_input_group = (ph_ov_f) dlsym (ph_handle, "PhInputGroup");
939 ph_query_cursor = (ph_pqc_f) dlsym (ph_handle, "PhQueryCursor");
940 if ((ph_attach != NULL) && (ph_input_group != NULL) && (ph_query_cursor != NULL)
941 && (*ph_attach) (0, 0) != NULL)
942 {
943
944 ph_ig = (*ph_input_group) (0);
945 in_photon = 1;
946 }
947 }
948 }
949 }
950
951 if (in_photon == -1)
952 {
953 int mod_status;
954 int shift_ext_status;
955
956 if (devctl (fileno (stdin), DCMD_CHR_LINESTATUS, &mod_status, sizeof (mod_status), NULL) ==
957 -1)
958 return 0;
959
960 shift_ext_status = mod_status & 0xffffff00UL;
961 mod_status &= 0x7f;
962 if ((mod_status & _LINESTATUS_CON_ALT) != 0)
963 result |= KEY_M_ALT;
964 if ((mod_status & _LINESTATUS_CON_CTRL) != 0)
965 result |= KEY_M_CTRL;
966 if ((mod_status & _LINESTATUS_CON_SHIFT) != 0 || (shift_ext_status & 0x00000800UL) != 0)
967 result |= KEY_M_SHIFT;
968 }
969 else
970 {
971 PhCursorInfo_t cursor_info;
972
973 (*ph_query_cursor) (ph_ig, &cursor_info);
974 if ((cursor_info.key_mods & 0x04) != 0)
975 result |= KEY_M_ALT;
976 if ((cursor_info.key_mods & 0x02) != 0)
977 result |= KEY_M_CTRL;
978 if ((cursor_info.key_mods & 0x01) != 0)
979 result |= KEY_M_SHIFT;
980 }
981 #endif
982
983 #if defined __linux__ || (defined __CYGWIN__ && defined TIOCLINUX)
984 {
985 unsigned char modifiers = 6;
986
987 if (ioctl (0, TIOCLINUX, &modifiers) < 0)
988 return 0;
989
990
991 if ((modifiers & SHIFT_PRESSED) != 0)
992 result |= KEY_M_SHIFT;
993 if ((modifiers & (ALTL_PRESSED | ALTR_PRESSED)) != 0)
994 result |= KEY_M_ALT;
995 if ((modifiers & CONTROL_PRESSED) != 0)
996 result |= KEY_M_CTRL;
997 }
998 #endif
999
1000 return result;
1001 }
1002
1003
1004
1005 static gboolean
1006 push_char (int c)
1007 {
1008 gboolean ret = FALSE;
1009
1010 if (seq_append == NULL)
1011 seq_append = seq_buffer;
1012
1013 if (seq_append != &(seq_buffer[SEQ_BUFFER_LEN - 2]))
1014 {
1015 *(seq_append++) = c;
1016 *seq_append = '\0';
1017 ret = TRUE;
1018 }
1019
1020 return ret;
1021 }
1022
1023
1024
1025
1026 static int
1027 correct_key_code (int code)
1028 {
1029 unsigned int c = code & ~KEY_M_MASK;
1030 unsigned int mod = code & KEY_M_MASK;
1031 #ifdef __QNXNTO__
1032 unsigned int qmod;
1033
1034 #endif
1035
1036
1037
1038
1039
1040 if (c < 32 || c >= 256)
1041 mod |= get_modifier ();
1042
1043
1044 if (c == '\r')
1045 c = '\n';
1046
1047
1048 if (c == KEY_SCANCEL)
1049 c = '\t';
1050
1051
1052 if (c == KEY_BTAB)
1053 {
1054 c = '\t';
1055 mod = KEY_M_SHIFT;
1056 }
1057
1058
1059 if (c == KEY_F (0))
1060 c = KEY_F (10);
1061
1062
1063
1064
1065
1066
1067
1068 if (c == '\b')
1069 {
1070
1071 c = KEY_BACKSPACE;
1072 mod &= ~KEY_M_CTRL;
1073 }
1074 else if (c < 32 && c != ESC_CHAR && c != '\t' && c != '\n')
1075 mod |= KEY_M_CTRL;
1076
1077 #ifdef __QNXNTO__
1078 qmod = get_modifier ();
1079
1080 if (c == 127 && mod == 0)
1081 {
1082
1083 mod |= get_modifier ();
1084 c = KEY_BACKSPACE;
1085 }
1086
1087 if (c == '0' && mod == 0 && (qmod & KEY_M_SHIFT) == KEY_M_SHIFT)
1088 {
1089
1090 mod = KEY_M_SHIFT;
1091 c = KEY_IC;
1092 }
1093
1094 if (c == '.' && mod == 0 && (qmod & KEY_M_SHIFT) == KEY_M_SHIFT)
1095 {
1096
1097 mod = KEY_M_SHIFT;
1098 c = KEY_DC;
1099 }
1100 #endif
1101
1102
1103 if (c == 0177)
1104 c = KEY_BACKSPACE;
1105
1106 #if 0
1107
1108 if (c == 'd' & 31)
1109 {
1110 c = KEY_DC;
1111 mod &= ~KEY_M_CTRL;
1112 }
1113
1114
1115 if (c == 'h' & 31)
1116 {
1117 c = KEY_BACKSPACE;
1118 mod &= ~KEY_M_CTRL;
1119 }
1120 #endif
1121
1122
1123 if (c == KEY_BACKSPACE && (mod & KEY_M_SHIFT) != 0)
1124 mod &= ~KEY_M_SHIFT;
1125
1126
1127 if (c >= KEY_F (1) && c <= KEY_F (10) && (mod & KEY_M_SHIFT) != 0)
1128 c += 10;
1129
1130
1131 if (c >= KEY_F (1) && c <= KEY_F (20))
1132 mod &= ~KEY_M_SHIFT;
1133
1134 if (!mc_global.tty.alternate_plus_minus)
1135 switch (c)
1136 {
1137 case KEY_KP_ADD:
1138 c = '+';
1139 break;
1140 case KEY_KP_SUBTRACT:
1141 c = '-';
1142 break;
1143 case KEY_KP_MULTIPLY:
1144 c = '*';
1145 break;
1146 default:
1147 break;
1148 }
1149
1150 return (mod | c);
1151 }
1152
1153
1154
1155 static int
1156 getch_with_timeout (unsigned int delay_us)
1157 {
1158 fd_set Read_FD_Set;
1159 int c;
1160 struct timeval time_out;
1161
1162 time_out.tv_sec = delay_us / G_USEC_PER_SEC;
1163 time_out.tv_usec = delay_us % G_USEC_PER_SEC;
1164 tty_nodelay (TRUE);
1165 FD_ZERO (&Read_FD_Set);
1166 FD_SET (input_fd, &Read_FD_Set);
1167 select (input_fd + 1, &Read_FD_Set, NULL, NULL, &time_out);
1168 c = tty_lowlevel_getch ();
1169 tty_nodelay (FALSE);
1170 return c;
1171 }
1172
1173
1174
1175 static void
1176 learn_store_key (GString *buffer, int c)
1177 {
1178 if (c == ESC_CHAR)
1179 g_string_append (buffer, "\\e");
1180 else if (c < ' ')
1181 {
1182 g_string_append_c (buffer, '^');
1183 g_string_append_c (buffer, c + 'a' - 1);
1184 }
1185 else if (c == '^')
1186 g_string_append (buffer, "^^");
1187 else
1188 g_string_append_c (buffer, (char) c);
1189 }
1190
1191
1192
1193 static void
1194 k_dispose (key_def *k)
1195 {
1196 if (k != NULL)
1197 {
1198 k_dispose (k->child);
1199 k_dispose (k->next);
1200 g_free (k);
1201 }
1202 }
1203
1204
1205
1206 static int
1207 key_code_comparator_by_name (const void *p1, const void *p2)
1208 {
1209 const key_code_name_t *n1 = *(const key_code_name_t * const *) p1;
1210 const key_code_name_t *n2 = *(const key_code_name_t * const *) p2;
1211
1212 return g_ascii_strcasecmp (n1->name, n2->name);
1213 }
1214
1215
1216
1217 static int
1218 key_code_comparator_by_code (const void *p1, const void *p2)
1219 {
1220 const key_code_name_t *n1 = *(const key_code_name_t * const *) p1;
1221 const key_code_name_t *n2 = *(const key_code_name_t * const *) p2;
1222
1223 return n1->code - n2->code;
1224 }
1225
1226
1227
1228 static inline void
1229 sort_key_conv_tab (enum KeySortType type_sort)
1230 {
1231 if (has_been_sorted != type_sort)
1232 {
1233 size_t i;
1234
1235 for (i = 0; i < key_conv_tab_size; i++)
1236 key_conv_tab_sorted[i] = &key_name_conv_tab[i];
1237
1238 if (type_sort == KEY_SORTBYNAME)
1239 qsort (key_conv_tab_sorted, key_conv_tab_size, sizeof (key_conv_tab_sorted[0]),
1240 &key_code_comparator_by_name);
1241 else if (type_sort == KEY_SORTBYCODE)
1242 qsort (key_conv_tab_sorted, key_conv_tab_size, sizeof (key_conv_tab_sorted[0]),
1243 &key_code_comparator_by_code);
1244
1245 has_been_sorted = type_sort;
1246 }
1247 }
1248
1249
1250
1251 static int
1252 lookup_keyname (const char *name, int *idx)
1253 {
1254 if (name[0] != '\0')
1255 {
1256 const key_code_name_t key = { 0, name, NULL, NULL };
1257 const key_code_name_t *keyp = &key;
1258 const key_code_name_t **res;
1259
1260 if (name[1] == '\0')
1261 {
1262 *idx = -1;
1263 return (int) name[0];
1264 }
1265
1266 sort_key_conv_tab (KEY_SORTBYNAME);
1267
1268 res = bsearch (&keyp, key_conv_tab_sorted, key_conv_tab_size,
1269 sizeof (key_conv_tab_sorted[0]), key_code_comparator_by_name);
1270
1271 if (res != NULL)
1272 {
1273 *idx = (int) (res - key_conv_tab_sorted);
1274 return (*res)->code;
1275 }
1276 }
1277
1278 *idx = -1;
1279 return 0;
1280 }
1281
1282
1283
1284 static gboolean
1285 lookup_keycode (const long code, int *idx)
1286 {
1287 if (code != 0)
1288 {
1289 const key_code_name_t key = { code, NULL, NULL, NULL };
1290 const key_code_name_t *keyp = &key;
1291 const key_code_name_t **res;
1292
1293 sort_key_conv_tab (KEY_SORTBYCODE);
1294
1295 res = bsearch (&keyp, key_conv_tab_sorted, key_conv_tab_size,
1296 sizeof (key_conv_tab_sorted[0]), key_code_comparator_by_code);
1297
1298 if (res != NULL)
1299 {
1300 *idx = (int) (res - key_conv_tab_sorted);
1301 return TRUE;
1302 }
1303 }
1304
1305 *idx = -1;
1306 return FALSE;
1307 }
1308
1309
1310
1311
1312
1313
1314
1315 void
1316 init_key (void)
1317 {
1318 const char *term;
1319
1320 term = getenv ("TERM");
1321
1322
1323
1324 define_sequences (mc_default_keys);
1325
1326
1327 if (mc_global.tty.xterm_flag
1328 || (term != NULL
1329 && (strncmp (term, "iris-ansi", 9) == 0
1330 || strncmp (term, "xterm", 5) == 0
1331 || strncmp (term, "rxvt", 4) == 0 || strncmp (term, "screen", 6) == 0)))
1332 define_sequences (xterm_key_defines);
1333
1334
1335 load_xtra_key_defines ();
1336
1337 #ifdef __QNX__
1338 if ((term != NULL) && (strncmp (term, "qnx", 3) == 0))
1339 {
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353 use_8th_bit_as_meta = FALSE;
1354 }
1355 #endif
1356
1357 #ifdef HAVE_TEXTMODE_X11_SUPPORT
1358 init_key_x11 ();
1359 #endif
1360
1361
1362
1363 if (term != NULL && (strncmp (term, "qansi-m", 7) == 0))
1364 define_sequences (qansi_key_defines);
1365 }
1366
1367
1368
1369
1370
1371
1372 void
1373 init_key_input_fd (void)
1374 {
1375 #ifdef HAVE_SLANG
1376 input_fd = SLang_TT_Read_FD;
1377 #endif
1378 }
1379
1380
1381
1382 void
1383 done_key (void)
1384 {
1385 k_dispose (keys);
1386 g_slist_free_full (select_list, g_free);
1387
1388 #ifdef HAVE_TEXTMODE_X11_SUPPORT
1389 if (x11_display)
1390 mc_XCloseDisplay (x11_display);
1391 #endif
1392 }
1393
1394
1395
1396 void
1397 add_select_channel (int fd, select_fn callback, void *info)
1398 {
1399 select_t *new;
1400
1401 new = g_new (select_t, 1);
1402 new->fd = fd;
1403 new->callback = callback;
1404 new->info = info;
1405
1406 select_list = g_slist_prepend (select_list, new);
1407 }
1408
1409
1410
1411 void
1412 delete_select_channel (int fd)
1413 {
1414 GSList *p;
1415
1416 p = g_slist_find_custom (select_list, GINT_TO_POINTER (fd), select_cmp_by_fd);
1417 if (p != NULL)
1418 select_list = g_slist_delete_link (select_list, p);
1419 }
1420
1421
1422
1423 void
1424 channels_up (void)
1425 {
1426 if (disabled_channels == 0)
1427 fputs ("Error: channels_up called with disabled_channels = 0\n", stderr);
1428 disabled_channels--;
1429 }
1430
1431
1432
1433 void
1434 channels_down (void)
1435 {
1436 disabled_channels++;
1437 }
1438
1439
1440
1441
1442
1443
1444 long
1445 tty_keyname_to_keycode (const char *name, char **label)
1446 {
1447 char **lc_keys, **p;
1448 char *cname;
1449 int k = -1;
1450 int key = 0;
1451 int lc_index = -1;
1452
1453 int use_meta = -1;
1454 int use_ctrl = -1;
1455 int use_shift = -1;
1456
1457 if (name == NULL)
1458 return 0;
1459
1460 cname = g_strstrip (g_strdup (name));
1461 lc_keys = g_strsplit_set (cname, "-+ ", -1);
1462 g_free (cname);
1463
1464 for (p = lc_keys; p != NULL && *p != NULL; p++)
1465 {
1466 if ((*p)[0] != '\0')
1467 {
1468 int idx;
1469
1470 key = lookup_keyname (g_strstrip (*p), &idx);
1471
1472 if (key == KEY_M_ALT)
1473 use_meta = idx;
1474 else if (key == KEY_M_CTRL)
1475 use_ctrl = idx;
1476 else if (key == KEY_M_SHIFT)
1477 use_shift = idx;
1478 else
1479 {
1480 k = key;
1481 lc_index = idx;
1482 break;
1483 }
1484 }
1485 }
1486
1487 g_strfreev (lc_keys);
1488
1489
1490 if (k <= 0)
1491 return 0;
1492
1493 if (label != NULL)
1494 {
1495 GString *s;
1496
1497 s = g_string_new ("");
1498
1499 if (use_meta != -1)
1500 {
1501 g_string_append (s, key_conv_tab_sorted[use_meta]->shortcut);
1502 g_string_append_c (s, '-');
1503 }
1504 if (use_ctrl != -1)
1505 {
1506 g_string_append (s, key_conv_tab_sorted[use_ctrl]->shortcut);
1507 g_string_append_c (s, '-');
1508 }
1509 if (use_shift != -1)
1510 {
1511 if (k < 127)
1512 g_string_append_c (s, (gchar) g_ascii_toupper ((gchar) k));
1513 else
1514 {
1515 g_string_append (s, key_conv_tab_sorted[use_shift]->shortcut);
1516 g_string_append_c (s, '-');
1517 g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut);
1518 }
1519 }
1520 else if (k < 128)
1521 {
1522 if ((k >= 'A') || (lc_index < 0) || (key_conv_tab_sorted[lc_index]->shortcut == NULL))
1523 g_string_append_c (s, (gchar) g_ascii_tolower ((gchar) k));
1524 else
1525 g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut);
1526 }
1527 else if ((lc_index != -1) && (key_conv_tab_sorted[lc_index]->shortcut != NULL))
1528 g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut);
1529 else
1530 g_string_append_c (s, (gchar) g_ascii_tolower ((gchar) key));
1531
1532 *label = g_string_free (s, FALSE);
1533 }
1534
1535 if (use_shift != -1)
1536 {
1537 if (k < 127 && k > 31)
1538 k = g_ascii_toupper ((gchar) k);
1539 else
1540 k |= KEY_M_SHIFT;
1541 }
1542
1543 if (use_ctrl != -1)
1544 {
1545 if (k < 256)
1546 k = XCTRL (k);
1547 else
1548 k |= KEY_M_CTRL;
1549 }
1550
1551 if (use_meta != -1)
1552 k = ALT (k);
1553
1554 return (long) k;
1555 }
1556
1557
1558
1559 char *
1560 tty_keycode_to_keyname (const int keycode)
1561 {
1562
1563 unsigned int k = keycode & ~KEY_M_MASK;
1564
1565 unsigned int mod = keycode & KEY_M_MASK;
1566
1567 int key_idx = -1;
1568
1569 GString *s;
1570 int idx;
1571
1572 s = g_string_sized_new (8);
1573
1574 if (lookup_keycode (k, &key_idx) || (k > 0 && k < 256))
1575 {
1576 if ((mod & KEY_M_ALT) != 0 && lookup_keycode (KEY_M_ALT, &idx))
1577 {
1578 g_string_append (s, key_conv_tab_sorted[idx]->name);
1579 g_string_append_c (s, '-');
1580 }
1581
1582 if ((mod & KEY_M_CTRL) != 0)
1583 {
1584
1585 if (k < 32)
1586 k += 64;
1587
1588 if (lookup_keycode (KEY_M_CTRL, &idx))
1589 {
1590 g_string_append (s, key_conv_tab_sorted[idx]->name);
1591 g_string_append_c (s, '-');
1592 }
1593 }
1594
1595 if ((mod & KEY_M_SHIFT) != 0)
1596 {
1597 if (lookup_keycode (KEY_M_ALT, &idx))
1598 {
1599 if (k < 127)
1600 g_string_append_c (s, (gchar) g_ascii_toupper ((gchar) k));
1601 else
1602 {
1603 g_string_append (s, key_conv_tab_sorted[idx]->name);
1604 g_string_append_c (s, '-');
1605 g_string_append (s, key_conv_tab_sorted[key_idx]->name);
1606 }
1607 }
1608 }
1609 else if (k < 128)
1610 {
1611 if ((k >= 'A') || (key_idx < 0) || (key_conv_tab_sorted[key_idx]->name == NULL))
1612 g_string_append_c (s, (gchar) k);
1613 else
1614 g_string_append (s, key_conv_tab_sorted[key_idx]->name);
1615 }
1616 else if ((key_idx != -1) && (key_conv_tab_sorted[key_idx]->name != NULL))
1617 g_string_append (s, key_conv_tab_sorted[key_idx]->name);
1618 else
1619 g_string_append_c (s, (gchar) keycode);
1620 }
1621
1622 return g_string_free (s, s->len == 0);
1623 }
1624
1625
1626
1627
1628
1629
1630
1631 gboolean
1632 define_sequence (int code, const char *seq, int action)
1633 {
1634 key_def *base;
1635
1636 if (strlen (seq) > SEQ_BUFFER_LEN - 1)
1637 return FALSE;
1638
1639 for (base = keys; (base != NULL) && (*seq != '\0');)
1640 if (*seq == base->ch)
1641 {
1642 if (base->child == NULL)
1643 {
1644 if (*(seq + 1) != '\0')
1645 base->child = create_sequence (seq + 1, code, action);
1646 else
1647 {
1648
1649 base->code = code;
1650 base->action = action;
1651 }
1652 return TRUE;
1653 }
1654
1655 base = base->child;
1656 seq++;
1657 }
1658 else
1659 {
1660 if (base->next != NULL)
1661 base = base->next;
1662 else
1663 {
1664 base->next = create_sequence (seq, code, action);
1665 return TRUE;
1666 }
1667 }
1668
1669 if (*seq == '\0')
1670 {
1671
1672 return FALSE;
1673 }
1674
1675 keys = create_sequence (seq, code, action);
1676 return TRUE;
1677 }
1678
1679
1680
1681
1682
1683
1684 gboolean
1685 is_idle (void)
1686 {
1687 int nfd;
1688 fd_set select_set;
1689 struct timeval time_out;
1690
1691 FD_ZERO (&select_set);
1692 FD_SET (input_fd, &select_set);
1693 nfd = MAX (0, input_fd) + 1;
1694 time_out.tv_sec = 0;
1695 time_out.tv_usec = 0;
1696 #ifdef HAVE_LIBGPM
1697 if (mouse_enabled && use_mouse_p == MOUSE_GPM)
1698 {
1699 if (gpm_fd >= 0)
1700 {
1701 FD_SET (gpm_fd, &select_set);
1702 nfd = MAX (nfd, gpm_fd + 1);
1703 }
1704 else
1705 {
1706 if (mouse_fd >= 0)
1707 {
1708 if (FD_ISSET (mouse_fd, &select_set))
1709 FD_CLR (mouse_fd, &select_set);
1710 mouse_fd = gpm_fd;
1711 }
1712
1713 if (gpm_fd == -1)
1714 {
1715 mouse_enabled = FALSE;
1716 use_mouse_p = MOUSE_NONE;
1717 }
1718 }
1719 }
1720 #endif
1721 return (select (nfd, &select_set, 0, 0, &time_out) <= 0);
1722 }
1723
1724
1725
1726 int
1727 get_key_code (int no_delay)
1728 {
1729 int c;
1730 static key_def *this = NULL, *parent;
1731 static gint64 esc_time = -1;
1732 static int lastnodelay = -1;
1733
1734 if (no_delay != lastnodelay)
1735 {
1736 this = NULL;
1737 lastnodelay = no_delay;
1738 }
1739
1740 pend_send:
1741 if (pending_keys != NULL)
1742 {
1743 gboolean bad_seq;
1744
1745 c = *pending_keys++;
1746 while (c == ESC_CHAR)
1747 c = ALT (*pending_keys++);
1748
1749 bad_seq = (*pending_keys != ESC_CHAR && *pending_keys != '\0');
1750 if (*pending_keys == '\0' || bad_seq)
1751 pending_keys = seq_append = NULL;
1752
1753 if (bad_seq)
1754 {
1755
1756
1757
1758
1759
1760
1761 int paranoia = 20;
1762
1763 while (getch_with_timeout (old_esc_mode_timeout) >= 0 && --paranoia != 0)
1764 ;
1765 }
1766 else
1767 {
1768 if (c > 127 && c < 256 && use_8th_bit_as_meta)
1769 c = ALT (c & 0x7f);
1770
1771 goto done;
1772 }
1773 }
1774
1775 nodelay_try_again:
1776 if (no_delay != 0)
1777 tty_nodelay (TRUE);
1778
1779 c = tty_lowlevel_getch ();
1780 #if (defined(USE_NCURSES) || defined(USE_NCURSESW)) && defined(KEY_RESIZE)
1781 if (c == KEY_RESIZE)
1782 goto nodelay_try_again;
1783 #endif
1784
1785 if (no_delay != 0)
1786 {
1787 tty_nodelay (FALSE);
1788 if (c == -1)
1789 {
1790 if (this == NULL || parent == NULL || parent->action != MCKEY_ESCAPE || !old_esc_mode ||
1791 esc_time == -1 || g_get_monotonic_time () < esc_time + old_esc_mode_timeout)
1792 return -1;
1793
1794 this = NULL;
1795 pending_keys = seq_append = NULL;
1796 return ESC_CHAR;
1797 }
1798 }
1799 else if (c == -1)
1800 {
1801
1802
1803
1804 if (seq_append == NULL)
1805 {
1806 this = NULL;
1807 return -1;
1808 }
1809
1810 pending_keys = seq_buffer;
1811 goto pend_send;
1812 }
1813
1814
1815 if (no_delay == 0 || this == NULL)
1816 {
1817 this = keys;
1818 parent = NULL;
1819
1820 if (c > 127 && c < 256 && use_8th_bit_as_meta)
1821 {
1822 c &= 0x7f;
1823
1824
1825 parent = keys;
1826 this = keys->child;
1827 }
1828 }
1829
1830 while (this != NULL)
1831 {
1832 if (c == this->ch)
1833 {
1834 if (this->child == NULL)
1835 {
1836
1837 pending_keys = seq_append = NULL;
1838 c = this->code;
1839 goto done;
1840 }
1841
1842
1843 if (!push_char (c))
1844 {
1845 pending_keys = seq_buffer;
1846 goto pend_send;
1847 }
1848
1849 parent = this;
1850 this = this->child;
1851 if (parent->action == MCKEY_ESCAPE && old_esc_mode)
1852 {
1853 if (no_delay != 0)
1854 {
1855 esc_time = g_get_monotonic_time ();
1856 goto nodelay_try_again;
1857 }
1858
1859 esc_time = -1;
1860 c = getch_with_timeout (old_esc_mode_timeout);
1861 if (c != -1)
1862 continue;
1863
1864 pending_keys = seq_append = NULL;
1865 this = NULL;
1866 return ESC_CHAR;
1867 }
1868
1869 if (no_delay != 0)
1870 goto nodelay_try_again;
1871 c = tty_lowlevel_getch ();
1872 continue;
1873 }
1874
1875
1876 if (this->next != NULL)
1877 {
1878 this = this->next;
1879 continue;
1880 }
1881
1882
1883 if ((parent != NULL) && (parent->action == MCKEY_ESCAPE))
1884 {
1885
1886 if (g_ascii_isdigit (c))
1887 c = KEY_F (c - '0');
1888 else if (c == ' ')
1889 c = ESC_CHAR;
1890 else
1891 c = ALT (c);
1892
1893 pending_keys = seq_append = NULL;
1894 goto done;
1895 }
1896
1897
1898 push_char (c);
1899 pending_keys = seq_buffer;
1900 goto pend_send;
1901 }
1902
1903 done:
1904 this = NULL;
1905 return correct_key_code (c);
1906 }
1907
1908
1909
1910
1911
1912
1913
1914 int
1915 tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block)
1916 {
1917 int c;
1918 int flag = 0;
1919 #ifdef HAVE_LIBGPM
1920 static struct Gpm_Event ev;
1921 #endif
1922 struct timeval time_out;
1923 struct timeval *time_addr = NULL;
1924 static int dirty = 3;
1925
1926 if ((dirty == 3) || is_idle ())
1927 {
1928 mc_refresh ();
1929 dirty = 1;
1930 }
1931 else
1932 dirty++;
1933
1934 vfs_timeout_handler ();
1935
1936
1937
1938
1939
1940 if (event->x > 0)
1941 {
1942 show_mouse_pointer (event->x, event->y);
1943 if (!redo_event)
1944 event->x = -1;
1945 }
1946
1947
1948 while (pending_keys == NULL)
1949 {
1950 int nfd;
1951 fd_set select_set;
1952
1953 FD_ZERO (&select_set);
1954 FD_SET (input_fd, &select_set);
1955 nfd = MAX (add_selects (&select_set), MAX (0, input_fd)) + 1;
1956
1957 #ifdef HAVE_LIBGPM
1958 if (mouse_enabled && (use_mouse_p == MOUSE_GPM))
1959 {
1960 if (gpm_fd >= 0)
1961 {
1962 FD_SET (gpm_fd, &select_set);
1963 nfd = MAX (nfd, gpm_fd + 1);
1964 }
1965 else
1966 {
1967 if (mouse_fd >= 0)
1968 {
1969 if (FD_ISSET (mouse_fd, &select_set))
1970 FD_CLR (mouse_fd, &select_set);
1971 mouse_fd = gpm_fd;
1972 }
1973
1974 if (gpm_fd == -1)
1975 {
1976 mouse_enabled = FALSE;
1977 use_mouse_p = MOUSE_NONE;
1978 }
1979 break;
1980 }
1981 }
1982 #endif
1983
1984 if (redo_event)
1985 {
1986 time_out.tv_usec = mou_auto_repeat * MC_USEC_PER_MSEC;
1987 time_out.tv_sec = 0;
1988
1989 time_addr = &time_out;
1990 }
1991 else
1992 {
1993 int seconds;
1994
1995 seconds = vfs_timeouts ();
1996 time_addr = NULL;
1997
1998 if (seconds != 0)
1999 {
2000
2001
2002
2003
2004
2005 time_out.tv_sec = seconds;
2006 time_out.tv_usec = 0;
2007 time_addr = &time_out;
2008 }
2009 }
2010
2011 if (!block || tty_got_winch ())
2012 {
2013 time_addr = &time_out;
2014 time_out.tv_sec = 0;
2015 time_out.tv_usec = 0;
2016 }
2017
2018 tty_enable_interrupt_key ();
2019 flag = select (nfd, &select_set, NULL, NULL, time_addr);
2020 tty_disable_interrupt_key ();
2021
2022
2023
2024
2025
2026
2027 if (flag == 0)
2028 {
2029 if (redo_event)
2030 return EV_MOUSE;
2031 if (!block || tty_got_winch ())
2032 return EV_NONE;
2033 vfs_timeout_handler ();
2034 }
2035 if (flag == -1 && errno == EINTR)
2036 return EV_NONE;
2037
2038 check_selects (&select_set);
2039
2040 if (FD_ISSET (input_fd, &select_set))
2041 break;
2042
2043 #ifdef HAVE_LIBGPM
2044 if (mouse_enabled && use_mouse_p == MOUSE_GPM)
2045 {
2046 if (gpm_fd >= 0)
2047 {
2048 if (FD_ISSET (gpm_fd, &select_set))
2049 {
2050 int status;
2051
2052 status = Gpm_GetEvent (&ev);
2053 if (status == 1)
2054 {
2055 Gpm_FitEvent (&ev);
2056 *event = ev;
2057 return EV_MOUSE;
2058 }
2059 if (status <= 0)
2060 {
2061 if (mouse_fd >= 0 && FD_ISSET (mouse_fd, &select_set))
2062 FD_CLR (mouse_fd, &select_set);
2063
2064 disable_mouse ();
2065 return EV_NONE;
2066 }
2067 }
2068 }
2069 else
2070 {
2071 if (mouse_fd >= 0)
2072 {
2073 if (FD_ISSET (mouse_fd, &select_set))
2074 FD_CLR (mouse_fd, &select_set);
2075 mouse_fd = gpm_fd;
2076 }
2077
2078 if (gpm_fd == -1)
2079 {
2080 mouse_enabled = FALSE;
2081 use_mouse_p = MOUSE_NONE;
2082 }
2083 break;
2084 }
2085 }
2086 #endif
2087 }
2088
2089 #ifndef HAVE_SLANG
2090 flag = is_wintouched (stdscr);
2091 untouchwin (stdscr);
2092 #endif
2093 c = block ? getch_with_delay () : get_key_code (1);
2094
2095 #ifndef HAVE_SLANG
2096 if (flag > 0)
2097 tty_touch_screen ();
2098 #endif
2099
2100 if (mouse_enabled && (c == MCKEY_MOUSE
2101 #ifdef KEY_MOUSE
2102 || c == KEY_MOUSE
2103 #endif
2104 || c == MCKEY_EXTENDED_MOUSE))
2105 {
2106
2107 gboolean extended = c == MCKEY_EXTENDED_MOUSE;
2108
2109 #ifdef KEY_MOUSE
2110 extended = extended || (c == KEY_MOUSE && xmouse_seq == NULL
2111 && xmouse_extended_seq != NULL);
2112 #endif
2113
2114 xmouse_get_event (event, extended);
2115 c = (event->type != 0) ? EV_MOUSE : EV_NONE;
2116 }
2117 else if (c == MCKEY_BRACKETED_PASTING_START)
2118 {
2119 bracketed_pasting_in_progress = TRUE;
2120 c = EV_NONE;
2121 }
2122 else if (c == MCKEY_BRACKETED_PASTING_END)
2123 {
2124 bracketed_pasting_in_progress = FALSE;
2125 c = EV_NONE;
2126 }
2127
2128 return c;
2129 }
2130
2131
2132
2133
2134 int
2135 tty_getch (void)
2136 {
2137 Gpm_Event ev;
2138 int key;
2139
2140 ev.x = -1;
2141 while ((key = tty_get_event (&ev, FALSE, TRUE)) == EV_NONE)
2142 ;
2143 return key;
2144 }
2145
2146
2147
2148 char *
2149 learn_key (void)
2150 {
2151
2152 #define LEARN_TIMEOUT 200
2153
2154 fd_set Read_FD_Set;
2155 gint64 end_time;
2156 int c;
2157 GString *buffer;
2158
2159 buffer = g_string_sized_new (16);
2160
2161 tty_keypad (FALSE);
2162 c = tty_lowlevel_getch ();
2163 while (c == -1)
2164 c = tty_lowlevel_getch ();
2165 learn_store_key (buffer, c);
2166
2167 end_time = g_get_monotonic_time () + LEARN_TIMEOUT * MC_USEC_PER_MSEC;
2168
2169 tty_nodelay (TRUE);
2170 while (TRUE)
2171 {
2172 while ((c = tty_lowlevel_getch ()) == -1)
2173 {
2174 gint64 time_out;
2175 struct timeval tv;
2176
2177 time_out = end_time - g_get_monotonic_time ();
2178 if (time_out <= 0)
2179 break;
2180
2181 tv.tv_sec = time_out / G_USEC_PER_SEC;
2182 tv.tv_usec = time_out % G_USEC_PER_SEC;
2183 FD_ZERO (&Read_FD_Set);
2184 FD_SET (input_fd, &Read_FD_Set);
2185 select (input_fd + 1, &Read_FD_Set, NULL, NULL, &tv);
2186 }
2187 if (c == -1)
2188 break;
2189 learn_store_key (buffer, c);
2190 }
2191 tty_keypad (TRUE);
2192 tty_nodelay (FALSE);
2193
2194 return g_string_free (buffer, buffer->len == 0);
2195 #undef LEARN_TIMEOUT
2196 }
2197
2198
2199
2200
2201
2202
2203 void
2204 numeric_keypad_mode (void)
2205 {
2206 if (mc_global.tty.console_flag != '\0' || mc_global.tty.xterm_flag)
2207 {
2208 fputs (ESC_STR ">", stdout);
2209 fflush (stdout);
2210 }
2211 }
2212
2213
2214
2215 void
2216 application_keypad_mode (void)
2217 {
2218 if (mc_global.tty.console_flag != '\0' || mc_global.tty.xterm_flag)
2219 {
2220 fputs (ESC_STR "=", stdout);
2221 fflush (stdout);
2222 }
2223 }
2224
2225
2226
2227 void
2228 enable_bracketed_paste (void)
2229 {
2230 printf (ESC_STR "[?2004h");
2231 fflush (stdout);
2232 }
2233
2234
2235
2236 void
2237 disable_bracketed_paste (void)
2238 {
2239 printf (ESC_STR "[?2004l");
2240 fflush (stdout);
2241 bracketed_pasting_in_progress = FALSE;
2242 }
2243
2244