summaryrefslogtreecommitdiff
path: root/src/video
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2013-08-05 20:37:25 +0000
committermichi_cc <michi_cc@openttd.org>2013-08-05 20:37:25 +0000
commit0883cf76e34527f3bf4d8a19c6f68b655969798c (patch)
tree2626bc344a106a36aa31fca834a40c1bb74f9472 /src/video
parent64d2fc4d1e4124a55ccee8c4a4c6e43d1c2ae9fe (diff)
downloadopenttd-0883cf76e34527f3bf4d8a19c6f68b655969798c.tar.xz
(svn r25684) -Change: [Win32] Draw the composition string ourselves if possible.
Diffstat (limited to 'src/video')
-rw-r--r--src/video/win32_v.cpp71
1 files changed, 70 insertions, 1 deletions
diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp
index a6ca85c97..2e7b40902 100644
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -52,6 +52,9 @@ bool _window_maximize;
uint _display_hz;
uint _fullscreen_bpp;
static Dimension _bck_resolution;
+#if !defined(WINCE) || _WIN32_WCE >= 0x400
+DWORD _imm_props;
+#endif
/** Whether the drawing is/may be done in a separate thread. */
static bool _draw_threaded;
@@ -501,6 +504,12 @@ static LRESULT HandleCharMsg(uint keycode, WChar charcode)
}
#if !defined(WINCE) || _WIN32_WCE >= 0x400
+/** Should we draw the composition string ourself, i.e is this a normal IME? */
+static bool DrawIMECompositionString()
+{
+ return (_imm_props & IME_PROP_AT_CARET) && !(_imm_props & IME_PROP_SPECIAL_UI);
+}
+
/** Set position of the composition window to the caret position. */
static void SetCompositionPos(HWND hwnd)
{
@@ -571,12 +580,50 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam)
str[len / sizeof(TCHAR)] = '\0';
/* Transmit text to windowing system. */
- if (len > 0) HandleTextInput(FS2OTTD(str));
+ if (len > 0) {
+ HandleTextInput(NULL, true); // Clear marked string.
+ HandleTextInput(FS2OTTD(str));
+ }
SetCompositionPos(hwnd);
/* Don't pass the result string on to the default window proc. */
lParam &= ~(GCS_RESULTSTR | GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR);
}
+
+ if ((lParam & GCS_COMPSTR) && DrawIMECompositionString()) {
+ /* Read composition string from the IME. */
+ LONG len = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0); // Length is always in bytes, even in UNICODE build.
+ TCHAR *str = (TCHAR *)_alloca(len + sizeof(TCHAR));
+ len = ImmGetCompositionString(hIMC, GCS_COMPSTR, str, len);
+ str[len / sizeof(TCHAR)] = '\0';
+
+ if (len > 0) {
+ static char utf8_buf[1024];
+ convert_from_fs(str, utf8_buf, lengthof(utf8_buf));
+
+ /* Convert caret position from bytes in the input string to a position in the UTF-8 encoded string. */
+ LONG caret_bytes = ImmGetCompositionString(hIMC, GCS_CURSORPOS, NULL, 0);
+ const char *caret = utf8_buf;
+ for (const TCHAR *c = str; *c != '\0' && *caret != '\0' && caret_bytes > 0; c++, caret_bytes--) {
+ /* Skip DBCS lead bytes or leading surrogates. */
+#ifdef UNICODE
+ if (Utf16IsLeadSurrogate(*c)) {
+#else
+ if (IsDBCSLeadByte(*c)) {
+#endif
+ c++;
+ caret_bytes--;
+ }
+ Utf8Consume(&caret);
+ }
+
+ HandleTextInput(utf8_buf, true, caret);
+ } else {
+ HandleTextInput(NULL, true);
+ }
+
+ lParam &= ~(GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS | GCS_DELTASTART);
+ }
}
ImmReleaseContext(hwnd, hIMC);
@@ -589,10 +636,13 @@ static void CancelIMEComposition(HWND hwnd)
HIMC hIMC = ImmGetContext(hwnd);
if (hIMC != NULL) ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
ImmReleaseContext(hwnd, hIMC);
+ /* Clear any marked string from the current edit box. */
+ HandleTextInput(NULL, true);
}
#else
+static bool DrawIMECompositionString() { return false; }
static void SetCompositionPos(HWND hwnd) {}
static void SetCandidatePos(HWND hwnd) {}
static void CancelIMEComposition(HWND hwnd) {}
@@ -609,6 +659,9 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
case WM_CREATE:
SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
SetCompositionPos(hwnd);
+#if !defined(WINCE) || _WIN32_WCE >= 0x400
+ _imm_props = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY);
+#endif
break;
case WM_ENTERSIZEMOVE:
@@ -735,13 +788,29 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
}
#if !defined(WINCE) || _WIN32_WCE >= 0x400
+ case WM_INPUTLANGCHANGE:
+ _imm_props = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY);
+ break;
+
+ case WM_IME_SETCONTEXT:
+ /* Don't show the composition window if we draw the string ourself. */
+ if (DrawIMECompositionString()) lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
+ break;
+
case WM_IME_STARTCOMPOSITION:
SetCompositionPos(hwnd);
+ if (DrawIMECompositionString()) return 0;
break;
case WM_IME_COMPOSITION:
return HandleIMEComposition(hwnd, wParam, lParam);
+ case WM_IME_ENDCOMPOSITION:
+ /* Clear any pending composition string. */
+ HandleTextInput(NULL, true);
+ if (DrawIMECompositionString()) return 0;
+ break;
+
case WM_IME_NOTIFY:
if (wParam == IMN_OPENCANDIDATE) SetCandidatePos(hwnd);
break;