aboutsummaryrefslogtreecommitdiff
path: root/win32/termios.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32/termios.c')
-rw-r--r--win32/termios.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/win32/termios.c b/win32/termios.c
index 97d67eebb..22ac09d27 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -12,19 +12,17 @@ int tcgetattr(int fd UNUSED_PARAM, struct termios *t UNUSED_PARAM)
12 12
13int64_t FAST_FUNC read_key(int fd, char *buf, int timeout) 13int64_t FAST_FUNC read_key(int fd, char *buf, int timeout)
14{ 14{
15 static int initialized = 0;
16 HANDLE cin = GetStdHandle(STD_INPUT_HANDLE); 15 HANDLE cin = GetStdHandle(STD_INPUT_HANDLE);
17 INPUT_RECORD record; 16 INPUT_RECORD record;
18 DWORD nevent_out; 17 DWORD nevent_out, mode;
18 int ret = -1;
19 19
20 if (fd != 0) 20 if (fd != 0)
21 bb_error_msg_and_die("read_key only works on stdin"); 21 bb_error_msg_and_die("read_key only works on stdin");
22 if (cin == INVALID_HANDLE_VALUE) 22 if (cin == INVALID_HANDLE_VALUE)
23 return -1; 23 return -1;
24 if (!initialized) { 24 GetConsoleMode(cin, &mode);
25 SetConsoleMode(cin, ENABLE_ECHO_INPUT); 25 SetConsoleMode(cin, 0);
26 initialized = 1;
27 }
28 26
29 if (timeout > 0) { 27 if (timeout > 0) {
30 if (WaitForSingleObject(cin, timeout) != WAIT_OBJECT_0) 28 if (WaitForSingleObject(cin, timeout) != WAIT_OBJECT_0)
@@ -32,9 +30,40 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout)
32 } 30 }
33 while (1) { 31 while (1) {
34 if (!ReadConsoleInput(cin, &record, 1, &nevent_out)) 32 if (!ReadConsoleInput(cin, &record, 1, &nevent_out))
35 return -1; 33 goto done;
36 if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown) 34 if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown)
37 continue; 35 continue;
38 return record.Event.KeyEvent.uChar.AsciiChar; 36 if (!record.Event.KeyEvent.uChar.AsciiChar) {
37 DWORD state = record.Event.KeyEvent.dwControlKeyState;
38 switch (record.Event.KeyEvent.wVirtualKeyCode) {
39 case VK_DELETE: return KEYCODE_DELETE;
40 case VK_INSERT: return KEYCODE_INSERT;
41 case VK_UP: return KEYCODE_UP;
42 case VK_DOWN: return KEYCODE_DOWN;
43 case VK_RIGHT:
44 if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
45 return KEYCODE_CTRL_RIGHT;
46 return KEYCODE_RIGHT;
47 case VK_LEFT:
48 if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
49 return KEYCODE_CTRL_LEFT;
50 return KEYCODE_LEFT;
51 case VK_HOME: return KEYCODE_HOME;
52 case VK_END: return KEYCODE_END;
53 case VK_PRIOR: return KEYCODE_PAGEUP;
54 case VK_NEXT: return KEYCODE_PAGEDOWN;
55 case VK_CAPITAL:
56 case VK_SHIFT:
57 case VK_CONTROL:
58 case VK_MENU:
59 break;
60 }
61 continue;
62 }
63 ret = record.Event.KeyEvent.uChar.AsciiChar;
64 break;
39 } 65 }
66 done:
67 SetConsoleMode(cin, mode);
68 return ret;
40} 69}