Update test programs for font/resizing work

* Rename QueryFont.exe to GetFont.exe -- it's shorted.  Make font table
   output shorter.  Make the program work on XP.

 * Add IsNewConsole.exe

 * Add GetBufferInfo.exe

 * Clear the executable bit on some .cc files
This commit is contained in:
Ryan Prichard 2016-06-04 21:10:19 -05:00
parent d0ae4cbb28
commit ebefb91e80
8 changed files with 344 additions and 74 deletions

25
misc/GetBufferInfo.cc Normal file
View File

@ -0,0 +1,25 @@
#include <windows.h>
#include <stdio.h>
#include "TestUtil.cc"
int main() {
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);
CONSOLE_SCREEN_BUFFER_INFO info = {};
BOOL ret = GetConsoleScreenBufferInfo(conout, &info);
ASSERT(ret && "GetConsoleScreenBufferInfo failed");
trace("srWindow={L=%d,T=%d,R=%d,B=%d}", info.srWindow.Left, info.srWindow.Top, info.srWindow.Right, info.srWindow.Bottom);
printf("srWindow={L=%d,T=%d,R=%d,B=%d}\n", info.srWindow.Left, info.srWindow.Top, info.srWindow.Right, info.srWindow.Bottom);
trace("dwSize=%d,%d", info.dwSize.X);
printf("dwSize=%d,%d\n", info.dwSize.X);
return 0;
}

261
misc/GetFont.cc Normal file
View File

