Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 06c1292

Browse files
kbleeskasal
authored andcommitted
Warn if the Windows console font doesn't support Unicode
Unicode console output won't display correctly with default settings because the default console font ("Terminal") only supports the system's OEM charset. Unfortunately, this is a user specific setting, so it cannot be easily fixed by e.g. some registry tricks in the setup program. This change prints a warning on exit if console output contained non-ascii characters and the console font is supposedly not a TrueType font (which usually have decent Unicode support). Signed-off-by: Karsten Blees <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 38b9bfd commit 06c1292

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

compat/winansi.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "../git-compat-util.h"
66
#include <malloc.h>
7+
#include <wingdi.h>
8+
#include <winreg.h>
79

810
/*
911
Functions to be wrapped:
@@ -26,6 +28,54 @@ static WORD plain_attr;
2628
static WORD attr;
2729
static int negative;
2830
static FILE *last_stream = NULL;
31+
static int non_ascii_used = 0;
32+
33+
typedef struct _CONSOLE_FONT_INFOEX {
34+
ULONG cbSize;
35+
DWORD nFont;
36+
COORD dwFontSize;
37+
UINT FontFamily;
38+
UINT FontWeight;
39+
WCHAR FaceName[LF_FACESIZE];
40+
} CONSOLE_FONT_INFOEX, *PCONSOLE_FONT_INFOEX;
41+
42+
typedef BOOL (WINAPI *PGETCURRENTCONSOLEFONTEX)(HANDLE, BOOL,
43+
PCONSOLE_FONT_INFOEX);
44+
45+
static void warn_if_raster_font(void)
46+
{
47+
DWORD fontFamily = 0;
48+
PGETCURRENTCONSOLEFONTEX pGetCurrentConsoleFontEx;
49+
50+
/* don't bother if output was ascii only */
51+
if (!non_ascii_used)
52+
return;
53+
54+
/* GetCurrentConsoleFontEx is available since Vista */
55+
pGetCurrentConsoleFontEx = GetProcAddress(GetModuleHandle("kernel32.dll"),
56+
"GetCurrentConsoleFontEx");
57+
if (pGetCurrentConsoleFontEx) {
58+
CONSOLE_FONT_INFOEX cfi;
59+
cfi.cbSize = sizeof(cfi);
60+
if (pGetCurrentConsoleFontEx(console, 0, &cfi))
61+
fontFamily = cfi.FontFamily;
62+
} else {
63+
/* pre-Vista: check default console font in registry */
64+
HKEY hkey;
65+
if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CURRENT_USER, "Console", 0,
66+
KEY_READ, &hkey)) {
67+
DWORD size = sizeof(fontFamily);
68+
RegQueryValueExA(hkey, "FontFamily", NULL, NULL,
69+
(LPVOID) &fontFamily, &size);
70+
RegCloseKey(hkey);
71+
}
72+
}
73+
74+
if (!(fontFamily & TMPF_TRUETYPE))
75+
warning("Your console font probably doesn\'t support "
76+
"Unicode. If you experience strange characters in the output, "
77+
"consider switching to a TrueType font such as Lucida Console!");
78+
}
2979

3080
static int is_console(FILE *stream)
3181
{
@@ -54,6 +104,8 @@ static int is_console(FILE *stream)
54104
attr = plain_attr = sbi.wAttributes;
55105
negative = 0;
56106
initialized = 1;
107+
/* check console font on exit */
108+
atexit(warn_if_raster_font);
57109
}
58110

59111
console = hcon;
@@ -69,6 +121,10 @@ static int write_console(const char *str, size_t len)
69121

70122
WriteConsoleW(console, wbuf, wlen, NULL, NULL);
71123

124+
/* remember if non-ascii characters are printed */
125+
if (wlen != len)
126+
non_ascii_used = 1;
127+
72128
/* return original (utf-8 encoded) length */
73129
return len;
74130
}

0 commit comments

Comments
 (0)