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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#include "libbb.h"
static struct termios dummy = {
0, /* c_iflag */
0, /* c_oflag */
0, /* c_cflag */
0, /* c_lflag */
'\0', /* c_line */
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", /* c_cc[NCCS] */
B9600, /* c_ispeed */
B9600 /* c_ospeed */
};
int tcsetattr(int fd UNUSED_PARAM, int mode UNUSED_PARAM, const struct termios *t)
{
dummy = *t;
return 0;
}
int tcgetattr(int fd UNUSED_PARAM, struct termios *t)
{
*t = dummy;
return 0;
}
int64_t FAST_FUNC read_key(int fd, char *buf UNUSED_PARAM, int timeout)
{
HANDLE cin = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD record;
DWORD nevent_out, mode;
int ret = -1;
char *s;
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')) {
ret = record.Event.KeyEvent.wVirtualKeyCode & ~0x40;
break;
}
switch (record.Event.KeyEvent.wVirtualKeyCode) {
case VK_DELETE: ret = KEYCODE_DELETE; goto done;
case VK_INSERT: ret = KEYCODE_INSERT; goto done;
case VK_UP: ret = KEYCODE_UP; goto done;
case VK_DOWN: ret = KEYCODE_DOWN; goto done;
case VK_RIGHT:
if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED)) {
ret = KEYCODE_CTRL_RIGHT;
goto done;
}
ret = KEYCODE_RIGHT;
goto done;
case VK_LEFT:
if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED)) {
ret = KEYCODE_CTRL_LEFT;
goto done;
}
ret = KEYCODE_LEFT;
goto done;
case VK_HOME: ret = KEYCODE_HOME; goto done;
case VK_END: ret = KEYCODE_END; goto done;
case VK_PRIOR: ret = KEYCODE_PAGEUP; goto done;
case VK_NEXT: ret = KEYCODE_PAGEDOWN; goto done;
}
continue;
}
if ( (record.Event.KeyEvent.uChar.AsciiChar & 0x80) == 0x80 ) {
s = &record.Event.KeyEvent.uChar.AsciiChar;
OemToCharBuff(s, s, 1);
}
ret = record.Event.KeyEvent.uChar.AsciiChar;
break;
}
done:
SetConsoleMode(cin, mode);
return ret;
}
speed_t cfgetispeed(const struct termios *termios_p)
{
return termios_p->c_ispeed;
}
speed_t cfgetospeed(const struct termios *termios_p)
{
return termios_p->c_ospeed;
}
int cfsetispeed(struct termios *termios_p, speed_t speed)
{
termios_p->c_ispeed = speed;
return 0;
}
int cfsetospeed(struct termios *termios_p, speed_t speed)
{
termios_p->c_ospeed = speed;
return 0;
}
|