@ -0,0 +1,261 @@
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <wchar.h>
#include "../src/shared/OsModule.h"
#include "../src/shared/StringUtil.h"
#include "TestUtil.cc"
#include "../src/shared/StringUtil.cc"
#define COUNT_OF(x) (sizeof(x) / sizeof((x)[0]))
// Some of these types and functions are missing from the MinGW headers.
// Others are undocumented.
struct AGENT_CONSOLE_FONT_INFO {
DWORD nFont;
COORD dwFontSize;
};
struct AGENT_CONSOLE_FONT_INFOEX {
ULONG cbSize;
DWORD nFont;
COORD dwFontSize;
UINT FontFamily;
UINT FontWeight;
WCHAR FaceName[LF_FACESIZE];
};
// undocumented XP API
typedef BOOL WINAPI SetConsoleFont_t(
HANDLE hOutput,
DWORD dwFontIndex);
// undocumented XP API
typedef DWORD WINAPI GetNumberOfConsoleFonts_t();
// XP and up
typedef BOOL WINAPI GetCurrentConsoleFont_t(
HANDLE hOutput,
BOOL bMaximumWindow,
AGENT_CONSOLE_FONT_INFO *lpConsoleCurrentFont);
// XP and up
typedef COORD WINAPI GetConsoleFontSize_t(
HANDLE hConsoleOutput,
DWORD nFont);
// Vista and up
typedef BOOL WINAPI GetCurrentConsoleFontEx_t(
HANDLE hConsoleOutput,
BOOL bMaximumWindow,
AGENT_CONSOLE_FONT_INFOEX *lpConsoleCurrentFontEx);
// Vista and up
typedef BOOL WINAPI SetCurrentConsoleFontEx_t(
HANDLE hConsoleOutput,
BOOL bMaximumWindow,
AGENT_CONSOLE_FONT_INFOEX *lpConsoleCurrentFontEx);
#define GET_MODULE_PROC(mod, funcName) \
m_##funcName = reinterpret_cast<funcName##_t*>((mod).proc(#funcName)); \
#define DEFINE_ACCESSOR(funcName) \
funcName##_t &funcName() const { \
ASSERT(valid()); \
return *m_##funcName; \
}
class XPFontAPI {
public:
XPFontAPI() : m_kernel32(L"kernel32.dll") {
GET_MODULE_PROC(m_kernel32, GetCurrentConsoleFont);
GET_MODULE_PROC(m_kernel32, GetConsoleFontSize);
}
bool valid() const {
return m_GetCurrentConsoleFont != NULL &&
m_GetConsoleFontSize != NULL;
}
DEFINE_ACCESSOR(GetCurrentConsoleFont)
DEFINE_ACCESSOR(GetConsoleFontSize)
private:
OsModule m_kernel32;
GetCurrentConsoleFont_t *m_GetCurrentConsoleFont;
GetConsoleFontSize_t *m_GetConsoleFontSize;
};
class UndocumentedXPFontAPI : public XPFontAPI {
public:
UndocumentedXPFontAPI() : m_kernel32(L"kernel32.dll") {
GET_MODULE_PROC(m_kernel32, SetConsoleFont);
GET_MODULE_PROC(m_kernel32, GetNumberOfConsoleFonts);
}
bool valid() const {
return this->XPFontAPI::valid() &&
m_SetConsoleFont != NULL &&
m_GetNumberOfConsoleFonts != NULL;
}
DEFINE_ACCESSOR(SetConsoleFont)
DEFINE_ACCESSOR(GetNumberOfConsoleFonts)
private:
OsModule m_kernel32;
SetConsoleFont_t *m_SetConsoleFont;
GetNumberOfConsoleFonts_t *m_GetNumberOfConsoleFonts;
};
class VistaFontAPI : public XPFontAPI {
public:
VistaFontAPI() : m_kernel32(L"kernel32.dll") {
GET_MODULE_PROC(m_kernel32, GetCurrentConsoleFontEx);
GET_MODULE_PROC(m_kernel32, SetCurrentConsoleFontEx);
}
bool valid() const {
return this->XPFontAPI::valid() &&
m_GetCurrentConsoleFontEx != NULL &&
m_SetCurrentConsoleFontEx != NULL;
}
DEFINE_ACCESSOR(GetCurrentConsoleFontEx)
DEFINE_ACCESSOR(SetCurrentConsoleFontEx)
private:
OsModule m_kernel32;
GetCurrentConsoleFontEx_t *m_GetCurrentConsoleFontEx;
SetCurrentConsoleFontEx_t *m_SetCurrentConsoleFontEx;
};
static std::vector<std::pair<DWORD, COORD> > readFontTable(
XPFontAPI &api, HANDLE conout, DWORD maxCount) {
std::vector<std::pair<DWORD, COORD> > ret;
for (DWORD i = 0; i < maxCount; ++i) {
COORD size = api.GetConsoleFontSize()(conout, i);
if (size.X == 0 && size.Y == 0) {
break;
}
ret.push_back(std::make_pair(i, size));
}
return ret;
}
static void dumpFontTable(HANDLE conout) {
const int kMaxCount = 1000;
XPFontAPI api;
if (!api.valid()) {
printf("dumpFontTable: cannot dump font table -- missing APIs\n");
return;
}
std::vector<std::pair<DWORD, COORD> > table =
readFontTable(api, conout, kMaxCount);
std::string line;
char tmp[128];
size_t first = 0;
while (first < table.size()) {
size_t last = std::min(table.size() - 1, first + 10 - 1);
winpty_snprintf(tmp, "%02u-%02u:",
static_cast<unsigned>(first), static_cast<unsigned>(last));
line = tmp;
for (size_t i = first; i <= last; ++i) {
if (i % 10 == 5) {
line += " - ";
}
winpty_snprintf(tmp, " %2dx%-2d",
table[i].second.X, table[i].second.Y);
line += tmp;
}
printf("%s\n", line.c_str());
first = last + 1;
}
if (table.size() == kMaxCount) {
printf("... stopped reading at %d fonts ...\n", kMaxCount);
}
}
static std::string stringToCodePoints(const std::wstring &str) {
std::string ret = "(";
for (size_t i = 0; i < str.size(); ++i) {
char tmp[32];
winpty_snprintf(tmp, "%X", str[i]);
if (ret.size() > 1) {
ret.push_back(' ');
}
ret += tmp;
}
ret.push_back(')');
return ret;
}
static void dumpFontInfoEx(
const AGENT_CONSOLE_FONT_INFOEX &infoex) {
std::wstring faceName(infoex.FaceName,
winpty_wcsnlen(infoex.FaceName, COUNT_OF(infoex.FaceName)));
cprintf(L"nFont=%u dwFontSize=(%d,%d) "
"FontFamily=0x%x FontWeight=%u FaceName=%ls %hs\n",
static_cast<unsigned>(infoex.nFont),
infoex.dwFontSize.X, infoex.dwFontSize.Y,
infoex.FontFamily, infoex.FontWeight, faceName.c_str(),
stringToCodePoints(faceName).c_str());
}
static void dumpVistaFont(VistaFontAPI &api, HANDLE conout, BOOL maxWindow) {
AGENT_CONSOLE_FONT_INFOEX infoex = {0};
infoex.cbSize = sizeof(infoex);
if (!api.GetCurrentConsoleFontEx()(conout, maxWindow, &infoex)) {
printf("GetCurrentConsoleFontEx call failed\n");
return;
}
dumpFontInfoEx(infoex);
}
static void dumpXPFont(XPFontAPI &api, HANDLE conout, BOOL maxWindow) {
AGENT_CONSOLE_FONT_INFO info = {0};
if (!api.GetCurrentConsoleFont()(conout, maxWindow, &info)) {
printf("GetCurrentConsoleFont call failed\n");
return;
}
printf("nFont=%u dwFontSize=(%d,%d)\n",
static_cast<unsigned>(info.nFont),
info.dwFontSize.X, info.dwFontSize.Y);
}
static void dumpFontAndTable(HANDLE conout) {
VistaFontAPI vista;
if (vista.valid()) {
printf("maxWnd=0: "); dumpVistaFont(vista, conout, FALSE);
printf("maxWnd=1: "); dumpVistaFont(vista, conout, TRUE);
dumpFontTable(conout);
return;
}
UndocumentedXPFontAPI xp;
if (xp.valid()) {
printf("maxWnd=0: "); dumpXPFont(xp, conout, FALSE);
printf("maxWnd=1: "); dumpXPFont(xp, conout, TRUE);
dumpFontTable(conout);
return;
}
printf("setSmallFont: neither Vista nor XP APIs detected -- giving up\n");
dumpFontTable(conout);
}
int main() {
const HANDLE conout = openConout();
const COORD largest = GetLargestConsoleWindowSize(conout);
printf("largestConsoleWindowSize=(%d,%d)\n", largest.X, largest.Y);
dumpFontAndTable(conout);
UndocumentedXPFontAPI xp;
if (xp.valid()) {
printf("GetNumberOfConsoleFonts returned %u\n", xp.GetNumberOfConsoleFonts()());
} else {
printf("The GetNumberOfConsoleFonts API was missing\n");
}
printf("CP=%u OutputCP=%u\n", GetConsoleCP(), GetConsoleOutputCP());
return 0;
}

