[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[MD:5214] RECONVERSION



こばやしです。

Meadow-2.1にIMEの再変換機能を実装してみました。
機能
・regionを選択して、再変換キーを押したら、regionを再変換。
・regionが選択されていなければ、カーソル位置から前後
 forward-word一つ分を再変換。
・再変換キーを押した後は、escキーで中止した場合でも、バッファー
 は変更されたとみなされます。

再変換時にちょっともたつく感じになりますが、改良の余地はかな
りあると思います。
Meadowの作法に合っていない部分もあると思いますが、パッチを添
付いたします。

#emacs-CVS用IME-Patchにも取り込みました。
http://homepage3.nifty.com/y3tk/emacs.html#ime-patch
-- 
KOBAYASHI Yasuhiro <kobayays@xxxxxxxxxxxxxx>
Index: src/mw32ime.c
===================================================================
--- src/mw32ime.c	(revision 3345)
+++ src/mw32ime.c	(working copy)
@@ -23,6 +23,9 @@
 #include "config.h"
 #include "lisp.h"
 #include <imm.h>
+#ifdef RECONVERSION
+#include "buffer.h"
+#endif
 
 #ifdef HAVE_NTGUI
 #include "frame.h"
@@ -251,6 +254,145 @@
   return TRUE;
 }
 	  
