Flutter Engine
The Flutter Engine
console_win.cc
Go to the documentation of this file.
1// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(DART_HOST_OS_WINDOWS)
7#include "bin/console.h"
8
9#include "bin/file.h"
10#include "bin/lockers.h"
11#include "bin/platform.h"
12#include "bin/utils.h"
13#include "bin/utils_win.h"
14
15// These are not always defined in the header files. See:
16// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
17#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
18#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
19#endif
20
21namespace dart {
22namespace bin {
23
24class ConsoleWin {
25 public:
26 static constexpr int kInvalidFlag = -1;
27
28 static void Initialize() {
29 saved_output_cp_ = kInvalidFlag;
30 saved_input_cp_ = kInvalidFlag;
31 // Set up a signal handler that restores the console state on a
32 // CTRL_C_EVENT signal. This will only run when there is no signal handler
33 // registered for the CTRL_C_EVENT from Dart code.
34 SetConsoleCtrlHandler(SignalHandler, TRUE);
35
36 // Set both the input and output code pages to UTF8.
37 const int output_cp = GetConsoleOutputCP();
38 const int input_cp = GetConsoleCP();
39 if (output_cp != CP_UTF8) {
40 SetConsoleOutputCP(CP_UTF8);
41 saved_output_cp_ = output_cp;
42 }
43 if (input_cp != CP_UTF8) {
44 SetConsoleCP(CP_UTF8);
45 saved_input_cp_ = input_cp;
46 }
47
48 // Try to set the bits for ANSI support, but swallow any failures.
49 saved_stdout_mode_ =
50 ModifyMode(STD_OUTPUT_HANDLE, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
51 saved_stderr_mode_ =
52 ModifyMode(STD_ERROR_HANDLE, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
53 saved_stdin_mode_ = ModifyMode(STD_INPUT_HANDLE, 0);
54
55 // TODO(28984): Due to issue #29104, we cannot set
56 // ENABLE_VIRTUAL_TERMINAL_INPUT here, as it causes ENABLE_PROCESSED_INPUT
57 // to be ignored.
58 }
59
60 static void Cleanup() {
61 // STD_OUTPUT_HANDLE, may have been closed or redirected. Therefore, we
62 // explicitly open the CONOUT$, CONERR$ and CONIN$ devices, so that we can
63 // be sure that we are really restoring the console to its original state.
64 if (saved_stdout_mode_ != kInvalidFlag) {
65 CleanupDevices("CONOUT$", STD_OUTPUT_HANDLE, saved_stdout_mode_);
66 saved_stdout_mode_ = kInvalidFlag;
67 }
68 if (saved_stderr_mode_ != kInvalidFlag) {
69 CleanupDevices("CONERR$", STD_ERROR_HANDLE, saved_stderr_mode_);
70 }
71 if (saved_stdin_mode_ != kInvalidFlag) {
72 CleanupDevices("CONIN$", STD_INPUT_HANDLE, saved_stdin_mode_);
73 }
74 if (saved_output_cp_ != kInvalidFlag) {
75 SetConsoleOutputCP(saved_output_cp_);
76 saved_output_cp_ = kInvalidFlag;
77 }
78 if (saved_input_cp_ != kInvalidFlag) {
79 SetConsoleCP(saved_input_cp_);
80 saved_input_cp_ = kInvalidFlag;
81 }
82 }
83
84 private:
85 static int saved_output_cp_;
86 static int saved_input_cp_;
87 static DWORD saved_stdout_mode_;
88 static DWORD saved_stderr_mode_;
89 static DWORD saved_stdin_mode_;
90
91 static BOOL WINAPI SignalHandler(DWORD signal) {
92 if (signal == CTRL_C_EVENT) {
93 Cleanup();
94 }
95 return FALSE;
96 }
97
98 static DWORD ModifyMode(DWORD handle, DWORD flags) {
99 HANDLE h = GetStdHandle(handle);
100 DWORD mode;
101 DWORD old_mode = kInvalidFlag;
102
103 /// GetConsoleMode fails if this instance of the VM isn't attached to a
104 /// console. In that case, we'll just return kInvalidFlag and won't try
105 /// to reset the state when we cleanup.
106 if ((h != INVALID_HANDLE_VALUE) && GetConsoleMode(h, &mode)) {
107 old_mode = mode;
108 // No reason to restore the mode on exit if it was already desirable.
109 if ((mode & flags) == flags) {
110 return kInvalidFlag;
111 }
112 if (flags != 0) {
113 const DWORD request = mode | flags;
114 SetConsoleMode(h, request);
115 }
116 }
117 return old_mode;
118 }
119
120 static void CleanupDevices(const char* device,
121 DWORD handle,
122 DWORD orig_flags) {
123 const intptr_t kWideBufLen = 64;
124 wchar_t widebuf[kWideBufLen];
125 int result =
126 MultiByteToWideChar(CP_UTF8, 0, device, -1, widebuf, kWideBufLen);
127 ASSERT(result != 0);
128 HANDLE h = CreateFileW(widebuf, GENERIC_READ | GENERIC_WRITE,
129 FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
130 if (h != INVALID_HANDLE_VALUE) {
131 SetStdHandle(STD_OUTPUT_HANDLE, h);
132 if (orig_flags != kInvalidFlag) {
133 SetConsoleMode(h, orig_flags);
134 }
135 }
136 }
137
140};
141
142int ConsoleWin::saved_output_cp_ = ConsoleWin::kInvalidFlag;
143int ConsoleWin::saved_input_cp_ = ConsoleWin::kInvalidFlag;
144DWORD ConsoleWin::saved_stdout_mode_ = ConsoleWin::kInvalidFlag;
145DWORD ConsoleWin::saved_stderr_mode_ = ConsoleWin::kInvalidFlag;
146DWORD ConsoleWin::saved_stdin_mode_ = ConsoleWin::kInvalidFlag;
147
148void Console::SaveConfig() {
150}
151
154}
155
156} // namespace bin
157} // namespace dart
158
159#endif // defined(DART_HOST_OS_WINDOWS)
static void RestoreConfig()
static void SaveConfig()
#define ASSERT(E)
VkDevice device
Definition: main.cc:53
FlutterSemanticsFlag flags
GAsyncResult * result
return FALSE
Definition: dart_vm.cc:33
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
static void SignalHandler(int signal)
Definition: backtrace.cc:101
void Initialize(zx::channel directory_request, std::optional< zx::eventpair > view_ref)
Initializes Dart bindings for the Fuchsia application model.
Definition: fuchsia.cc:103
SkScalar h
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)
Definition: globals.h:593
#define DISALLOW_ALLOCATION()
Definition: globals.h:604
int BOOL
Definition: windows_types.h:37
#define INVALID_HANDLE_VALUE
#define WINAPI
void * HANDLE
Definition: windows_types.h:36
unsigned long DWORD
Definition: windows_types.h:22