49
misc/IsNewConsole.cc Normal file
View File

@ -0,0 +1,49 @@
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "TestUtil.cc"
const int SC_CONSOLE_MARK = 0xFFF2;
const int SC_CONSOLE_SELECT_ALL = 0xFFF5;
static COORD getCursorPos(HANDLE conout) {
CONSOLE_SCREEN_BUFFER_INFO info = {};
BOOL ret = GetConsoleScreenBufferInfo(conout, &info);
ASSERT(ret && "GetConsoleScreenBufferInfo failed");
return info.dwCursorPosition;
}
static void setCursorPos(HANDLE conout, COORD pos) {
BOOL ret = SetConsoleCursorPosition(conout, pos);
ASSERT(ret && "SetConsoleCursorPosition failed");
}
int main() {
const HANDLE conout = openConout();
const HWND hwnd = GetConsoleWindow();
ASSERT(hwnd != NULL && "GetConsoleWindow() returned NULL");
bool isWindows10NewConsole = false;
COORD pos = getCursorPos(conout);
setCursorPos(conout, { 1, 0 });
{
COORD posA = getCursorPos(conout);
SendMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_MARK, 0);
COORD posB = getCursorPos(conout);
isWindows10NewConsole = !memcmp(&posA, &posB, sizeof(posA));
SendMessage(hwnd, WM_CHAR, 27, 0x00010001); // Send ESCAPE
}
setCursorPos(conout, pos);
if (isWindows10NewConsole) {
printf("New Windows 10 console\n");
} else {
printf("Legacy console\n");
}
return 0;
}

