From 5531e51fe26e4c6bbd34dbaa98b12564f8a7f295 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 16:32:36 +1000 Subject: win32: winansi: implement \033[J --- win32/winansi.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/win32/winansi.c b/win32/winansi.c index e2e7010fb..51bfad67c 100644 --- a/win32/winansi.c +++ b/win32/winansi.c @@ -91,6 +91,24 @@ static void erase_in_line(void) NULL); } +static void erase_till_end_of_screen(void) +{ + CONSOLE_SCREEN_BUFFER_INFO sbi; + COORD pos; + + if (!console) + return; + + GetConsoleScreenBufferInfo(console, &sbi); + FillConsoleOutputCharacterA(console, ' ', + sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition, + NULL); + + pos.X = 0; + for (pos.Y = sbi.dwCursorPosition.Y+1; pos.Y < sbi.dwSize.Y; pos.Y++) + FillConsoleOutputCharacterA(console, ' ', sbi.dwSize.X, + pos, NULL); +} static const char *set_attr(const char *str) { @@ -230,6 +248,9 @@ static const char *set_attr(const char *str) set_console_attr(); break; + case 'J': + erase_till_end_of_screen(); + break; case 'K': erase_in_line(); break; -- cgit v1.2.3-55-g6feb From 79fc61359a8f9a9563627e9ad8e5938c3ffee4ca Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 15:37:12 +1000 Subject: win32: read_key: reset console state after reading --- win32/termios.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/win32/termios.c b/win32/termios.c index 6d85ff98e..1bd3cbd5b 100644 --- a/win32/termios.c +++ b/win32/termios.c @@ -12,25 +12,29 @@ int tcgetattr(int fd UNUSED_PARAM, struct termios *t UNUSED_PARAM) int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM) { - static int initialized = 0; HANDLE cin = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD record; - DWORD nevent_out; + 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; - if (!initialized) { - SetConsoleMode(cin, ENABLE_ECHO_INPUT); - initialized = 1; - } + GetConsoleMode(cin, &mode); + SetConsoleMode(cin, 0); while (1) { if (!ReadConsoleInput(cin, &record, 1, &nevent_out)) - return -1; + goto done; if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown) continue; - return record.Event.KeyEvent.uChar.AsciiChar; + if (!record.Event.KeyEvent.uChar.AsciiChar) + continue; + ret = record.Event.KeyEvent.uChar.AsciiChar; + break; } + done: + SetConsoleMode(cin, mode); + return ret; } -- cgit v1.2.3-55-g6feb From fc11f0cef175a7bfd652691d05f3e19147462cb1 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 16:47:04 +1000 Subject: win32: read_key: imap some movement keys to KEYCODE_* --- win32/termios.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/win32/termios.c b/win32/termios.c index 1bd3cbd5b..812f6d5d7 100644 --- a/win32/termios.c +++ b/win32/termios.c @@ -29,8 +29,24 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM) goto done; if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown) continue; - if (!record.Event.KeyEvent.uChar.AsciiChar) + if (!record.Event.KeyEvent.uChar.AsciiChar) { + switch (record.Event.KeyEvent.wVirtualKeyCode) { + case VK_UP: return KEYCODE_UP; + case VK_DOWN: return KEYCODE_DOWN; + case VK_RIGHT: return KEYCODE_RIGHT; + case VK_LEFT: return KEYCODE_LEFT; + case VK_HOME: return KEYCODE_HOME; + case VK_END: return KEYCODE_END; + case VK_CAPITAL: + case VK_SHIFT: + case VK_CONTROL: + case VK_MENU: + break; + default: + return -1; + } continue; + } ret = record.Event.KeyEvent.uChar.AsciiChar; break; } -- cgit v1.2.3-55-g6feb From d527acced45955fa83f0453e2c215b6cc1cad920 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 16:54:54 +1000 Subject: win32: winansi: implement \033[%uD --- win32/winansi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/win32/winansi.c b/win32/winansi.c index 51bfad67c..3e97779cb 100644 --- a/win32/winansi.c +++ b/win32/winansi.c @@ -110,6 +110,18 @@ static void erase_till_end_of_screen(void) pos, NULL); } +static void move_cursor_back(int n) +{ + CONSOLE_SCREEN_BUFFER_INFO sbi; + + if (!console) + return; + + GetConsoleScreenBufferInfo(console, &sbi); + sbi.dwCursorPosition.X -= n; + SetConsoleCursorPosition(console, sbi.dwCursorPosition); +} + static const char *set_attr(const char *str) { const char *func; @@ -248,6 +260,9 @@ static const char *set_attr(const char *str) set_console_attr(); break; + case 'D': + move_cursor_back(strtol(str, (char **)&str, 10)); + break; case 'J': erase_till_end_of_screen(); break; -- cgit v1.2.3-55-g6feb From 62822fc3b2cadf823d4d74be902c76e1af0b904a Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 17:58:57 +1000 Subject: win32: read_key: support Ctrl-{Left,Right} --- win32/termios.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/win32/termios.c b/win32/termios.c index 812f6d5d7..0154bd11f 100644 --- a/win32/termios.c +++ b/win32/termios.c @@ -30,11 +30,18 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM) if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown) continue; if (!record.Event.KeyEvent.uChar.AsciiChar) { + DWORD state = record.Event.KeyEvent.dwControlKeyState; switch (record.Event.KeyEvent.wVirtualKeyCode) { case VK_UP: return KEYCODE_UP; case VK_DOWN: return KEYCODE_DOWN; - case VK_RIGHT: return KEYCODE_RIGHT; - case VK_LEFT: return KEYCODE_LEFT; + 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_CAPITAL: -- cgit v1.2.3-55-g6feb From a335db7cd1acbe54c0bfe5ec02457d430e866f04 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 17:59:09 +1000 Subject: win32: read_key: support Delete --- win32/termios.c | 1 + 1 file changed, 1 insertion(+) diff --git a/win32/termios.c b/win32/termios.c index 0154bd11f..177a7bdbe 100644 --- a/win32/termios.c +++ b/win32/termios.c @@ -32,6 +32,7 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM) if (!record.Event.KeyEvent.uChar.AsciiChar) { DWORD state = record.Event.KeyEvent.dwControlKeyState; switch (record.Event.KeyEvent.wVirtualKeyCode) { + case VK_DELETE: return KEYCODE_DELETE; case VK_UP: return KEYCODE_UP; case VK_DOWN: return KEYCODE_DOWN; case VK_RIGHT: -- cgit v1.2.3-55-g6feb From 1a6d1cbfb455e71208017039d41fe7e62a69cda2 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 18:00:35 +1000 Subject: win32: read_key: do not return -1 on unknown key -1 to lineedit means error... when tty is destroyed... it would terminate ash for some reasone --- win32/termios.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/win32/termios.c b/win32/termios.c index 177a7bdbe..283e88b3a 100644 --- a/win32/termios.c +++ b/win32/termios.c @@ -50,8 +50,6 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM) case VK_CONTROL: case VK_MENU: break; - default: - return -1; } continue; } -- cgit v1.2.3-55-g6feb From 3bc78ad7df40a9d2787d7dd7f79a5d3257d619e4 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 18:07:31 +1000 Subject: win32: winansi: implement \033[H (no param) --- win32/winansi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/win32/winansi.c b/win32/winansi.c index 3e97779cb..568f925aa 100644 --- a/win32/winansi.c +++ b/win32/winansi.c @@ -122,6 +122,18 @@ static void move_cursor_back(int n) SetConsoleCursorPosition(console, sbi.dwCursorPosition); } +static void move_cursor(int x, int y) +{ + COORD pos; + + if (!console) + return; + + pos.X = x; + pos.Y = y; + SetConsoleCursorPosition(console, pos); +} + static const char *set_attr(const char *str) { const char *func; @@ -263,6 +275,10 @@ static const char *set_attr(const char *str) case 'D': move_cursor_back(strtol(str, (char **)&str, 10)); break; + case 'H': + if (!len) + move_cursor(0, 0); + break; case 'J': erase_till_end_of_screen(); break; -- cgit v1.2.3-55-g6feb From b7d776dee51ce10de0f996fd91789488bc659605 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 18:30:49 +1000 Subject: win32: winansi: implement \033[%u;%uH --- win32/winansi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/win32/winansi.c b/win32/winansi.c index 568f925aa..d95bd473b 100644 --- a/win32/winansi.c +++ b/win32/winansi.c @@ -278,6 +278,13 @@ static const char *set_attr(const char *str) case 'H': if (!len) move_cursor(0, 0); + else { + int row = strtol(str, (char **)&str, 10); + if (*str == ';') { + int col = strtol(str+1, (char **)&str, 10); + move_cursor(col, row); + } + } break; case 'J': erase_till_end_of_screen(); -- cgit v1.2.3-55-g6feb From 0231af4e5b38956216a058ebf1e1619ae47dfa14 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Tue, 14 Sep 2010 18:35:45 +1000 Subject: win32: read_key: add Page Up/Down and Insert --- win32/termios.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/win32/termios.c b/win32/termios.c index 283e88b3a..e2dc96361 100644 --- a/win32/termios.c +++ b/win32/termios.c @@ -33,6 +33,7 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM) DWORD state = record.Event.KeyEvent.dwControlKeyState; 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: @@ -45,6 +46,8 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM) 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: -- cgit v1.2.3-55-g6feb