summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2013-08-05 20:36:43 +0000
committermichi_cc <michi_cc@openttd.org>2013-08-05 20:36:43 +0000
commite37968aadd8c14d15d49b90754a69126bdf674e7 (patch)
tree2f7e7260d333a36554fd33bf8221f475a98b1e2e
parentfdc436b531a36264d6f2ad8d4ae10170a8c281a8 (diff)
downloadopenttd-e37968aadd8c14d15d49b90754a69126bdf674e7.tar.xz
(svn r25673) -Fix: [Win32] Use the right code page for converting ANSI strings into UTF-8 for non-Unicode builds. And don't crap out on DBCS code pages either.
-rw-r--r--src/os/windows/win32.cpp90
-rw-r--r--src/os/windows/win32.h4
-rw-r--r--src/video/win32_v.cpp14
3 files changed, 36 insertions, 72 deletions
diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp
index 30c259a64..37d402ae2 100644
--- a/src/os/windows/win32.cpp
+++ b/src/os/windows/win32.cpp
@@ -428,10 +428,6 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
char *argv[64]; // max 64 command line arguments
char *cmdline;
-#if !defined(UNICODE)
- _codepage = GetACP(); // get system codepage as some kind of a default
-#endif /* UNICODE */
-
CrashLog::InitialiseCrashLog();
#if defined(UNICODE)
@@ -567,11 +563,11 @@ bool GetClipboardContents(char *buffer, size_t buff_len)
cbuf = GetClipboardData(CF_UNICODETEXT);
ptr = (const char*)GlobalLock(cbuf);
- const char *ret = convert_from_fs((const wchar_t*)ptr, buffer, buff_len);
+ int out_len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)ptr, -1, buffer, (int)buff_len, NULL, NULL);
GlobalUnlock(cbuf);
CloseClipboard();
- if (*ret == '\0') return false;
+ if (out_len == 0) return false;
#if !defined(UNICODE)
} else if (IsClipboardFormatAvailable(CF_TEXT)) {
OpenClipboard(NULL);
@@ -613,26 +609,7 @@ void CSleep(int milliseconds)
const char *FS2OTTD(const TCHAR *name)
{
static char utf8_buf[512];
-#if defined(UNICODE)
return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
-#else
- char *s = utf8_buf;
-
- for (; *name != '\0'; name++) {
- wchar_t w;
- int len = MultiByteToWideChar(_codepage, 0, name, 1, &w, 1);
- if (len != 1) {
- DEBUG(misc, 0, "[utf8] M2W error converting '%c'. Errno %lu", *name, GetLastError());
- continue;
- }
-
- if (s + Utf8CharLen(w) >= lastof(utf8_buf)) break;
- s += Utf8Encode(s, w);
- }
-
- *s = '\0';
- return utf8_buf;
-#endif /* UNICODE */
}
/**
@@ -645,33 +622,11 @@ const char *FS2OTTD(const TCHAR *name)
* this function. So if the value is needed for anything else, use convert_from_fs
* @param name pointer to a valid string that will be converted (UTF8)
* @return pointer to the converted string; if failed string is of zero-length
- * @see the current code-page comes from video\win32_v.cpp, event-notification
- * WM_INPUTLANGCHANGE
*/
const TCHAR *OTTD2FS(const char *name)
{
static TCHAR system_buf[512];
-#if defined(UNICODE)
return convert_to_fs(name, system_buf, lengthof(system_buf));
-#else
- char *s = system_buf;
-
- for (WChar c; (c = Utf8Consume(&name)) != '\0';) {
- if (s >= lastof(system_buf)) break;
-
- char mb;
- int len = WideCharToMultiByte(_codepage, 0, (wchar_t*)&c, 1, &mb, 1, NULL, NULL);
- if (len != 1) {
- DEBUG(misc, 0, "[utf8] W2M error converting '0x%X'. Errno %lu", c, GetLastError());
- continue;
- }
-
- *s++ = mb;
- }
-
- *s = '\0';
- return system_buf;
-#endif /* UNICODE */
}
@@ -683,14 +638,26 @@ const TCHAR *OTTD2FS(const char *name)
* @param buflen length in characters of the receiving buffer
* @return pointer to utf8_buf. If conversion fails the string is of zero-length
*/
-char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
+char *convert_from_fs(const TCHAR *name, char *utf8_buf, size_t buflen)
{
- int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, (int)buflen, NULL, NULL);
- if (len == 0) {
- DEBUG(misc, 0, "[utf8] W2M error converting wide-string. Errno %lu", GetLastError());
+#if defined(UNICODE)
+ const WCHAR *wide_buf = name;
+#else
+ /* Convert string from the local codepage to UTF-16. */
+ int wide_len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
+ if (wide_len == 0) {
utf8_buf[0] = '\0';
+ return utf8_buf;
}
+ WCHAR *wide_buf = AllocaM(WCHAR, wide_len);
+ MultiByteToWideChar(CP_ACP, 0, name, -1, wide_buf, wide_len);
+#endif
+
+ /* Convert UTF-16 string to UTF-8. */
+ int len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, (int)buflen, NULL, NULL);
+ if (len == 0) utf8_buf[0] = '\0';
+
return utf8_buf;
}
@@ -704,15 +671,26 @@ char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
* @param buflen length in wide characters of the receiving buffer
* @return pointer to utf16_buf. If conversion fails the string is of zero-length
*/
-wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen)
+TCHAR *convert_to_fs(const char *name, TCHAR *system_buf, size_t buflen)
{
- int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, utf16_buf, (int)buflen);
+#if defined(UNICODE)
+ int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, system_buf, (int)buflen);
+ if (len == 0) system_buf[0] = '\0';
+#else
+ int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
if (len == 0) {
- DEBUG(misc, 0, "[utf8] M2W error converting '%s'. Errno %lu", name, GetLastError());
- utf16_buf[0] = '\0';
+ system_buf[0] = '\0';
+ return system_buf;
}
- return utf16_buf;
+ WCHAR *wide_buf = AllocaM(WCHAR, len);
+ MultiByteToWideChar(CP_UTF8, 0, name, -1, wide_buf, len);
+
+ len = WideCharToMultiByte(CP_ACP, 0, wide_buf, len, system_buf, (int)buflen, NULL, NULL);
+ if (len == 0) system_buf[0] = '\0';
+#endif
+
+ return system_buf;
}
/**
diff --git a/src/os/windows/win32.h b/src/os/windows/win32.h
index 941d3ea84..d0eb371aa 100644
--- a/src/os/windows/win32.h
+++ b/src/os/windows/win32.h
@@ -18,8 +18,8 @@ bool MyShowCursor(bool show, bool toggle = false);
typedef void (*Function)(int);
bool LoadLibraryList(Function proc[], const char *dll);
-char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen);
-wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen);
+char *convert_from_fs(const TCHAR *name, char *utf8_buf, size_t buflen);
+TCHAR *convert_to_fs(const char *name, TCHAR *utf16_buf, size_t buflen);
/* Function shortcuts for UTF-8 <> UNICODE conversion. When unicode is not
* defined these macros return the string passed to them, with UNICODE
diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp
index fb50367fc..cdc3a6ec8 100644
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -50,9 +50,6 @@ bool _window_maximize;
uint _display_hz;
uint _fullscreen_bpp;
static Dimension _bck_resolution;
-#if !defined(UNICODE)
-uint _codepage;
-#endif
/** Whether the drawing is/may be done in a separate thread. */
static bool _draw_threaded;
@@ -605,17 +602,6 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
return 0;
}
-#if !defined(UNICODE)
- case WM_INPUTLANGCHANGE: {
- TCHAR locale[6];
- LCID lcid = GB(lParam, 0, 16);
-
- int len = GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, locale, lengthof(locale));
- if (len != 0) _codepage = _ttoi(locale);
- return 1;
- }
-#endif /* UNICODE */
-
case WM_DEADCHAR:
console = GB(lParam, 16, 8) == 41;
return 0;