From 765e7d349e1d9b20fda640672a2e6864db4d8b08 Mon Sep 17 00:00:00 2001 From: michi_cc Date: Mon, 5 Aug 2013 20:36:55 +0000 Subject: (svn r25676) -Fix: [Win32] The ANSI code page is not UTF-8 for non-Unicode builds. --- src/fontdetection.cpp | 65 ++++++++++++----------------------------- src/os/windows/crashlog_win.cpp | 8 ++--- src/os/windows/win32.cpp | 49 ++++++++++++------------------- src/os/windows/win32.h | 11 ++----- 4 files changed, 42 insertions(+), 91 deletions(-) diff --git a/src/fontdetection.cpp b/src/fontdetection.cpp index 2a847933f..82c4f354f 100644 --- a/src/fontdetection.cpp +++ b/src/fontdetection.cpp @@ -42,26 +42,19 @@ extern FT_Library _library; * filename into something that isn't UTF-8 but represents the Unicode file * name. This is the short DOS 8.3 format. This does not contain any * characters that fopen doesn't support. - * @param long_path the path in UTF-8. + * @param long_path the path in system encoding. * @return the short path in ANSI (ASCII). */ -char *GetShortPath(const char *long_path) +const char *GetShortPath(const TCHAR *long_path) { static char short_path[MAX_PATH]; #ifdef UNICODE - /* The non-unicode GetShortPath doesn't support UTF-8..., - * so convert the path to wide chars, then get the short - * path and convert it back again. */ - wchar_t long_path_w[MAX_PATH]; - MultiByteToWideChar(CP_UTF8, 0, long_path, -1, long_path_w, MAX_PATH); - - wchar_t short_path_w[MAX_PATH]; - GetShortPathNameW(long_path_w, short_path_w, MAX_PATH); - - WideCharToMultiByte(CP_ACP, 0, short_path_w, -1, short_path, MAX_PATH, NULL, NULL); + WCHAR short_path_w[MAX_PATH]; + GetShortPathName(long_path, short_path_w, lengthof(short_path_w)); + WideCharToMultiByte(CP_ACP, 0, short_path_w, -1, short_path, lengthof(short_path), NULL, NULL); #else /* Technically not needed, but do it for consistency. */ - GetShortPathNameA(long_path, short_path, MAX_PATH); + GetShortPathName(long_path, short_path, lengthof(short_path)); #endif return short_path; } @@ -82,9 +75,10 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) HKEY hKey; LONG ret; TCHAR vbuffer[MAX_PATH], dbuffer[256]; - TCHAR *font_namep; - char *font_path; + TCHAR *pathbuf; + const char *font_path; uint index; + size_t path_len; /* On windows NT (2000, NT3.5, XP, etc.) the fonts are stored in the * "Windows NT" key, on Windows 9x in the Windows key. To save us having @@ -97,15 +91,8 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) return err; } - /* For Unicode we need some conversion between widechar and - * normal char to match the data returned by RegEnumValue, - * otherwise just use parameter */ -#if defined(UNICODE) - font_namep = MallocT(MAX_PATH); - MB_TO_WIDE_BUFFER(font_name, font_namep, MAX_PATH * sizeof(TCHAR)); -#else - font_namep = const_cast(font_name); // only cast because in unicode pointer is not const -#endif + /* Convert font name to file system encoding. */ + TCHAR *font_namep = _tcsdup(OTTD2FS(font_name)); for (index = 0;; index++) { TCHAR *s; @@ -142,23 +129,13 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) /* Some fonts are contained in .ttc files, TrueType Collection fonts. These * contain multiple fonts inside this single file. GetFontData however * returns the whole file, so we need to check each font inside to get the - * proper font. - * Also note that FreeType does not support UNICODE filenames! */ -#if defined(UNICODE) - /* We need a cast here back from wide because FreeType doesn't support - * widechar filenames. Just use the buffer we allocated before for the - * font_name search */ - font_path = (char*)font_namep; - WIDE_TO_MB_BUFFER(vbuffer, font_path, MAX_PATH * sizeof(TCHAR)); -#else - font_path = vbuffer; -#endif - - ttd_strlcat(font_path, "\\", MAX_PATH * sizeof(TCHAR)); - ttd_strlcat(font_path, WIDE_TO_MB(dbuffer), MAX_PATH * sizeof(TCHAR)); + * proper font. */ + path_len = _tcslen(vbuffer) + _tcslen(dbuffer) + 2; // '\' and terminating nul. + pathbuf = AllocaM(TCHAR, path_len); + _sntprintf(pathbuf, path_len, _T("%s\\%s"), vbuffer, dbuffer); - /* Convert the path into something that FreeType understands */ - font_path = GetShortPath(font_path); + /* Convert the path into something that FreeType understands. */ + font_path = GetShortPath(pathbuf); index = 0; do { @@ -175,9 +152,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) folder_error: registry_no_font_found: -#if defined(UNICODE) free(font_namep); -#endif RegCloseKey(hKey); return err; } @@ -338,11 +313,7 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT } char font_name[MAX_PATH]; -#if defined(UNICODE) - WIDE_TO_MB_BUFFER((const TCHAR*)logfont->elfFullName, font_name, lengthof(font_name)); -#else - strecpy(font_name, (const TCHAR*)logfont->elfFullName, lastof(font_name)); -#endif + convert_from_fs((const TCHAR *)logfont->elfFullName, font_name, lengthof(font_name)); /* Add english name after font name */ const char *english_name = GetEnglishFontName(logfont); diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index 646b06f2b..44edd72f1 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -197,7 +197,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod) GetModuleFileName(mod, buffer, MAX_PATH); GetFileInfo(&dfi, buffer); output += seprintf(output, last, " %-20s handle: %p size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\n", - WIDE_TO_MB(buffer), + FS2OTTD(buffer), mod, dfi.size, dfi.crc32, @@ -621,11 +621,9 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA { switch (msg) { case WM_INITDIALOG: { -#if defined(UNICODE) /* We need to put the crash-log in a separate buffer because the default * buffer in MB_TO_WIDE is not large enough (512 chars) */ - wchar_t crash_msgW[lengthof(CrashLogWindows::current->crashlog)]; -#endif + TCHAR crash_msgW[lengthof(CrashLogWindows::current->crashlog)]; /* Convert unix -> dos newlines because the edit box only supports that properly :( */ const char *unix_nl = CrashLogWindows::current->crashlog; char dos_nl[lengthof(CrashLogWindows::current->crashlog)]; @@ -655,7 +653,7 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA } SetDlgItemText(wnd, 10, text); - SetDlgItemText(wnd, 11, MB_TO_WIDE_BUFFER(dos_nl, crash_msgW, lengthof(crash_msgW))); + SetDlgItemText(wnd, 11, convert_to_fs(dos_nl, crash_msgW, lengthof(crash_msgW))); SendDlgItemMessage(wnd, 11, WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), FALSE); SetWndSize(wnd, -1); } return TRUE; diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 314ff621a..d7ea4ab35 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -78,12 +78,12 @@ bool LoadLibraryList(Function proc[], const char *dll) void ShowOSErrorBox(const char *buf, bool system) { MyShowCursor(true); - MessageBox(GetActiveWindow(), MB_TO_WIDE(buf), _T("Error!"), MB_ICONSTOP); + MessageBox(GetActiveWindow(), OTTD2FS(buf), _T("Error!"), MB_ICONSTOP); } void OSOpenBrowser(const char *url) { - ShellExecute(GetActiveWindow(), _T("open"), MB_TO_WIDE(url), NULL, NULL, SW_SHOWNORMAL); + ShellExecute(GetActiveWindow(), _T("open"), OTTD2FS(url), NULL, NULL, SW_SHOWNORMAL); } /* Code below for windows version of opendir/readdir/closedir copied and @@ -371,12 +371,10 @@ static INT_PTR CALLBACK HelpDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARAM *q++ = *p++; } *q = '\0'; -#if defined(UNICODE) /* We need to put the text in a separate buffer because the default - * buffer in MB_TO_WIDE might not be large enough (512 chars) */ - wchar_t help_msgW[8192]; -#endif - SetDlgItemText(wnd, 11, MB_TO_WIDE_BUFFER(help_msg, help_msgW, lengthof(help_msgW))); + * buffer in OTTD2FS might not be large enough (512 chars). */ + TCHAR help_msg_buf[8192]; + SetDlgItemText(wnd, 11, convert_to_fs(help_msg, help_msg_buf, lengthof(help_msg_buf))); SendDlgItemMessage(wnd, 11, WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), FALSE); } return TRUE; @@ -407,12 +405,10 @@ void ShowInfo(const char *str) _help_msg = str; DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(101), NULL, HelpDialogFunc); } else { -#if defined(UNICODE) /* We need to put the text in a separate buffer because the default - * buffer in MB_TO_WIDE might not be large enough (512 chars) */ - wchar_t help_msgW[8192]; -#endif - MessageBox(GetActiveWindow(), MB_TO_WIDE_BUFFER(str, help_msgW, lengthof(help_msgW)), _T("OpenTTD"), MB_ICONINFORMATION | MB_OK); + * buffer in OTTD2FS might not be large enough (512 chars). */ + TCHAR help_msg_buf[8192]; + MessageBox(GetActiveWindow(), convert_to_fs(str, help_msg_buf, lengthof(help_msg_buf)), _T("OpenTTD"), MB_ICONINFORMATION | MB_OK); } MyShowCursor(old); } @@ -426,24 +422,18 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi { int argc; char *argv[64]; // max 64 command line arguments - char *cmdline; CrashLog::InitialiseCrashLog(); -#if defined(UNICODE) - -#if !defined(WINCE) +#if defined(UNICODE) && !defined(WINCE) /* Check if a win9x user started the win32 version */ if (HasBit(GetVersion(), 31)) usererror("This version of OpenTTD doesn't run on windows 95/98/ME.\nPlease download the win9x binary and try again."); #endif - /* For UNICODE we need to convert the commandline to char* _AND_ - * save it because argv[] points into this buffer and thus needs to - * be available between subsequent calls to FS2OTTD() */ - char cmdlinebuf[MAX_PATH]; -#endif /* UNICODE */ - - cmdline = WIDE_TO_MB_BUFFER(GetCommandLine(), cmdlinebuf, lengthof(cmdlinebuf)); + /* Convert the command line to UTF-8. We need a dedicated buffer + * for this because argv[] points into this buffer and this needs to + * be available between subsequent calls to FS2OTTD(). */ + char *cmdline = strdup(FS2OTTD(GetCommandLine())); #if defined(_DEBUG) CreateConsole(); @@ -459,6 +449,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi argc = ParseCommandLine(cmdline, argv, lengthof(argv)); openttd_main(argc, argv); + free(cmdline); return 0; } @@ -486,12 +477,10 @@ char *getcwd(char *buf, size_t size) /* GetModuleFileName returns dir with file, so remove everything behind latest '\\' */ char *p = strrchr(buf, '\\'); if (p != NULL) *p = '\0'; -#elif defined(UNICODE) +#else TCHAR path[MAX_PATH]; GetCurrentDirectory(MAX_PATH - 1, path); convert_from_fs(path, buf, size); -#else - GetCurrentDirectory(size, buf); #endif return buf; } @@ -503,7 +492,7 @@ void DetermineBasePaths(const char *exe) TCHAR path[MAX_PATH]; #ifdef WITH_PERSONAL_DIR if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) { - strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(tmp)); + strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, MAX_PATH); ttd_strlcat(tmp, PERSONAL_DIR, MAX_PATH); AppendPathSeparator(tmp, MAX_PATH); @@ -513,7 +502,7 @@ void DetermineBasePaths(const char *exe) } if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) { - strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(tmp)); + strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, MAX_PATH); ttd_strlcat(tmp, PERSONAL_DIR, MAX_PATH); AppendPathSeparator(tmp, MAX_PATH); @@ -536,12 +525,12 @@ void DetermineBasePaths(const char *exe) _searchpaths[SP_BINARY_DIR] = NULL; } else { TCHAR exec_dir[MAX_PATH]; - _tcsncpy(path, MB_TO_WIDE_BUFFER(exe, path, lengthof(path)), lengthof(path)); + _tcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path)); if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, NULL)) { DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError()); _searchpaths[SP_BINARY_DIR] = NULL; } else { - strecpy(tmp, WIDE_TO_MB_BUFFER(exec_dir, tmp, lengthof(tmp)), lastof(tmp)); + strecpy(tmp, convert_from_fs(exec_dir, tmp, lengthof(tmp)), lastof(tmp)); char *s = strrchr(tmp, PATHSEPCHAR); *(s + 1) = '\0'; _searchpaths[SP_BINARY_DIR] = strdup(tmp); diff --git a/src/os/windows/win32.h b/src/os/windows/win32.h index f4b03d970..45bcff10a 100644 --- a/src/os/windows/win32.h +++ b/src/os/windows/win32.h @@ -23,21 +23,14 @@ TCHAR *convert_to_fs(const char *name, TCHAR *utf16_buf, size_t buflen, bool con /* Function shortcuts for UTF-8 <> UNICODE conversion. When unicode is not * defined these macros return the string passed to them, with UNICODE - * they return a pointer to the converted string. The only difference between - * XX_TO_YY and XX_TO_YY_BUFFER is that with the buffer variant you can - * specify where to put the converted string (and how long it can be). Without - * the buffer and internal buffer is used, of max 512 characters */ + * they return a pointer to the converted string. These functions use an + * internal buffer of max 512 characters. */ #if defined(UNICODE) # define MB_TO_WIDE(str) OTTD2FS(str) -# define MB_TO_WIDE_BUFFER(str, buffer, buflen) convert_to_fs(str, buffer, buflen) # define WIDE_TO_MB(str) FS2OTTD(str) -# define WIDE_TO_MB_BUFFER(str, buffer, buflen) convert_from_fs(str, buffer, buflen) #else -extern uint _codepage; // local code-page in the system @see win32_v.cpp:WM_INPUTLANGCHANGE # define MB_TO_WIDE(str) (str) -# define MB_TO_WIDE_BUFFER(str, buffer, buflen) (str) # define WIDE_TO_MB(str) (str) -# define WIDE_TO_MB_BUFFER(str, buffer, buflen) (str) #endif HRESULT OTTDSHGetFolderPath(HWND, int, HANDLE, DWORD, LPTSTR); -- cgit v1.2.3-54-g00ecf