Chromium Code Reviews| Index: runtime/bin/platform_win.cc |
| diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc |
| index 71a274346d439320e45cbe43a029e26a2cf21091..e34d515963d8bc9cf69a58c1e10f44c3d9b583a7 100644 |
| --- a/runtime/bin/platform_win.cc |
| +++ b/runtime/bin/platform_win.cc |
| @@ -46,6 +46,7 @@ class PlatformWin { |
| static void InitOnce() { |
| platform_win_mutex_ = new Mutex(); |
| saved_output_cp_ = -1; |
| + saved_input_cp_ = -1; |
| // Set up a no-op handler so that CRT functions return an error instead of |
| // hitting an assertion failure. |
| // See: https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx |
| @@ -61,50 +62,89 @@ class PlatformWin { |
| static void SaveAndConfigureConsole() { |
| MutexLocker ml(platform_win_mutex_); |
| + // Set both the input and output code pages to UTF8. |
| ASSERT(saved_output_cp_ == -1); |
| + ASSERT(saved_input_cp_ == -1); |
| saved_output_cp_ = GetConsoleOutputCP(); |
| + saved_input_cp_ = GetConsoleCP(); |
| SetConsoleOutputCP(CP_UTF8); |
| + SetConsoleCP(CP_UTF8); |
| + ansi_supported_ = true; |
| HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); |
| - if ((out != INVALID_HANDLE_VALUE) && |
| - GetConsoleMode(out, &saved_console_out_mode_)) { |
| - const DWORD request = |
| - saved_console_out_mode_ | ENABLE_VIRTUAL_TERMINAL_PROCESSING; |
| - SetConsoleMode(out, request); |
| + DWORD out_mode; |
| + if ((out != INVALID_HANDLE_VALUE) && GetConsoleMode(out, &out_mode)) { |
| + const DWORD request = out_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING; |
| + ansi_supported_ = ansi_supported_ && SetConsoleMode(out, request); |
| + } else { |
| + ansi_supported_ = false; |
| } |
| HANDLE in = GetStdHandle(STD_INPUT_HANDLE); |
| - if ((in != INVALID_HANDLE_VALUE) && |
| - GetConsoleMode(in, &saved_console_in_mode_)) { |
| - const DWORD request = |
| - saved_console_in_mode_ | ENABLE_VIRTUAL_TERMINAL_INPUT; |
| - SetConsoleMode(in, request); |
| + DWORD in_mode; |
| + if ((in != INVALID_HANDLE_VALUE) && GetConsoleMode(in, &in_mode)) { |
| + const DWORD request = in_mode | ENABLE_VIRTUAL_TERMINAL_INPUT; |
| + ansi_supported_ = ansi_supported_ && SetConsoleMode(in, request); |
| + } else { |
| + ansi_supported_ = false; |
|
sortie
2017/03/16 11:39:08
This looks like escape codes are considered unsupp
|
| } |
| } |
| static void RestoreConsole() { |
| MutexLocker ml(platform_win_mutex_); |
| + |
| + // STD_OUTPUT_HANDLE and STD_INPUT_HANDLE may have been closed or |
| + // redirected. Therefore, we explicitly open the CONOUT$ and CONIN$ |
| + // devices, so that we can be sure that we are really unsetting |
| + // ENABLE_VIRTUAL_TERMINAL_PROCESSING and ENABLE_VIRTUAL_TERMINAL_INPUT |
| + // respectively. |
| + HANDLE out; |
| + { |
| + Utf8ToWideScope conin("CONOUT$"); |
| + out = CreateFileW(conin.wide(), GENERIC_READ | GENERIC_WRITE, |
| + FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); |
| + if (out != INVALID_HANDLE_VALUE) { |
| + SetStdHandle(STD_OUTPUT_HANDLE, out); |
| + } |
| + } |
| + DWORD out_mode; |
| + if ((out != INVALID_HANDLE_VALUE) && GetConsoleMode(out, &out_mode)) { |
| + DWORD request = out_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT; |
| + SetConsoleMode(out, request); |
| + } |
| + |
| + HANDLE in; |
| + { |
| + Utf8ToWideScope conin("CONIN$"); |
| + in = CreateFileW(conin.wide(), GENERIC_READ | GENERIC_WRITE, |
| + FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); |
| + if (in != INVALID_HANDLE_VALUE) { |
| + SetStdHandle(STD_INPUT_HANDLE, in); |
| + } |
| + } |
| + DWORD in_mode; |
| + if ((in != INVALID_HANDLE_VALUE) && GetConsoleMode(in, &in_mode)) { |
| + DWORD request = in_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT; |
| + SetConsoleMode(in, request); |
| + } |
| + |
| if (saved_output_cp_ != -1) { |
| SetConsoleOutputCP(saved_output_cp_); |
| saved_output_cp_ = -1; |
| } |
| - HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); |
| - if (out != INVALID_HANDLE_VALUE) { |
| - SetConsoleMode(out, saved_console_out_mode_); |
| - saved_console_out_mode_ = 0; |
| - } |
| - HANDLE in = GetStdHandle(STD_INPUT_HANDLE); |
| - if (in != INVALID_HANDLE_VALUE) { |
| - SetConsoleMode(in, saved_console_in_mode_); |
| - saved_console_in_mode_ = 0; |
| + if (saved_input_cp_ != -1) { |
| + SetConsoleCP(saved_input_cp_); |
| + saved_input_cp_ = -1; |
| } |
| } |
| + static bool ansi_supported() { return ansi_supported_; } |
| + |
| private: |
| static Mutex* platform_win_mutex_; |
| static int saved_output_cp_; |
| - static DWORD saved_console_out_mode_; |
| - static DWORD saved_console_in_mode_; |
| + static int saved_input_cp_; |
| + static bool ansi_supported_; |
| static void InvalidParameterHandler(const wchar_t* expression, |
| const wchar_t* function, |
| @@ -120,9 +160,9 @@ class PlatformWin { |
| }; |
| int PlatformWin::saved_output_cp_ = -1; |
| -DWORD PlatformWin::saved_console_out_mode_ = 0; |
| -DWORD PlatformWin::saved_console_in_mode_ = 0; |
| +int PlatformWin::saved_input_cp_ = -1; |
| Mutex* PlatformWin::platform_win_mutex_ = NULL; |
| +bool PlatformWin::ansi_supported_ = false; |
| bool Platform::Initialize() { |
| PlatformWin::InitOnce(); |
| @@ -219,6 +259,11 @@ const char* Platform::ResolveExecutablePath() { |
| } |
| +bool Platform::AnsiSupported() { |
| + return PlatformWin::ansi_supported(); |
| +} |
| + |
| + |
| void Platform::Exit(int exit_code) { |
| // TODO(zra): Remove once VM shuts down cleanly. |
| ::dart::private_flag_windows_run_tls_destructors = false; |