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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
#include "libbb.h"
int tcsetattr(int fd UNUSED_PARAM, int mode UNUSED_PARAM, const struct termios *t UNUSED_PARAM)
{
return -1;
}
int tcgetattr(int fd UNUSED_PARAM, struct termios *t UNUSED_PARAM)
{
return -1;
}
int64_t FAST_FUNC read_key(int fd, char *buf, int timeout)
{
HANDLE cin = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD record;
DWORD nevent_out, mode;
int ret = -1;
if (fd != 0)
bb_error_msg_and_die("read_key only works on stdin");
if (cin == INVALID_HANDLE_VALUE)
return -1;
GetConsoleMode(cin, &mode);
SetConsoleMode(cin, 0);
if (timeout > 0) {
if (WaitForSingleObject(cin, timeout) != WAIT_OBJECT_0)
goto done;
}
while (1) {
if (!ReadConsoleInput(cin, &record, 1, &nevent_out))
goto done;
if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown)
continue;
if (!record.Event.KeyEvent.uChar.AsciiChar) {
DWORD state = record.Event.KeyEvent.dwControlKeyState;
if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED) &&
(record.Event.KeyEvent.wVirtualKeyCode >= 'A' &&
record.Event.KeyEvent.wVirtualKeyCode <= 'Z'))
return record.Event.KeyEvent.wVirtualKeyCode & ~0x40;
switch (record.Event.KeyEvent.wVirtualKeyCode) {
case VK_DELETE: return KEYCODE_DELETE;
case VK_INSERT: return KEYCODE_INSERT;
case VK_UP: return KEYCODE_UP;
case VK_DOWN: return KEYCODE_DOWN;
case VK_RIGHT:
if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
return KEYCODE_CTRL_RIGHT;
return KEYCODE_RIGHT;
case VK_LEFT:
if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
return KEYCODE_CTRL_LEFT;
return KEYCODE_LEFT;
case VK_HOME: return KEYCODE_HOME;
case VK_END: return KEYCODE_END;
case VK_PRIOR: return KEYCODE_PAGEUP;
case VK_NEXT: return KEYCODE_PAGEDOWN;
case VK_CAPITAL:
case VK_SHIFT:
case VK_CONTROL:
case VK_MENU:
break;
}
continue;
}
ret = record.Event.KeyEvent.uChar.AsciiChar;
break;
}
done:
SetConsoleMode(cin, mode);
return ret;
}
|