From 9e39cb6498d628c1fd8ad81ed72d424ed7a2bd7b Mon Sep 17 00:00:00 2001 From: Takashi Yano via Cygwin-patches Date: Thu, 27 Aug 2020 12:35:03 +0900 Subject: [PATCH] Cygwin: console: Replace WriteConsoleA() with WriteConsoleW(). - To allow sending non-ASCII chars to console, all WriteConsoleA() are replaced by WriteConsoleW(). Addresses: https://cygwin.com/pipermail/cygwin-patches/2020q3/010476.html --- winsup/cygwin/fhandler_console.cc | 89 ++++++++++++++++--------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 52741ce8b6..51b2518d73 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -59,7 +59,7 @@ static struct fhandler_base::rabuf_t con_ra; /* Write pending buffer for ESC sequence handling in xterm compatible mode */ -static unsigned char last_char; +static wchar_t last_char; /* simple helper class to accumulate output in a buffer and send that to the console on request: */ @@ -67,18 +67,20 @@ static class write_pending_buffer { private: static const size_t WPBUF_LEN = 256u; - unsigned char buf[WPBUF_LEN]; + char buf[WPBUF_LEN]; size_t ixput; public: - inline void put (unsigned char x) + inline void put (char x) { if (ixput < WPBUF_LEN) buf[ixput++] = x; } inline void empty () { ixput = 0u; } - inline void send (HANDLE &handle, DWORD *wn = NULL) + inline void send (HANDLE &handle) { - WriteConsoleA (handle, buf, ixput, wn, 0); + wchar_t bufw[WPBUF_LEN]; + DWORD len = sys_mbstowcs (bufw, WPBUF_LEN, buf, ixput); + WriteConsoleW (handle, bufw, len, NULL, 0); } } wpbuf; @@ -291,7 +293,7 @@ fhandler_console::request_xterm_mode_input (bool req) dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT; SetConsoleMode (get_handle (), dwMode); if (con.cursor_key_app_mode) /* Restore DECCKM */ - WriteConsoleA (get_output_handle (), "\033[?1h", 5, NULL, 0); + WriteConsoleW (get_output_handle (), L"\033[?1h", 5, NULL, 0); } } else @@ -1805,6 +1807,9 @@ fhandler_console::write_console (PWCHAR buf, DWORD len, DWORD& done) if (buf[i] >= (unsigned char) '`' && buf[i] <= (unsigned char) '~') buf[i] = __vt100_conv[buf[i] - (unsigned char) '`']; + if (len > 0) + last_char = buf[len-1]; + while (len > 0) { DWORD nbytes = len > MAX_WRITE_CHARS ? MAX_WRITE_CHARS : len; @@ -2013,6 +2018,7 @@ fhandler_console::char_command (char c) { int x, y, n; char buf[40]; + wchar_t bufw[40]; int r, g, b; if (wincap.has_con_24bit_colors () && !con_is_legacy) @@ -2047,9 +2053,9 @@ fhandler_console::char_command (char c) if (wincap.has_con_esc_rep ()) /* Just send the sequence */ wpbuf.send (get_output_handle ()); - else if (last_char && last_char != '\n') + else if (last_char && last_char != L'\n') for (int i = 0; i < con.args[0]; i++) - WriteConsoleA (get_output_handle (), &last_char, 1, 0, 0); + WriteConsoleW (get_output_handle (), &last_char, 1, 0, 0); break; case 'r': /* DECSTBM */ con.scroll_region.Top = con.args[0] ? con.args[0] - 1 : 0; @@ -2070,25 +2076,25 @@ fhandler_console::char_command (char c) { /* Erase scroll down area */ n = con.args[0] ? : 1; - __small_sprintf (buf, "\033[%d;1H\033[J\033[%d;%dH", - srBottom - (n-1) - con.b.srWindow.Top + 1, - y + 1 - con.b.srWindow.Top, x + 1); - WriteConsoleA (get_output_handle (), - buf, strlen (buf), 0, 0); + __small_swprintf (bufw, L"\033[%d;1H\033[J\033[%d;%dH", + srBottom - (n-1) - con.b.srWindow.Top + 1, + y + 1 - con.b.srWindow.Top, x + 1); + WriteConsoleW (get_output_handle (), + bufw, wcslen (bufw), 0, 0); } - __small_sprintf (buf, "\033[%d;%dr", - y + 1 - con.b.srWindow.Top, - srBottom + 1 - con.b.srWindow.Top); - WriteConsoleA (get_output_handle (), buf, strlen (buf), 0, 0); + __small_swprintf (bufw, L"\033[%d;%dr", + y + 1 - con.b.srWindow.Top, + srBottom + 1 - con.b.srWindow.Top); + WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0); wpbuf.put ('T'); wpbuf.send (get_output_handle ()); - __small_sprintf (buf, "\033[%d;%dr", - srTop + 1 - con.b.srWindow.Top, - srBottom + 1 - con.b.srWindow.Top); - WriteConsoleA (get_output_handle (), buf, strlen (buf), 0, 0); - __small_sprintf (buf, "\033[%d;%dH", - y + 1 - con.b.srWindow.Top, x + 1); - WriteConsoleA (get_output_handle (), buf, strlen (buf), 0, 0); + __small_swprintf (bufw, L"\033[%d;%dr", + srTop + 1 - con.b.srWindow.Top, + srBottom + 1 - con.b.srWindow.Top); + WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0); + __small_swprintf (bufw, L"\033[%d;%dH", + y + 1 - con.b.srWindow.Top, x + 1); + WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0); } else { @@ -2104,19 +2110,19 @@ fhandler_console::char_command (char c) cursor_get (&x, &y); if (y < srTop || y > srBottom) break; - __small_sprintf (buf, "\033[%d;%dr", - y + 1 - con.b.srWindow.Top, - srBottom + 1 - con.b.srWindow.Top); - WriteConsoleA (get_output_handle (), buf, strlen (buf), 0, 0); + __small_swprintf (bufw, L"\033[%d;%dr", + y + 1 - con.b.srWindow.Top, + srBottom + 1 - con.b.srWindow.Top); + WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0); wpbuf.put ('S'); wpbuf.send (get_output_handle ()); - __small_sprintf (buf, "\033[%d;%dr", - srTop + 1 - con.b.srWindow.Top, - srBottom + 1 - con.b.srWindow.Top); - WriteConsoleA (get_output_handle (), buf, strlen (buf), 0, 0); - __small_sprintf (buf, "\033[%d;%dH", - y + 1 - con.b.srWindow.Top, x + 1); - WriteConsoleA (get_output_handle (), buf, strlen (buf), 0, 0); + __small_swprintf (bufw, L"\033[%d;%dr", + srTop + 1 - con.b.srWindow.Top, + srBottom + 1 - con.b.srWindow.Top); + WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0); + __small_swprintf (bufw, L"\033[%d;%dH", + y + 1 - con.b.srWindow.Top, x + 1); + WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0); } else { @@ -2850,7 +2856,6 @@ fhandler_console::write_normal (const unsigned char *src, break; default: found += ret; - last_char = *(found - 1); break; } } @@ -3068,12 +3073,12 @@ fhandler_console::write (const void *vsrc, size_t len) && srBottom == con.b.srWindow.Bottom) { /* Erase scroll down area */ - char buf[] = "\033[32768;1H\033[J\033[32768;32768"; - __small_sprintf (buf, "\033[%d;1H\033[J\033[%d;%dH", - srBottom - con.b.srWindow.Top + 1, - y + 1 - con.b.srWindow.Top, x + 1); - WriteConsoleA (get_output_handle (), - buf, strlen (buf), 0, 0); + wchar_t buf[] = L"\033[32768;1H\033[J\033[32768;32768"; + __small_swprintf (buf, L"\033[%d;1H\033[J\033[%d;%dH", + srBottom - con.b.srWindow.Top + 1, + y + 1 - con.b.srWindow.Top, x + 1); + WriteConsoleW (get_output_handle (), + buf, wcslen (buf), 0, 0); } /* Substitute "CSI Ps T" */ wpbuf.put ('[');