changeset 20700:28e4d872be76 draft

-Fix: [Win32] Handle DBCS characters correctly in the non-Unicode build.
author Michael Lutz <michi@icosahedron.de>
date Sun, 21 Jul 2013 22:36:48 +0200
parents d198fbc52efc
children db150a402c4d
files src/video/win32_v.cpp
diffstat 1 files changed, 45 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -434,9 +434,39 @@
 static LRESULT HandleCharMsg(uint keycode, WChar charcode)
 {
 #if !defined(UNICODE)
-	wchar_t w;
-	int len = MultiByteToWideChar(_codepage, 0, (char*)&charcode, 1, &w, 1);
-	charcode = len == 1 ? w : 0;
+	static char prev_char = 0;
+
+	char input[2] = {(char)charcode, 0};
+	int input_len = 1;
+
+	if (prev_char != 0) {
+		/* We stored a lead byte previously, combine it with this byte. */
+		input[0] = prev_char;
+		input[1] = (char)charcode;
+		input_len = 2;
+	} else if (IsDBCSLeadByte(charcode)) {
+		/* We got a lead byte, store and exit. */
+		prev_char = charcode;
+		return 0;
+	}
+	prev_char = 0;
+
+	wchar_t w[2]; // Can get up to two code points as a result.
+	int len = MultiByteToWideChar(CP_ACP, 0, input, input_len, w, 2);
+	switch (len) {
+		case 1: // Normal unicode character.
+			charcode = w[0];
+			break;
+
+		case 2: // Got an UTF-16 surrogate pair back.
+			charcode = Utf16DecodeSurrogate(w[0], w[1]);
+			break;
+
+		default: // Some kind of error.
+			DEBUG(driver, 1, "Invalid DBCS character sequence encountered, dropping input");
+			charcode = 0;
+			break;
+	}
 #else
 	static WChar prev_char = 0;
 
@@ -597,6 +627,18 @@
 			return 0;
 		}
 
+#if !defined(WINCE) || _WIN32_WCE >= 0x400
+#if !defined(UNICODE)
+		case WM_IME_CHAR:
+			if (GB(wParam, 8, 8) != 0) {
+				/* DBCS character, send lead byte first. */
+				HandleCharMsg(0, GB(wParam, 8, 8));
+			}
+			HandleCharMsg(0, GB(wParam, 0, 8));
+			return 0;
+#endif
+#endif
+
 		case WM_DEADCHAR:
 			console = GB(lParam, 16, 8) == 41;
 			return 0;