1// Copyright (c) 2013, 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(HOST_OS_WINDOWS)
7
8#include "bin/stdio.h"
9
10// These are not always defined in the header files. See:
11// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
12#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
13#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
14#endif
15
16#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
17#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
18#endif
19
20namespace dart {
21namespace bin {
22
23bool Stdin::ReadByte(intptr_t fd, int* byte) {
24 HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
25 uint8_t buffer[1];
26 DWORD read = 0;
27 BOOL success = ReadFile(h, buffer, 1, &read, NULL);
28 if (!success && (GetLastError() != ERROR_BROKEN_PIPE)) {
29 return false;
30 }
31 *byte = (read == 1) ? buffer[0] : -1;
32 return true;
33}
34
35bool Stdin::GetEchoMode(intptr_t fd, bool* enabled) {
36 HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
37 DWORD mode;
38 if (!GetConsoleMode(h, &mode)) {
39 return false;
40 }
41 *enabled = ((mode & ENABLE_ECHO_INPUT) != 0);
42 return true;
43}
44
45bool Stdin::SetEchoMode(intptr_t fd, bool enabled) {
46 HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
47 DWORD mode;
48 if (!GetConsoleMode(h, &mode)) {
49 return false;
50 }
51 if (enabled) {
52 mode |= ENABLE_ECHO_INPUT;
53 } else {
54 mode &= ~ENABLE_ECHO_INPUT;
55 }
56 return SetConsoleMode(h, mode);
57}
58
59bool Stdin::GetLineMode(intptr_t fd, bool* enabled) {
60 HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
61 DWORD mode;
62 if (!GetConsoleMode(h, &mode)) {
63 return false;
64 }
65 *enabled = (mode & ENABLE_LINE_INPUT) != 0;
66 return true;
67}
68
69bool Stdin::SetLineMode(intptr_t fd, bool enabled) {
70 HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
71 DWORD mode;
72 if (!GetConsoleMode(h, &mode)) {
73 return false;
74 }
75 if (enabled) {
76 mode |= ENABLE_LINE_INPUT;
77 } else {
78 mode &= ~ENABLE_LINE_INPUT;
79 }
80 return SetConsoleMode(h, mode);
81}
82
83bool Stdin::AnsiSupported(intptr_t fd, bool* supported) {
84 ASSERT(supported != NULL);
85 HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
86 if (h == INVALID_HANDLE_VALUE) {
87 *supported = false;
88 return true;
89 }
90 DWORD mode;
91 if (!GetConsoleMode(h, &mode)) {
92 *supported = false;
93 return true;
94 }
95 *supported = (mode & ENABLE_VIRTUAL_TERMINAL_INPUT) != 0;
96 return true;
97}
98
99bool Stdout::GetTerminalSize(intptr_t fd, int size[2]) {
100 HANDLE h;
101 if (fd == 1) {
102 h = GetStdHandle(STD_OUTPUT_HANDLE);
103 } else {
104 h = GetStdHandle(STD_ERROR_HANDLE);
105 }
106 CONSOLE_SCREEN_BUFFER_INFO info;
107 if (!GetConsoleScreenBufferInfo(h, &info)) {
108 return false;
109 }
110 size[0] = info.srWindow.Right - info.srWindow.Left + 1;
111 size[1] = info.srWindow.Bottom - info.srWindow.Top + 1;
112 return true;
113}
114
115bool Stdout::AnsiSupported(intptr_t fd, bool* supported) {
116 ASSERT(supported != NULL);
117 HANDLE h;
118 if (fd == 1) {
119 h = GetStdHandle(STD_OUTPUT_HANDLE);
120 } else {
121 h = GetStdHandle(STD_ERROR_HANDLE);
122 }
123 if (h == INVALID_HANDLE_VALUE) {
124 *supported = false;
125 return true;
126 }
127 DWORD mode;
128 if (!GetConsoleMode(h, &mode)) {
129 *supported = false;
130 return true;
131 }
132 *supported = (mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0;
133 return true;
134}
135
136} // namespace bin
137} // namespace dart
138
139#endif // defined(HOST_OS_WINDOWS)
140