+#ifdef RECONVERSION
+LRESULT
+mw32_get_ime_reconversion_length ()
+{
+  Lisp_Object str, start, end, point, marker;
+  LRESULT lResult = 0;
+  int len, pt, pt_byte;
+  char *lpstr;
+
+  pt = PT;
+  pt_byte = PT_BYTE;
+
+  if (!NILP (current_buffer->read_only))
+    return 0;
+
+  if (!NILP (current_buffer->mark_active))
+    {
+      point = Fmake_marker ();
+      set_marker_both (point, Qnil, PT, PT_BYTE);
+      marker = Fmake_marker ();
+      set_marker_both (marker,
+		       Qnil,
+		       marker_position (current_buffer->mark),
+		       marker_byte_position (current_buffer->mark));
+      start = marker_position (current_buffer->mark) < PT ? marker : point;
+      end = marker_position (current_buffer->mark) > PT ? marker : point;
+    }
+  else
+    {
+      start = Fmake_marker ();
+      Fforward_word (make_number (-1));
+      set_marker_both (start, Qnil, PT, PT_BYTE);
+      end = Fmake_marker ();
+      Fend_of_line (make_number (1));
+      set_marker_both (end, Qnil, PT, PT_BYTE);
+    }
+
+  str = Fbuffer_substring_no_properties (start, end);
+
+  MW32_ENCODE_TEXT(str, Vw32_system_coding_system, &lpstr, &len);
+  SET_PT_BOTH (pt, pt_byte);
+  
+  /* Return need size on reconverted string */
+  lResult = sizeof (RECONVERTSTRING) + len + 1;
+  return lResult;
+}
+
+
+BOOL
+mw32_get_ime_reconversion_string (hwnd, wParam, reconv)
+     HWND hwnd;
+     WPARAM wParam;
+     RECONVERTSTRING *reconv;
+{
+  HIMC hIMC;
+  int len, result;
+  char *lpstr;
+  Lisp_Object str, start, end, point, marker;
+  struct frame *f = SELECTED_FRAME ();
+
+  if (!NILP (current_buffer->mark_active))
+    {
+      point = Fmake_marker ();
+      set_marker_both (point, Qnil, PT, PT_BYTE);
+      marker = Fmake_marker ();
+      set_marker_both (marker,
+		       Qnil,
+		       marker_position (current_buffer->mark),
+		       marker_byte_position (current_buffer->mark));
+      start = marker_position (current_buffer->mark) < PT ? marker : point;
+      end = marker_position (current_buffer->mark) > PT ? marker : point;
+    }
+  else
+    {
+      start = Fmake_marker ();
+      Fforward_word (make_number (-1));
+      set_marker_both (start, Qnil, PT, PT_BYTE);
+      end = Fmake_marker ();
+      Fend_of_line (make_number (1));
+      set_marker_both (end, Qnil, PT, PT_BYTE);
+    }
+
+  str = Fbuffer_substring_no_properties (start, end);
+
+  MW32_ENCODE_TEXT(str, Vw32_system_coding_system, &lpstr, &len);
+  
+  Fgoto_char (start);
+  
+  hIMC = (ImmGetContextProc) (hwnd);
+  if (!hIMC)
+    return FALSE;
+  
+  /* Memories are reserved in advance. */
+  strcpy ((LPSTR) reconv + sizeof (RECONVERTSTRING), lpstr);
+  reconv->dwStrLen = len;
+  reconv->dwStrOffset = sizeof (RECONVERTSTRING);
+  reconv->dwTargetStrLen = len;
+  reconv->dwTargetStrOffset = 0;
+
+  /* Reconverted area is all of selected string. */
+  reconv->dwCompStrOffset = 0;
+  reconv->dwCompStrLen = len;
+  reconv->dwTargetStrOffset = 0;
+
+#if 0 /* Why not need for automatic adjustment? */
+  /* Automatically adjust RECONVERTSTRING if not selected. */
+  if (NILP (current_buffer->mark_active))
+    (ImmSetCompositionStringProc) (hIMC,
+				   SCS_QUERYRECONVERTSTRING,
+				   (LPCVOID) reconv,
+				   reconv->dwSize,
+				   NULL, 0 );
+#endif
+  
+  if ((ImmSetCompositionStringProc) (hIMC,
+				     SCS_SETRECONVERTSTRING,
+				     (LPCVOID) reconv,
+				     reconv->dwSize,
+				     NULL, 0))
+    {
+      {
+      /* Set the position of candidate list dialog. */
+	struct window *w = XWINDOW (f->selected_window);
+	mw32_set_ime_conv_window (hwnd,
+				  WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
+				  WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y));
+      }
+      /* Delete the selected area. */
+      Fdelete_region (start, end);
+      result = TRUE;
+    }
+  else
+    result = FALSE;
+  
+  (ImmReleaseContextProc) (hwnd, hIMC);
+  return result;
+}
+#endif /* RECONVERSION */
+
 void
 mw32_ime_control_init (void)
 {
Index: src/mw32term.h
===================================================================
--- src/mw32term.h	(revision 3345)
+++ src/mw32term.h	(working copy)
@@ -843,6 +843,46 @@
 #define IR_OPENCONVERT    0x120
 #define IR_CLOSECONVERT   0x122
 
+#ifdef RECONVERSION
+#ifndef WM_IME_REQUEST
+#define WM_IME_REQUEST                  0x288
+#endif
+#ifndef IMR_COMPOSITIONWINDOW
+#define IMR_COMPOSITIONWINDOW           0x0001
+#endif
+#ifndef IMR_CANDIDATEWINDOW
+#define IMR_CANDIDATEWINDOW             0x0002
+#endif
+#ifdef IMR_COMPOSITIONFONT
+#define IMR_COMPOSITIONFONT             0x0003
+#endif
+#ifndef IMR_RECONVERTSTRING
+#define IMR_RECONVERTSTRING             0x0004
+#endif
+#ifndef IMR_CONFIRMRECONVERTSTRING
+#define IMR_CONFIRMRECONVERTSTRING      0x0005
+#endif
+
+#ifndef RECONVERTSTRING
+typedef struct RECONVERTSTRING {
+  DWORD dwSize;
+  DWORD dwVersion;
+  DWORD dwStrLen;
+  DWORD dwStrOffset;
+  DWORD dwCompStrLen;
+  DWORD dwCompStrOffset;
+  DWORD dwTargetStrLen;
+  DWORD dwTargetStrOffset;
+} RECONVERTSTRING, *PRECONVERTSTRING;
+#endif
+#ifndef SCS_SETRECONVERTSTRING
+#define SCS_SETRECONVERTSTRING 0x00010000
+#endif
+#ifndef SCS_QUERYRECONVERTSTRING
+#define SCS_QUERYRECONVERTSTRING 0x00020000
+#endif
+#endif
+
 #define IDM_UNDO 100
 #ifdef W32_SCROLLBAR
 #define WM_EMACS_VSCROLL                           (WM_USER+2020)
Index: src/makefile.meadow.w32-in
===================================================================
--- src/makefile.meadow.w32-in	(revision 3345)
+++ src/makefile.meadow.w32-in	(working copy)
@@ -1566,6 +1566,7 @@
     $(SRC)/s/ms-w32.h \
     $(SRC)/m/intel386.h \
     $(SRC)/lisp.h \
+    $(SRC)/buffer.h \
     $(SRC)/frame.h \
     $(SRC)/window.h \
     $(SRC)/dispextern.h \
Index: src/mw32fns.c
===================================================================
--- src/mw32fns.c	(revision 3345)
+++ src/mw32fns.c	(working copy)
@@ -3524,6 +3524,26 @@
       }
     goto dflt;
 
+#ifdef RECONVERSION
+    case WM_IME_REQUEST:
+      if (wParam == IMR_RECONVERTSTRING)
+	{
+	  if (lParam)
+	    {
+	      extern LRESULT mw32_get_ime_reconversion_string (HWND hwnd,
+							      WPARAM wParam,
+							      RECONVERTSTRING* lParam);
+	      return mw32_get_ime_reconversion_string (hwnd, wParam,
+						      (RECONVERTSTRING*) lParam);
+	    }
+	  else
+	    {
+	      extern LRESULT mw32_get_ime_reconversion_length ();
+	      return mw32_get_ime_reconversion_length ();
+	    }
+	}
+      goto dflt;
+#endif
   case WM_IME_STARTCOMPOSITION:
     {
       struct window *w = XWINDOW (f->selected_window);