Subject: Emacs-CVS Win32 MS-IME will lost some input
From: Yao <[email-masked]>
To: [email-masked]
Date: Thu, 13 Nov 2008 22:02:43 -0800 (PST)
Newsgroups: gnu.emacs.bug
List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs.gnu.org>

Hi

I am using japanese input method .If I input continuously I will lost
some word.
Because Emacs handles  WM_IME_CHAR.When first WM_IME_CHAR arrived  It
read whole string and ignore the other WM_IME_CHAR messages.So it use
a ignore_ime_char flag.

The flag is reseted after a WM_IME_ENDCOMPOSITION message.I think when
I input continuously the IME haven't send some WM_IME_ENDCOMPOSITION
message, Because it has not ENDed.

And the composition window is not followed the cursor.

This is my patch.
------BEGIN-----
Index: src/w32fns.c
===================================================================
RCS file: /sources/emacs/emacs/src/w32fns.c,v
retrieving revision 1.349
diff -U 3 -r1.349 w32fns.c
--- src/w32fns.c	30 Oct 2008 01:27:07 -0000	1.349
+++ src/w32fns.c	14 Nov 2008 05:49:34 -0000
@@ -255,6 +255,9 @@
 typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN
DWORD flags);
 typedef BOOL (WINAPI * GetMonitorInfo_Proc)
   (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
+typedef HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND hWnd, IN HIMC
himc);
+typedef HWND (WINAPI * ImmSetCompositionWindow_Proc)
+  (IN HIMC himc, IN LPCOMPOSITIONFORM compform);

 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
 ClipboardSequence_Proc clipboard_sequence_fn = NULL;
@@ -262,11 +265,11 @@
 ImmGetContext_Proc get_ime_context_fn = NULL;
 MonitorFromPoint_Proc monitor_from_point_fn = NULL;
 GetMonitorInfo_Proc get_monitor_info_fn = NULL;
+ImmReleaseContext_Proc release_ime_context_fn = NULL;
+ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;

 extern AppendMenuW_Proc unicode_append_menu;

-/* Flag to selectively ignore WM_IME_CHAR messages.  */
-static int ignore_ime_char = 0;

 /* W95 mousewheel handler */
 unsigned int msh_mousewheel = 0;
@@ -3134,15 +3137,14 @@
       }
       break;

-    case WM_IME_CHAR:
+    case WM_IME_COMPOSITION:
       /* If we can't get the IME result as unicode, use default
processing,
          which will at least allow characters decodable in the system
locale
          get through.  */
       if (!get_composition_string_fn)
         goto dflt;
-
-      else if (!ignore_ime_char)
-        {
+	  if (lParam & GCS_RESULTSTR)
+		{
           wchar_t * buffer;
           int size, i;
           W32Msg wmsg;
@@ -3159,14 +3161,47 @@
               my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer
[i],
                            lParam);
             }
-          /* We output the whole string above, so ignore following
ones
-             until we are notified of the end of composition.  */
-          ignore_ime_char = 1;
+		  release_ime_context_fn (hwnd, context);
         }
+	  else
+		{
+		  goto dflt;
+		}
       break;
-
+	case WM_IME_STARTCOMPOSITION:
+      if (!set_ime_composition_window_fn)
+        goto dflt;
+	  HIMC context = get_ime_context_fn (hwnd);
+	  if (!context)
+		{
+		  break;
+		}
+	  f = x_window_to_frame (dpyinfo, hwnd);
+	  COMPOSITIONFORM compform;
+	  struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
+	  compform.dwStyle = CFS_RECT;
+	  compform.ptCurrentPos.x =	WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w-
>phys_cursor.x);
+
+	  compform.ptCurrentPos.y = WINDOW_TO_FRAME_PIXEL_Y (w, w-
>phys_cursor.y);
+
+	  compform.rcArea.left = (WINDOW_BOX_LEFT_EDGE_X (w)
+							  + WINDOW_LEFT_MARGIN_WIDTH (w)
+							  + WINDOW_LEFT_FRINGE_WIDTH (w));
+
+	  compform.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
+							 + WINDOW_HEADER_LINE_HEIGHT (w));
+
+	  compform.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
+							   - WINDOW_RIGHT_MARGIN_WIDTH (w)
+							   - WINDOW_RIGHT_FRINGE_WIDTH (w));
+
+	  compform.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
+								- WINDOW_MODE_LINE_HEIGHT (w));
+	  set_ime_composition_window_fn(context, &compform);
+	  release_ime_context_fn (hwnd, context);
+
+	  break;
     case WM_IME_ENDCOMPOSITION:
-      ignore_ime_char = 0;
       goto dflt;

       /* Simulate middle mouse button events when left and right
buttons
@@ -7258,6 +7293,10 @@
       GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
     get_ime_context_fn = (ImmGetContext_Proc)
       GetProcAddress (imm32_lib, "ImmGetContext");
+	release_ime_context_fn = (ImmReleaseContext_Proc)
+	  GetProcAddress (imm32_lib, "ImmReleaseContext");
+	set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
+	  GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
   }
   DEFVAR_INT ("w32-ansi-code-page",
 	      &w32_ansi_code_page,
Index: src/w32term.c
===================================================================
RCS file: /sources/emacs/emacs/src/w32term.c,v
retrieving revision 1.309
diff -U 3 -r1.309 w32term.c
--- src/w32term.c	12 Nov 2008 15:51:11 -0000	1.309
+++ src/w32term.c	14 Nov 2008 05:53:00 -0000
@@ -33,6 +33,7 @@
 #include <errno.h>
 #include <setjmp.h>
 #include <sys/stat.h>
+#include <imm.h>

 #include "charset.h"
 #include "character.h"
@@ -5061,7 +5062,11 @@
 	{
 	  struct frame *f = XFRAME (WINDOW_FRAME (w));
 	  HWND hwnd = FRAME_W32_WINDOW (f);
-
+ 	  if (f == FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame)
+		{
+		  PostMessage (hwnd,
+					   WM_IME_STARTCOMPOSITION, 0, 0);
+		}
 	  w32_system_caret_x
 	    = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 	  w32_system_caret_y
------END--------