|
|
|
|
|
#include <windows.h> |
|
#include <assert.h> |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include <wchar.h> |
|
#include <vector> |
|
#include <string> |
|
|
|
#include "../src/shared/DebugClient.h" |
|
#include "../src/shared/TimeMeasurement.h" |
|
|
|
#include "../src/shared/DebugClient.cc" |
|
#include "../src/shared/WinptyAssert.cc" |
|
#include "../src/shared/WinptyException.cc" |
|
|
|
|
|
static void startChildProcess(const wchar_t *args) { |
|
wchar_t program[1024]; |
|
wchar_t cmdline[1024]; |
|
GetModuleFileNameW(NULL, program, 1024); |
|
swprintf(cmdline, L"\"%ls\" %ls", program, args); |
|
|
|
STARTUPINFOW sui; |
|
PROCESS_INFORMATION pi; |
|
memset(&sui, 0, sizeof(sui)); |
|
memset(&pi, 0, sizeof(pi)); |
|
sui.cb = sizeof(sui); |
|
|
|
CreateProcessW(program, cmdline, |
|
NULL, NULL, |
|
FALSE, |
|
CREATE_NEW_CONSOLE, |
|
NULL, NULL, |
|
&sui, &pi); |
|
} |
|
|
|
static void setBufferSize(HANDLE conout, int x, int y) { |
|
COORD size = { static_cast<SHORT>(x), static_cast<SHORT>(y) }; |
|
BOOL success = SetConsoleScreenBufferSize(conout, size); |
|
trace("setBufferSize: (%d,%d), result=%d", x, y, success); |
|
} |
|
|
|
static void setWindowPos(HANDLE conout, int x, int y, int w, int h) { |
|
SMALL_RECT r = { |
|
static_cast<SHORT>(x), static_cast<SHORT>(y), |
|
static_cast<SHORT>(x + w - 1), |
|
static_cast<SHORT>(y + h - 1) |
|
}; |
|
BOOL success = SetConsoleWindowInfo(conout, TRUE, &r); |
|
trace("setWindowPos: (%d,%d,%d,%d), result=%d", x, y, w, h, success); |
|
} |
|
|
|
static void setCursorPos(HANDLE conout, int x, int y) { |
|
COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) }; |
|
SetConsoleCursorPosition(conout, coord); |
|
} |
|
|
|
static void setBufferSize(int x, int y) { |
|
setBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), x, y); |
|
} |
|
|
|
static void setWindowPos(int x, int y, int w, int h) { |
|
setWindowPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y, w, h); |
|
} |
|
|
|
static void setCursorPos(int x, int y) { |
|
setCursorPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y); |
|
} |
|
|
|
static void countDown(int sec) { |
|
for (int i = sec; i > 0; --i) { |
|
printf("%d.. ", i); |
|
fflush(stdout); |
|
Sleep(1000); |
|
} |
|
printf("\n"); |
|
} |
|
|
|
static void writeBox(int x, int y, int w, int h, char ch, int attributes=7) { |
|
CHAR_INFO info = { 0 }; |
|
info.Char.AsciiChar = ch; |
|
info.Attributes = attributes; |
|
std::vector<CHAR_INFO> buf(w * h, info); |
|
HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE); |
|
COORD bufSize = { static_cast<SHORT>(w), static_cast<SHORT>(h) }; |
|
COORD bufCoord = { 0, 0 }; |
|
SMALL_RECT writeRegion = { |
|
static_cast<SHORT>(x), |
|
static_cast<SHORT>(y), |
|
static_cast<SHORT>(x + w - 1), |
|
static_cast<SHORT>(y + h - 1) |
|
}; |
|
WriteConsoleOutputA(conout, buf.data(), bufSize, bufCoord, &writeRegion); |
|
} |
|
|
|
static void setChar(int x, int y, char ch, int attributes=7) { |
|
writeBox(x, y, 1, 1, ch, attributes); |
|
} |
|
|
|
static void fillChar(int x, int y, int repeat, char ch) { |
|
COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) }; |
|
DWORD actual = 0; |
|
FillConsoleOutputCharacterA( |
|
GetStdHandle(STD_OUTPUT_HANDLE), |
|
ch, repeat, coord, &actual); |
|
} |
|
|
|
static void repeatChar(int count, char ch) { |
|
for (int i = 0; i < count; ++i) { |
|
putchar(ch); |
|
} |
|
fflush(stdout); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
static void cvfprintf(HANDLE conout, const wchar_t *fmt, va_list ap) { |
|
wchar_t buffer[256]; |
|
vswprintf(buffer, 256 - 1, fmt, ap); |
|
buffer[255] = L'\0'; |
|
DWORD actual = 0; |
|
if (!WriteConsoleW(conout, buffer, wcslen(buffer), &actual, NULL)) { |
|
wprintf(L"WriteConsoleW call failed!\n"); |
|
} |
|
} |
|
|
|
static void cfprintf(HANDLE conout, const wchar_t *fmt, ...) { |
|
va_list ap; |
|
va_start(ap, fmt); |
|
cvfprintf(conout, fmt, ap); |
|
va_end(ap); |
|
} |
|
|
|
static void cprintf(const wchar_t *fmt, ...) { |
|
va_list ap; |
|
va_start(ap, fmt); |
|
cvfprintf(GetStdHandle(STD_OUTPUT_HANDLE), fmt, ap); |
|
va_end(ap); |
|
} |
|
|
|
static std::string narrowString(const std::wstring &input) |
|
{ |
|
int mblen = WideCharToMultiByte( |
|
CP_UTF8, 0, |
|
input.data(), input.size(), |
|
NULL, 0, NULL, NULL); |
|
if (mblen <= 0) { |
|
return std::string(); |
|
} |
|
std::vector<char> tmp(mblen); |
|
int mblen2 = WideCharToMultiByte( |
|
CP_UTF8, 0, |
|
input.data(), input.size(), |
|
tmp.data(), tmp.size(), |
|
NULL, NULL); |
|
assert(mblen2 == mblen); |
|
return std::string(tmp.data(), tmp.size()); |
|
} |
|
|
|
HANDLE openConout() { |
|
const HANDLE conout = CreateFileW(L"CONOUT$", |
|
GENERIC_READ | GENERIC_WRITE, |
|
FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
NULL, OPEN_EXISTING, 0, NULL); |
|
ASSERT(conout != INVALID_HANDLE_VALUE); |
|
return conout; |
|
} |
|
|