From fb9bde8cca1ce1e2d20b353cddef6624ad94b20f Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 18 Feb 2002 23:49:36 +0000 Subject: [PATCH] copy tentative support for win98 ime from wgl to wdx --- panda/src/wdxdisplay/config_wdxdisplay.cxx | 6 ++ panda/src/wdxdisplay/config_wdxdisplay.h | 1 + panda/src/wdxdisplay/wdxGraphicsWindow.cxx | 85 ++++++++++++++++------ panda/src/wdxdisplay/wdxGraphicsWindow.h | 1 + panda/src/wgldisplay/wglGraphicsWindow.cxx | 4 +- 5 files changed, 73 insertions(+), 24 deletions(-) diff --git a/panda/src/wdxdisplay/config_wdxdisplay.cxx b/panda/src/wdxdisplay/config_wdxdisplay.cxx index 2be0d26284..7f6f47384b 100644 --- a/panda/src/wdxdisplay/config_wdxdisplay.cxx +++ b/panda/src/wdxdisplay/config_wdxdisplay.cxx @@ -33,6 +33,12 @@ bool dx_force_16bpp_zbuffer = config_wdxdisplay.GetBool("dx-force-16bpp-zbuffer" bool bResponsive_minimized_fullscreen_window = config_wdxdisplay.GetBool("responsive-minimized-fullscreen-window",false); bool dx_preserve_fpu_state = config_wdxdisplay.GetBool("dx-preserve-fpu-state", 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_wdxdisplay.GetBool("ime-composition-w", true); + extern void AtExitFn(void); //////////////////////////////////////////////////////////////////// diff --git a/panda/src/wdxdisplay/config_wdxdisplay.h b/panda/src/wdxdisplay/config_wdxdisplay.h index 20cc42c98a..6318005a4c 100644 --- a/panda/src/wdxdisplay/config_wdxdisplay.h +++ b/panda/src/wdxdisplay/config_wdxdisplay.h @@ -31,6 +31,7 @@ extern bool dx_preserve_fpu_state; extern Filename get_icon_filename(); extern Filename get_mono_cursor_filename(); extern Filename get_color_cursor_filename(); +extern bool ime_composition_w; extern EXPCL_PANDADX void init_libwdxdisplay(); diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx index f595cf5f51..b1050c48f5 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx @@ -375,29 +375,58 @@ 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() returns 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; } @@ -1215,6 +1244,20 @@ void wdxGraphicsWindow::config_window(wdxGraphicsWindowGroup *pParentGroup) { } } _dxgsg = DCAST(DXGraphicsStateGuardian, _gsg); + + // 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; } void wdxGraphicsWindow::finish_window_setup(void) { diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.h b/panda/src/wdxdisplay/wdxGraphicsWindow.h index dba4c4d33b..35d00b801c 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.h +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.h @@ -127,6 +127,7 @@ private: bool _mouse_passive_motion_enabled; bool _mouse_entry_enabled; bool _ime_open; + bool _ime_composition_w; bool _exiting_window; bool _window_inactive; bool _active_minimized_fullscreen; diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 0e0ab7296f..d4d4fe5f78 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -1708,7 +1708,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, ime_result, max_ime_result); - // ImmGetCompositionStringA() returned an encoded ANSI + // ImmGetCompositionStringA() returns an encoded ANSI // string, which we now have to map to wide-character // Unicode. static const int max_wide_result = 128; @@ -1727,8 +1727,6 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { } ImmReleaseContext(hwnd, hIMC); - - } return 0; }