aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-09-14 18:40:56 +1000
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-09-14 18:40:56 +1000
commit982fdd36984502ad7ff320be0192f37998f65c41 (patch)
tree67d1feb5add8b216153caf01299b12d55a443510
parentc2c28bd9eaf568f803136578cadad4d7cdf68f5e (diff)
parent0231af4e5b38956216a058ebf1e1619ae47dfa14 (diff)
downloadbusybox-w32-982fdd36984502ad7ff320be0192f37998f65c41.tar.gz
busybox-w32-982fdd36984502ad7ff320be0192f37998f65c41.tar.bz2
busybox-w32-982fdd36984502ad7ff320be0192f37998f65c41.zip
Merge branch 'lineedit' into vi
-rw-r--r--win32/termios.c45
-rw-r--r--win32/winansi.c59
2 files changed, 96 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}
diff --git a/win32/winansi.c b/win32/winansi.c
index e2e7010fb..d95bd473b 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -91,6 +91,48 @@ static void erase_in_line(void)
91 NULL); 91 NULL);
92} 92}
93 93
94static void erase_till_end_of_screen(void)
95{
96 CONSOLE_SCREEN_BUFFER_INFO sbi;
97 COORD pos;
98
99 if (!console)
100 return;
101
102 GetConsoleScreenBufferInfo(console, &sbi);
103 FillConsoleOutputCharacterA(console, ' ',
104 sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition,
105 NULL);
106
107 pos.X = 0;
108 for (pos.Y = sbi.dwCursorPosition.Y+1; pos.Y < sbi.dwSize.Y; pos.Y++)
109 FillConsoleOutputCharacterA(console, ' ', sbi.dwSize.X,
110 pos, NULL);
111}
112
113static void move_cursor_back(int n)
114{
115 CONSOLE_SCREEN_BUFFER_INFO sbi;
116
117 if (!console)
118 return;
119
120 GetConsoleScreenBufferInfo(console, &sbi);
121 sbi.dwCursorPosition.X -= n;
122 SetConsoleCursorPosition(console, sbi.dwCursorPosition);
123}
124
125static void move_cursor(int x, int y)
126{
127 COORD pos;
128
129 if (!console)
130 return;
131
132 pos.X = x;
133 pos.Y = y;
134 SetConsoleCursorPosition(console, pos);
135}
94 136
95static const char *set_attr(const char *str) 137static const char *set_attr(const char *str)
96{ 138{
@@ -230,6 +272,23 @@ static const char *set_attr(const char *str)
230 272
231 set_console_attr(); 273 set_console_attr();
232 break; 274 break;
275 case 'D':
276 move_cursor_back(strtol(str, (char **)&str, 10));
277 break;
278 case 'H':
279 if (!len)
280 move_cursor(0, 0);
281 else {
282 int row = strtol(str, (char **)&str, 10);
283 if (*str == ';') {
284 int col = strtol(str+1, (char **)&str, 10);
285 move_cursor(col, row);
286 }
287 }
288 break;
289 case 'J':
290 erase_till_end_of_screen();
291 break;
233 case 'K': 292 case 'K':
234 erase_in_line(); 293 erase_in_line();
235 break; 294 break;