Bladeren bron

copy tentative support for win98 ime from wgl to wdx

David Rose 24 jaren geleden
bovenliggende
commit
fb9bde8cca

+ 6 - 0
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 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);
 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);
 extern void AtExitFn(void);
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
panda/src/wdxdisplay/config_wdxdisplay.h

@@ -31,6 +31,7 @@ extern bool dx_preserve_fpu_state;
 extern Filename get_icon_filename();
 extern Filename get_icon_filename();
 extern Filename get_mono_cursor_filename();
 extern Filename get_mono_cursor_filename();
 extern Filename get_color_cursor_filename();
 extern Filename get_color_cursor_filename();
+extern bool ime_composition_w;
 
 
 extern EXPCL_PANDADX void init_libwdxdisplay();
 extern EXPCL_PANDADX void init_libwdxdisplay();
 
 

+ 64 - 21
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 const int max_ime_result = 128;
           static char ime_result[max_ime_result];
           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;
         return 0;
       }
       }
@@ -1215,6 +1244,20 @@ void wdxGraphicsWindow::config_window(wdxGraphicsWindowGroup *pParentGroup) {
         }
         }
     }
     }
     _dxgsg = DCAST(DXGraphicsStateGuardian, _gsg);
     _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) {
 void wdxGraphicsWindow::finish_window_setup(void) {

+ 1 - 0
panda/src/wdxdisplay/wdxGraphicsWindow.h

@@ -127,6 +127,7 @@ private:
   bool              _mouse_passive_motion_enabled;
   bool              _mouse_passive_motion_enabled;
   bool              _mouse_entry_enabled;
   bool              _mouse_entry_enabled;
   bool              _ime_open;
   bool              _ime_open;
+  bool              _ime_composition_w;
   bool              _exiting_window;
   bool              _exiting_window;
   bool              _window_inactive;
   bool              _window_inactive;
   bool              _active_minimized_fullscreen;
   bool              _active_minimized_fullscreen;

+ 1 - 3
panda/src/wgldisplay/wglGraphicsWindow.cxx

@@ -1708,7 +1708,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
               ImmGetCompositionStringA(hIMC, GCS_RESULTSTR,
               ImmGetCompositionStringA(hIMC, GCS_RESULTSTR,
                                        ime_result, max_ime_result);
                                        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
             // string, which we now have to map to wide-character
             // Unicode.
             // Unicode.
             static const int max_wide_result = 128;
             static const int max_wide_result = 128;
@@ -1727,8 +1727,6 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
           }
           }
 
 
           ImmReleaseContext(hwnd, hIMC);
           ImmReleaseContext(hwnd, hIMC);
-            
-
         }
         }
         return 0;
         return 0;
       }
       }