UNPKG

5.35 kBtext/x-cView Raw
1// This file is included into test programs using #include
2
3#include <windows.h>
4#include <assert.h>
5#include <stdio.h>
6#include <string.h>
7#include <wchar.h>
8#include <vector>
9#include <string>
10
11#include "../src/shared/DebugClient.h"
12#include "../src/shared/TimeMeasurement.h"
13
14#include "../src/shared/DebugClient.cc"
15#include "../src/shared/WinptyAssert.cc"
16#include "../src/shared/WinptyException.cc"
17
18// Launch this test program again, in a new console that we will destroy.
19static 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);
24
25 STARTUPINFOW sui;
26 PROCESS_INFORMATION pi;
27 memset(&sui, 0, sizeof(sui));
28 memset(&pi, 0, sizeof(pi));
29 sui.cb = sizeof(sui);
30
31 CreateProcessW(program, cmdline,
32 NULL, NULL,
33 /*bInheritHandles=*/FALSE,
34 /*dwCreationFlags=*/CREATE_NEW_CONSOLE,
35 NULL, NULL,
36 &sui, &pi);
37}
38
39static 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);
43}
44
45static void setWindowPos(HANDLE conout, int x, int y, int w, int h) {
46 SMALL_RECT r = {
47 static_cast<SHORT>(x), static_cast<SHORT>(y),
48 static_cast<SHORT>(x + w - 1),
49 static_cast<SHORT>(y + h - 1)
50 };
51 BOOL success = SetConsoleWindowInfo(conout, /*bAbsolute=*/TRUE, &r);
52 trace("setWindowPos: (%d,%d,%d,%d), result=%d", x, y, w, h, success);
53}
54
55static void setCursorPos(HANDLE conout, int x, int y) {
56 COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
57 SetConsoleCursorPosition(conout, coord);
58}
59
60static void setBufferSize(int x, int y) {
61 setBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), x, y);
62}
63
64static void setWindowPos(int x, int y, int w, int h) {
65 setWindowPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y, w, h);
66}
67
68static void setCursorPos(int x, int y) {
69 setCursorPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y);
70}
71
72static void countDown(int sec) {
73 for (int i = sec; i > 0; --i) {
74 printf("%d.. ", i);
75 fflush(stdout);
76 Sleep(1000);
77 }
78 printf("\n");
79}
80
81static 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)
94 };
95 WriteConsoleOutputA(conout, buf.data(), bufSize, bufCoord, &writeRegion);
96}
97
98static void setChar(int x, int y, char ch, int attributes=7) {
99 writeBox(x, y, 1, 1, ch, attributes);
100}
101
102static void fillChar(int x, int y, int repeat, char ch) {
103 COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
104 DWORD actual = 0;
105 FillConsoleOutputCharacterA(
106 GetStdHandle(STD_OUTPUT_HANDLE),
107 ch, repeat, coord, &actual);
108}
109
110static void repeatChar(int count, char ch) {
111 for (int i = 0; i < count; ++i) {
112 putchar(ch);
113 }
114 fflush(stdout);
115}
116
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).
122static void cvfprintf(HANDLE conout, const wchar_t *fmt, va_list ap) {
123 wchar_t buffer[256];
124 vswprintf(buffer, 256 - 1, fmt, ap);
125 buffer[255] = L'\0';
126 DWORD actual = 0;
127 if (!WriteConsoleW(conout, buffer, wcslen(buffer), &actual, NULL)) {
128 wprintf(L"WriteConsoleW call failed!\n");
129 }
130}
131
132static void cfprintf(HANDLE conout, const wchar_t *fmt, ...) {
133 va_list ap;
134 va_start(ap, fmt);
135 cvfprintf(conout, fmt, ap);
136 va_end(ap);
137}
138
139static void cprintf(const wchar_t *fmt, ...) {
140 va_list ap;
141 va_start(ap, fmt);
142 cvfprintf(GetStdHandle(STD_OUTPUT_HANDLE), fmt, ap);
143 va_end(ap);
144}
145
146static std::string narrowString(const std::wstring &input)
147{
148 int mblen = WideCharToMultiByte(
149 CP_UTF8, 0,
150 input.data(), input.size(),
151 NULL, 0, NULL, NULL);
152 if (mblen <= 0) {
153 return std::string();
154 }
155 std::vector<char> tmp(mblen);
156 int mblen2 = WideCharToMultiByte(
157 CP_UTF8, 0,
158 input.data(), input.size(),
159 tmp.data(), tmp.size(),
160 NULL, NULL);
161 assert(mblen2 == mblen);
162 return std::string(tmp.data(), tmp.size());
163}
164
165HANDLE 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);
171 return conout;
172}