0
misc/MoveConsoleWindow.cc Executable file → Normal file
View File

View File

@ -1,74 +0,0 @@
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <wchar.h>
#include "TestUtil.cc"
static void queryCurrentConsoleFont(HANDLE conout, BOOL max) {
CONSOLE_FONT_INFO info = {0};
if (!GetCurrentConsoleFont(conout, max, &info)) {
cprintf(L"GetCurrentConsoleFont call failed\n");
} else {
cprintf(L"info(max=%d): nFont=%u dwFontSize=(%d,%d)\n",
max, static_cast<unsigned>(info.nFont),
info.dwFontSize.X, info.dwFontSize.Y);
}
}
static void queryCurrentConsoleFontEx(HANDLE conout, BOOL max) {
CONSOLE_FONT_INFOEX infoex = {0};
infoex.cbSize = sizeof(infoex);
if (!GetCurrentConsoleFontEx(conout, max, &infoex)) {
cprintf(L"GetCurrentConsoleFontEx call failed\n");
} else {
wchar_t faceName[LF_FACESIZE + 1];
memcpy(faceName, infoex.FaceName, sizeof(faceName));
faceName[LF_FACESIZE] = L'\0';
cprintf(L"infoex(max=%d): nFont=%u dwFontSize=(%d,%d) "
L"FontFamily=0x%x FontWeight=%u "
L"FaceName=\"%ls\"",
max, static_cast<unsigned>(infoex.nFont),
infoex.dwFontSize.X, infoex.dwFontSize.Y,
infoex.FontFamily, infoex.FontWeight,
faceName);
cprintf(L" (");
for (int i = 0; i < LF_FACESIZE; ++i) {
if (i > 0) {
cprintf(L" ");
}
cprintf(L"%X", infoex.FaceName[i]);
if (infoex.FaceName[i] == L'\0') {
break;
}
}
cprintf(L")\n");
}
}
int main() {
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
queryCurrentConsoleFont(conout, FALSE);
queryCurrentConsoleFont(conout, TRUE);
queryCurrentConsoleFontEx(conout, FALSE);
queryCurrentConsoleFontEx(conout, TRUE);
const COORD largest = GetLargestConsoleWindowSize(conout);
cprintf(L"largestConsoleWindowSize=(%d,%d)\n", largest.X, largest.Y);
for (int i = 0;; ++i) {
const COORD size = GetConsoleFontSize(conout, i);
if (size.X == 0 && size.Y == 0) {
break;
}
cprintf(L"font %d: %dx%d\n", i, size.X, size.Y);
}
HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
FARPROC proc = GetProcAddress(kernel32, "GetNumberOfConsoleFonts");
if (proc == NULL) {
cprintf(L"Could not get address of GetNumberOfConsoleFonts\n");
} else {
cprintf(L"GetNumberOfConsoleFonts returned %d\n",
reinterpret_cast<int WINAPI(*)(HANDLE)>(proc)(conout));
}
cprintf(L"InputCP=%u OutputCP=%u", GetConsoleCP(), GetConsoleOutputCP());
return 0;
}

0
misc/SetBufferSize.cc Executable file → Normal file
View File

0
misc/SetWindowRect.cc Executable file → Normal file
View File

View File

@ -161,3 +161,12 @@ static std::string narrowString(const std::wstring &input)
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;
}