From 672a29655c9b1e3583f13212ed0bfcea2a02f595 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 18 Feb 2002 19:47:05 +0000 Subject: [PATCH] experiment with win98 support for ime --- panda/src/wgldisplay/config_wgldisplay.cxx | 6 ++ panda/src/wgldisplay/config_wgldisplay.h | 1 + panda/src/wgldisplay/wglGraphicsWindow.cxx | 87 ++++++++++++++++------ panda/src/wgldisplay/wglGraphicsWindow.h | 1 + 4 files changed, 74 insertions(+), 21 deletions(-) diff --git a/panda/src/wgldisplay/config_wgldisplay.cxx b/panda/src/wgldisplay/config_wgldisplay.cxx index 5a99e79b21..f1f063073f 100644 --- a/panda/src/wgldisplay/config_wgldisplay.cxx +++ b/panda/src/wgldisplay/config_wgldisplay.cxx @@ -44,6 +44,12 @@ bool bResponsive_minimized_fullscreen_window = config_wgldisplay.GetBool("respon // will crab out WireGL. bool support_wiregl = config_wgldisplay.GetBool("support-wiregl", false); +// For now, set this true to use the IME correctly on Win2000, or +// false on Win98. This is temporary; once we have been able to +// verify that this distinction is actually necessary, we can replace +// this config variable with an actual OS detection. +bool ime_composition_w = config_wgldisplay.GetBool("ime-composition-w", true); + extern void AtExitFn(void); //////////////////////////////////////////////////////////////////// diff --git a/panda/src/wgldisplay/config_wgldisplay.h b/panda/src/wgldisplay/config_wgldisplay.h index a27049327c..e7a92d2f93 100644 --- a/panda/src/wgldisplay/config_wgldisplay.h +++ b/panda/src/wgldisplay/config_wgldisplay.h @@ -37,6 +37,7 @@ extern bool gl_sync_video; extern int gl_forced_pixfmt; extern bool bResponsive_minimized_fullscreen_window; extern bool support_wiregl; +extern bool ime_composition_w; extern EXPCL_PANDAGL void init_libwgldisplay(); diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 254a870307..0e0ab7296f 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -519,6 +519,20 @@ void wglGraphicsWindow::config() { ImmReleaseContext(_mwindow, hIMC); } + // Check the version of the OS we are running. If we are running + // win2000, we must use ImmGetCompositionStringW() to report the + // characters returned by the IME, since WM_CHAR and + // ImmGetCompositionStringA() both just return question marks. + // However, this function doesn't work for Win98; on this OS, we + // have to use ImmGetCompositionStringA() instead, which returns an + // encoded string in shift-jis (which we then have to decode). + + // For now, this is user-configurable, to allow testing of this code + // on both OS's. After we verify that truth of the above claim, we + // should base this decision on GetVersionEx() or maybe + // VerifyVersionInfo(). + _ime_composition_w = ime_composition_w; + hwnd_pandawin_map[_mwindow] = this; global_wglwinptr = NULL; // get rid of any reference to this obj @@ -1661,29 +1675,60 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { static const int max_ime_result = 128; static char ime_result[max_ime_result]; + + if (_ime_composition_w) { + // Since ImmGetCompositionStringA() doesn't seem to work + // for Win2000 (it always returns question mark + // characters), we have to use ImmGetCompositionStringW() + // on this OS. This is actually the easier of the two + // functions to use. + + DWORD result_size = + ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, + ime_result, max_ime_result); + + // Add this string into the text buffer of the application. - // There's a rumor that ImmGetCompositionStringW() doesn't - // work for Win95 or Win98; for these OS's we must use - // ImmGetCompositionStringA(). How does this affect the - // returning of multibyte characters? - DWORD result_size = - ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, - ime_result, max_ime_result); - ImmReleaseContext(hwnd, hIMC); - - // Add this string into the text buffer of the application. - - // ImmGetCompositionStringW() returns a string, but it's - // filled in with wstring data: every two characters defines a - // 16-bit unicode char. The docs aren't clear on the - // endianness of this. I guess it's safe to assume all Win32 - // machines are little-endian. - for (DWORD i = 0; i < result_size; i += 2) { - int result = - ((int)(unsigned char)ime_result[i + 1] << 8) | - (unsigned char)ime_result[i]; - _input_devices[0].keystroke(result); + // ImmGetCompositionStringW() returns a string, but it's + // filled in with wstring data: every two characters defines a + // 16-bit unicode char. The docs aren't clear on the + // endianness of this. I guess it's safe to assume all Win32 + // machines are little-endian. + for (DWORD i = 0; i < result_size; i += 2) { + int result = + ((int)(unsigned char)ime_result[i + 1] << 8) | + (unsigned char)ime_result[i]; + _input_devices[0].keystroke(result); + } + } else { + // On the other hand, ImmGetCompositionStringW() doesn't + // work on Win95 or Win98; for these OS's we must use + // ImmGetCompositionStringA(). + DWORD result_size = + ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, + ime_result, max_ime_result); + + // ImmGetCompositionStringA() returned an encoded ANSI + // string, which we now have to map to wide-character + // Unicode. + static const int max_wide_result = 128; + static wchar_t wide_result[max_wide_result]; + + int wide_size = + MultiByteToWideChar(CP_ACP, 0, + ime_result, result_size, + wide_result, max_wide_result); + if (wide_size == 0) { + PrintErrorMessage(LAST_ERROR); + } + for (int i = 0; i < wide_size; i++) { + _input_devices[0].keystroke(wide_result[i]); + } } + + ImmReleaseContext(hwnd, hIMC); + + } return 0; } diff --git a/panda/src/wgldisplay/wglGraphicsWindow.h b/panda/src/wgldisplay/wglGraphicsWindow.h index f2cea1c6db..8ec63b9392 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.h +++ b/panda/src/wgldisplay/wglGraphicsWindow.h @@ -131,6 +131,7 @@ private: bool _mouse_passive_motion_enabled; bool _mouse_entry_enabled; bool _ime_open; + bool _ime_composition_w; // vars for frames/sec meter DWORD _start_time;