+++ /dev/null
-#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;
-}