1 // This file is included into test programs using #include
11 #include "../src/shared/DebugClient.h"
12 #include "../src/shared/TimeMeasurement.h"
14 #include "../src/shared/DebugClient.cc"
15 #include "../src/shared/WinptyAssert.cc"
16 #include "../src/shared/WinptyException.cc"
18 // Launch this test program again, in a new console that we will destroy.
19 static void startChildProcess(const wchar_t *args) {
20 wchar_t program[1024];
21 wchar_t cmdline[1024];
22 GetModuleFileNameW(NULL, program, 1024);
23 swprintf(cmdline, L"\"%ls\" %ls", program, args);
26 PROCESS_INFORMATION pi;
27 memset(&sui, 0, sizeof(sui));
28 memset(&pi, 0, sizeof(pi));
31 CreateProcessW(program, cmdline,
33 /*bInheritHandles=*/FALSE,
34 /*dwCreationFlags=*/CREATE_NEW_CONSOLE,
39 static void setBufferSize(HANDLE conout, int x, int y) {
40 COORD size = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
41 BOOL success = SetConsoleScreenBufferSize(conout, size);
42 trace("setBufferSize: (%d,%d), result=%d", x, y, success);
45 static void setWindowPos(HANDLE conout, int x, int y, int w, int h) {
47 static_cast<SHORT>(x), static_cast<SHORT>(y),
48 static_cast<SHORT>(x + w - 1),
49 static_cast<SHORT>(y + h - 1)
51 BOOL success = SetConsoleWindowInfo(conout, /*bAbsolute=*/TRUE, &r);
52 trace("setWindowPos: (%d,%d,%d,%d), result=%d", x, y, w, h, success);
55 static void setCursorPos(HANDLE conout, int x, int y) {
56 COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
57 SetConsoleCursorPosition(conout, coord);
60 static void setBufferSize(int x, int y) {
61 setBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), x, y);
64 static void setWindowPos(int x, int y, int w, int h) {
65 setWindowPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y, w, h);
68 static void setCursorPos(int x, int y) {
69 setCursorPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y);
72 static void countDown(int sec) {
73 for (int i = sec; i > 0; --i) {
81 static void writeBox(int x, int y, int w, int h, char ch, int attributes=7) {
82 CHAR_INFO info = { 0 };
83 info.Char.AsciiChar = ch;
84 info.Attributes = attributes;
85 std::vector<CHAR_INFO> buf(w * h, info);
86 HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
87 COORD bufSize = { static_cast<SHORT>(w), static_cast<SHORT>(h) };
88 COORD bufCoord = { 0, 0 };
89 SMALL_RECT writeRegion = {
90 static_cast<SHORT>(x),
91 static_cast<SHORT>(y),
92 static_cast<SHORT>(x + w - 1),
93 static_cast<SHORT>(y + h - 1)
95 WriteConsoleOutputA(conout, buf.data(), bufSize, bufCoord, &writeRegion);
98 static void setChar(int x, int y, char ch, int attributes=7) {
99 writeBox(x, y, 1, 1, ch, attributes);
102 static void fillChar(int x, int y, int repeat, char ch) {
103 COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
105 FillConsoleOutputCharacterA(
106 GetStdHandle(STD_OUTPUT_HANDLE),
107 ch, repeat, coord, &actual);
110 static void repeatChar(int count, char ch) {
111 for (int i = 0; i < count; ++i) {
117 // I don't know why, but wprintf fails to print this face name,
118 // "MS ゴシック" (aka MS Gothic). It helps to use wprintf instead of printf, and
119 // it helps to call `setlocale(LC_ALL, "")`, but the Japanese symbols are
120 // ultimately converted to `?` symbols, even though MS Gothic is able to
121 // display its own name, and the current code page is 932 (Shift-JIS).
122 static void cvfprintf(HANDLE conout, const wchar_t *fmt, va_list ap) {
124 vswprintf(buffer, 256 - 1, fmt, ap);
127 if (!WriteConsoleW(conout, buffer, wcslen(buffer), &actual, NULL)) {
128 wprintf(L"WriteConsoleW call failed!\n");
132 static void cfprintf(HANDLE conout, const wchar_t *fmt, ...) {
135 cvfprintf(conout, fmt, ap);
139 static void cprintf(const wchar_t *fmt, ...) {
142 cvfprintf(GetStdHandle(STD_OUTPUT_HANDLE), fmt, ap);
146 static std::string narrowString(const std::wstring &input)
148 int mblen = WideCharToMultiByte(
150 input.data(), input.size(),
151 NULL, 0, NULL, NULL);
153 return std::string();
155 std::vector<char> tmp(mblen);
156 int mblen2 = WideCharToMultiByte(
158 input.data(), input.size(),
159 tmp.data(), tmp.size(),
161 assert(mblen2 == mblen);
162 return std::string(tmp.data(), tmp.size());
165 HANDLE openConout() {
166 const HANDLE conout = CreateFileW(L"CONOUT$",
167 GENERIC_READ | GENERIC_WRITE,
168 FILE_SHARE_READ | FILE_SHARE_WRITE,
169 NULL, OPEN_EXISTING, 0, NULL);
170 ASSERT(conout != INVALID_HANDLE_VALUE);