(Mdetail_text, minput_get_description, minput_get_commands)
[m17n/m17n-lib.git] / src / input.c
index a3ef38e..928da5b 100644 (file)
@@ -22,7 +22,7 @@
 
 /***en
     @addtogroup m17nInputMethod
-    @brief API for Input method
+    @brief API for Input method.
 
     An input method is an object to enable inputting various
     characters.  An input method is identified by a pair of symbols,
@@ -46,7 +46,7 @@
     An internal input method accepts an input key which is a symbol
     associated with an input event.  As there is no way for the @c
     m17n @c library to know how input events are represented in an
-    application program, a application programmer have to convert an
+    application program, an application programmer have to convert an
     input event to an input key by himself.  See the documentation of
     the function minput_event_to_key () for the detail.
 
@@ -56,9 +56,9 @@
     defined in an external resources (e.g. XIM of X Window System).
     For this kind of input methods, the symbol NAME must have a
     property of key @c Minput_driver, and the value must be a pointer
-    to an input method driver.  So, by preparing a proper driver, any
-    kind of input method can be treated in the framework of the @c
-    m17n @c library.
+    to an input method driver.  Therefore, by preparing a proper
+    driver, any kind of input method can be treated in the framework
+    of the @c m17n @c library.
 
     For convenience, the m17n-X library provides an input method
     driver that enables the input style of OverTheSpot for XIM, and
@@ -80,7 +80,7 @@
 /*=*/
 /***ja
     @addtogroup m17nInputMethod
-    @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI
+    @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
 
     ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£ÆþÎÏ¥á
     ¥½¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢¤³¤ÎÁȤˤè¤Ã
     µÁ¤¹¤ë¤³¤È¤¬¤Ç¤­¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢
     ¤ë¡£
 
-    ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿ÆþÎÏ¥­¡¼¤ò¼õ¤±¼è
-    ¤ë¡£ÆþÎÏ¥­¡¼¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È
-    ¤¬¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¡¦¥×¥í¥°¥é¥à¤Ç¤É¤Î¤è¤¦¤Ëɽ¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤë½Ñ
-    ¤ò»ý¤¿¤Ê¤¤¤Î¤Ç¡¢ÆþÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥­¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó
-    ¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô 
-    minput_event_to_key () ¤ÎÀâÌÀ¤ò»²¾È¡£
+    ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
+    ÎÏ¥­¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
+    ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤë½Ñ¤ò»ý¤¿¤Ê¤¤¤Î¤Ç¡¢ÆþÎÏ
+    ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥­¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç¹Ô
+    ¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤ÎÀâ
+    ÌÀ¤ò»²¾È¡£
 
     <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
 
     ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò¥­¡¼
     ¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç
     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤·¤¿¤¬¤Ã¤Æ¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢
-    ¤¤¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â @c m17n @c ¥é¥¤¥Ö¥é¥ê¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦
-    »ö¤¬¤Ç¤­¤ë¡£
+    ¤¤¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â @c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·
+    ¤¦»ö¤¬¤Ç¤­¤ë¡£
 
-    ´Êñ¤Î¤¿¤á¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿¥¤¥ë
+    ÍøÊØÀ­¤Î¤¿¤á¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿¥¤¥ë
     ¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î @c
     Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý¤·
-    ¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ïm17n-win API ¤Î¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
+    ¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
 
     </ul> 
 
 
 #include <stdio.h>
 #include <string.h>
-#include <dlfcn.h>
 
 #include "config.h"
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
 #include "m17n-gui.h"
 #include "m17n-misc.h"
 #include "internal.h"
 #include "symbol.h"
 #include "plist.h"
 
+static int mdebug_mask = MDEBUG_INPUT;
+
 static MSymbol Minput_method;
 
 /** Symbols to load an input method data.  */
@@ -233,7 +239,7 @@ integer_value (MInputContext *ic, MPlist *arg)
   MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
   int code;
   MText *preedit = ic->preedit;
-  int len = mtext_nbytes (preedit);
+  int len = mtext_nchars (preedit);
 
   if (MPLIST_INTEGER_P (arg))
     return MPLIST_INTEGER (arg);
@@ -250,7 +256,7 @@ integer_value (MInputContext *ic, MPlist *arg)
     code = ic->cursor_pos + 1;
   else if (code == '<')
     code = 0;
-  else if (code == '<')
+  else if (code == '>')
     code = len;
   return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
 }
@@ -686,8 +692,6 @@ load_input_method (MSymbol language, MSymbol name, MPlist *plist,
   MPlist *macros = NULL;
   MPlist *elt;
 
-  if (! MPLIST_PLIST_P (plist))
-    MERROR (MERROR_IM, -1);
   for (; MPLIST_PLIST_P (plist); plist = MPLIST_NEXT (plist))
     {
       elt = MPLIST_PLIST (plist);
@@ -747,9 +751,12 @@ load_input_method (MSymbol language, MSymbol name, MPlist *plist,
        }
     }
 
-  MPLIST_DO (elt, maps)
-    M17N_OBJECT_UNREF (MPLIST_VAL (elt));
-  M17N_OBJECT_UNREF (maps);
+  if (maps)
+    {
+      MPLIST_DO (elt, maps)
+       M17N_OBJECT_UNREF (MPLIST_VAL (elt));
+      M17N_OBJECT_UNREF (maps);
+    }
   if (! title)
     title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
                             MTEXT_FORMAT_US_ASCII);
@@ -807,7 +814,7 @@ shift_state (MInputContext *ic, MSymbol state_name)
 {
   MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
   MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
-  MIMState *state = ic_info->state;
+  MIMState *state;
 
   /* Find a state to shift to.  If not found, shift to the initial
      state.  */
@@ -815,6 +822,8 @@ shift_state (MInputContext *ic, MSymbol state_name)
   if (! state)
     state = (MIMState *) MPLIST_VAL (im_info->states);
 
+  MDEBUG_PRINT1 ("\n[IM] state-shift (%s)", MSYMBOL_NAME (state->name));
+
   /* Enter the new state.  */
   ic_info->state = state;
   ic_info->map = state->map;
@@ -829,6 +838,16 @@ shift_state (MInputContext *ic, MSymbol state_name)
       mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
                             Mcandidate_index, NULL, 0);
       mtext_cat (ic->produced, ic->preedit);
+      if ((mdebug__flag & mdebug_mask)
+         && mtext_nchars (ic->produced) > 0)
+       {
+         int i;
+
+         MDEBUG_PRINT (" (produced");
+           for (i = 0; i < mtext_nchars (ic->produced); i++)
+             MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
+         MDEBUG_PRINT (")");
+       }
       mtext_reset (ic->preedit);
       ic->candidate_list = NULL;
       ic->candidate_show = 0;
@@ -852,9 +871,17 @@ shift_state (MInputContext *ic, MSymbol state_name)
   if (ic_info->key_head == ic_info->used
       && ic_info->map == ic_info->state->map
       && ic_info->map->map_actions)
-    take_action_list (ic, ic_info->map->map_actions);
+    {
+      MDEBUG_PRINT (" init-actions:");
+      take_action_list (ic, ic_info->map->map_actions);
+    }
 }
 
+/* Find a candidate group that contains a candidate number INDEX from
+   PLIST.  Set START_INDEX to the first candidate number of the group,
+   END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
+   candidate group number if they are non-NULL.  If INDEX is -1, find
+   the last candidate group.  */
 
 static MPlist *
 find_candidates_group (MPlist *plist, int index,
@@ -868,7 +895,8 @@ find_candidates_group (MPlist *plist, int index,
        len = mtext_nchars (MPLIST_MTEXT (plist));
       else
        len = mplist_length (MPLIST_PLIST (plist));
-      if (i + len > index)
+      if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
+         : i + len > index)
        {
          if (start_index)
            *start_index = i;
@@ -963,7 +991,7 @@ new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
 }
 
 static void
-udpate_candidate (MInputContext *ic, MTextProperty *prop, int idx)
+update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
 {
   int from = mtext_property_start (prop);
   int to = mtext_property_end (prop);
@@ -1027,6 +1055,7 @@ take_action_list (MInputContext *ic, MPlist *action_list)
          args = MPLIST_NEXT (action);
        }
 
+      MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
       if (name == Minsert)
        {
          if (MPLIST_MTEXT_P (args))
@@ -1097,9 +1126,14 @@ take_action_list (MInputContext *ic, MPlist *action_list)
                                     end - start - 1, MPLIST_SYMBOL (args),
                                     NULL)
                        : MPLIST_INTEGER (args)));
-             if (idx < 0
-                 || (idx >= end
-                     && MPLIST_TAIL_P (MPLIST_NEXT (group))))
+             if (idx < 0)
+               {
+                 find_candidates_group (mtext_property_value (prop), -1,
+                                        NULL, &end, NULL);
+                 idx = end - 1;
+               }
+             else if (idx >= end
+                      && MPLIST_TAIL_P (MPLIST_NEXT (group)))
                idx = 0;
            }
          else
@@ -1132,7 +1166,7 @@ take_action_list (MInputContext *ic, MPlist *action_list)
                ingroup_index = len - 1;
              idx += ingroup_index;
            }
-         udpate_candidate (ic, prop, idx);
+         update_candidate (ic, prop, idx);
        }
       else if (name == Mshow)
        ic->candidate_show = 1;
@@ -1285,12 +1319,13 @@ take_action_list (MInputContext *ic, MPlist *action_list)
          else
            val1 /= val2;
          mplist_put (ic_info->vars, sym, (void *) val1);
+         MDEBUG_PRINT2 ("(%s=%d)", MSYMBOL_NAME (sym), val1);
        }
       else if (name == Mequal || name == Mless || name == Mgreater)
        {
          int val1, val2;
          MPlist *actions1, *actions2;
-         int ret;
+         int ret = 0;
 
          val1 = integer_value (ic, args);
          args = MPLIST_NEXT (args);
@@ -1360,6 +1395,9 @@ handle_key (MInputContext *ic)
   MSymbol key = ic_info->keys[ic_info->key_head];
   int i;
 
+  MDEBUG_PRINT2 ("[IM] handle `%s' in state %s", 
+                MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
+
   if (map->submaps)
     {
       submap = mplist_get (map->submaps, key);
@@ -1369,12 +1407,14 @@ handle_key (MInputContext *ic)
 
   if (submap)
     {
+      MDEBUG_PRINT (" submap-found");
       mtext_cpy (ic->preedit, ic_info->preedit_saved);
       ic->cursor_pos = ic_info->state_pos;
       ic_info->key_head++;
       ic_info->map = map = submap;
       if (map->map_actions)
        {
+         MDEBUG_PRINT (" map-actions:");
          if (take_action_list (ic, map->map_actions) < 0)
            return -1;
        }
@@ -1397,6 +1437,7 @@ handle_key (MInputContext *ic)
        {
          if (map->branch_actions)
            {
+             MDEBUG_PRINT (" branch-actions:");
              if (take_action_list (ic, map->branch_actions) < 0)
                return -1;
            }
@@ -1405,6 +1446,7 @@ handle_key (MInputContext *ic)
          if (ic_info->map != ic_info->state->map)
            shift_state (ic, ic_info->state->name);
        }
+      MDEBUG_PRINT ("\n");
     }
   else
     {
@@ -1413,14 +1455,20 @@ handle_key (MInputContext *ic)
       /* If MAP is the root map of the initial state, it means that
         the current input method can not handle KEY.  */
       if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
-       return -1;
+       {
+         MDEBUG_PRINT (" unhandled\n");
+         return -1;
+       }
 
       if (map != ic_info->state->map)
        {
          /* If MAP is not the root map... */
          /* If MAP has branch actions, perform them.  */
          if (map->branch_actions)
-           take_action_list (ic, map->branch_actions);
+           {
+             MDEBUG_PRINT (" branch-actions:");
+             take_action_list (ic, map->branch_actions);
+           }
          /* If MAP is still not the root map, shift to the current
             state. */
          if (ic_info->map != ic_info->state->map)
@@ -1428,7 +1476,10 @@ handle_key (MInputContext *ic)
              shift_state (ic, ic_info->state->name);
              /* If MAP has branch_actions, perform them.  */
              if (ic_info->map->branch_actions)
-               take_action_list (ic, ic_info->map->branch_actions);
+               {
+                 MDEBUG_PRINT (" init-actions:");
+                 take_action_list (ic, ic_info->map->branch_actions);
+               }
            }
        }
       else
@@ -1436,33 +1487,42 @@ handle_key (MInputContext *ic)
          /* MAP is the root map, perform branch actions (if any) or
             shift to the initial state.  */
          if (map->branch_actions)
-           take_action_list (ic, map->branch_actions);
+           {
+             MDEBUG_PRINT (" branch-actions:");
+             take_action_list (ic, map->branch_actions);
+           }
          else
            shift_state (ic,
                         ((MIMState *) MPLIST_VAL (im_info->states))->name);
        }
+      MDEBUG_PRINT ("\n");
     }
   return 0;
 }
 
 static void
-reset_ic (MInputContext *ic)
+reset_ic (MInputContext *ic, MSymbol ignore)
 {
   MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
   MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
 
+  if (im_info->states)
+    /* Shift to the initial state.  */
+    shift_state (ic, Mnil);
+  else
+    ic_info->state = NULL;
   MLIST_RESET (ic_info);
-  ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
-  ic_info->map = ic_info->state->map;
+  ic_info->map = ic_info->state ? ic_info->state->map : NULL;
   ic_info->state_key_head = ic_info->key_head = 0;
+  ic_info->key_unhandled = 0;
   ic->cursor_pos = ic_info->state_pos = 0;
-  ic->status = ic_info->state->title;
+  ic->status = ic_info->state ? ic_info->state->title : NULL;
   if (! ic->status)
     ic->status = im_info->title;
   ic->candidate_list = NULL;
   ic->candidate_show = 0;
   ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1;
-  if (ic_info->map->map_actions)
+  if (ic_info->map && ic_info->map->map_actions)
     take_action_list (ic, ic_info->map->map_actions);
 }
 
@@ -1571,7 +1631,7 @@ create_ic (MInputContext *ic)
        }
       M17N_OBJECT_UNREF (func_args);
     }
-  reset_ic (ic);
+  reset_ic (ic, Mnil);
   return 0;
 }
 
@@ -1618,6 +1678,11 @@ filter (MInputContext *ic, MSymbol key, void *arg)
   MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
   int i = 0;
 
+  if (! ic_info->state)
+    {
+      ic_info->key_unhandled = 1;
+      return 0;
+    }
   mtext_reset (ic->produced);
   ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
   MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
@@ -1627,7 +1692,7 @@ filter (MInputContext *ic, MSymbol key, void *arg)
       {
        /* KEY was not handled.  Reset the status and break the
           loop.  */
-       reset_ic (ic);
+       reset_ic (ic, Mnil);
        /* This forces returning 1.  */
        ic_info->key_unhandled = 1;
        break;
@@ -1635,7 +1700,7 @@ filter (MInputContext *ic, MSymbol key, void *arg)
     if (i++ == 100)
       {
        mdebug_hook ();
-       reset_ic (ic);
+       reset_ic (ic, Mnil);
        ic_info->key_unhandled = 1;
        break;
       }
@@ -1784,6 +1849,7 @@ minput__init ()
   Minput_candidates_draw = msymbol ("input-candidates-draw");
   Minput_set_spot = msymbol ("input-set-spot");
   Minput_toggle = msymbol ("input-toggle");
+  Minput_reset = msymbol ("input-reset");
 
   Mcandidate_list = msymbol_as_managing_key ("  candidate-list");
   Mcandidate_index = msymbol ("  candidate-index");
@@ -1829,7 +1895,9 @@ minput__init ()
   minput_default_driver.destroy_ic = destroy_ic;
   minput_default_driver.filter = filter;
   minput_default_driver.lookup = lookup;
-  minput_default_driver.callback_list = NULL;
+  minput_default_driver.callback_list = mplist ();
+  mplist_put (minput_default_driver.callback_list, Minput_reset,
+             (void *) reset_ic);
   minput_driver = &minput_default_driver;
   return 0;
 }
@@ -1887,7 +1955,7 @@ minput__char_to_key (int c)
 
     These are the predefined symbols that are used as the @c COMMAND
     argument of callback functions of an input method driver (see
-    #MInputDriver::callback_list).  */ 
+    #MInputDriver::callback_list ).  */ 
 /***ja
     @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
 
@@ -1908,6 +1976,7 @@ MSymbol Minput_candidates_done;
 MSymbol Minput_candidates_draw;
 MSymbol Minput_set_spot;
 MSymbol Minput_toggle;
+MSymbol Minput_reset;
 /*** @} */
 /*=*/
 
@@ -1918,7 +1987,7 @@ MSymbol Minput_toggle;
     internal input methods.
 
     The member MInputDriver::open_im () searches the m17n database for
-    an input method that matches the tag \<#Minput_method, $LANGUAGE,
+    an input method that matches the tag \< #Minput_method, $LANGUAGE,
     $NAME\> and loads it.
 
     The member MInputDriver::callback_list () is @c NULL.  Thus, it is
@@ -1940,7 +2009,7 @@ MSymbol Minput_toggle;
     ¥È¤Î¥É¥é¥¤¥Ð¤Ç¤¢¤ë¡£
 
     ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥° 
-    \<#Minput_method, $LANGUAGE, $NAME\> ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢
+    \< #Minput_method, $LANGUAGE, $NAME\> ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢
     ¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
 
     ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ê¤Î¤Ç¡¢¥×¥í¥°¥é
@@ -1963,15 +2032,16 @@ MInputDriver minput_default_driver;
     The variable #minput_driver is a pointer to the input method
     driver that is used by internal input methods.  The macro
     M17N_INIT () initializes it to a pointer to #minput_default_driver
-    (if <m17n.h> is included) or to #minput_gui_driver (if
-    <m17n-gui.h> is included).  */ 
+    (if <m17n<EM></EM>.h> is included) or to #minput_gui_driver (if
+    <m17n-gui<EM></EM>.h> is included).  */ 
 /***ja
     @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
 
     ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
-    ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥íM17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
-    ¥¿¤ò #minput_default_driver (<m17n.h> ¤¬´Þ¤Þ¤ì¤ë»þ) ¤Þ¤¿¤Ï 
-    #minput_gui_driver ( <m17n-gui.h> ¤¬´Þ¤Þ¤ì¤ë»þ) ¤Ë½é´ü²½¤¹¤ë¡£  */ 
+    ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
+    ¥¿¤ò #minput_default_driver (<m17n<EM></EM>.h> ¤¬´Þ¤Þ¤ì¤ë»þ) ¤Þ¤¿¤Ï
+    #minput_gui_driver ( <m17n-gui<EM></EM>.h> ¤¬´Þ¤Þ¤ì¤ë»þ) ¤Ë½é´ü²½¤¹
+    ¤ë¡£  */ 
 
 MInputDriver *minput_driver;
 
@@ -2148,7 +2218,7 @@ minput_create_ic (MInputMethod *im, void *arg)
     The minput_destroy_ic () function destroys the input context $IC,
     which must have been created by minput_create_ic ().  It calls
     callback functions corresponding to #Minput_preedit_done,
-    #Minput_status_done, and #Mcandidate_done in this order.  */
+    #Minput_status_done, and #Minput_candidates_done in this order.  */
 
 /***ja
     @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
@@ -2156,7 +2226,7 @@ minput_create_ic (MInputMethod *im, void *arg)
     ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£¤³
     ¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê
     ¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï#Minput_preedit_done,
-    #Minput_status_done, #Mcandidate_done ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò
+    #Minput_status_done, #Minput_candidates_done ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò
     ¤³¤Î½ç¤Ë¸Æ¤Ö¡£
   */
 
@@ -2183,9 +2253,9 @@ minput_destroy_ic (MInputContext *ic)
 
     The minput_filter () function filters input key $KEY according to
     input context $IC, and calls callback functions corresponding to
-    #Minput_preedit_draw, #Minput_status_draw, and #Mcandidate_draw if
-    the preedit text, the status, and the current candidate are
-    changed respectively.
+    #Minput_preedit_draw, #Minput_status_draw, and
+    #Minput_candidates_draw if the preedit text, the status, and the
+    current candidate are changed respectively.
 
     @return
     If $KEY is filtered out, this function returns 1.  In that case,
@@ -2199,7 +2269,7 @@ minput_destroy_ic (MInputContext *ic)
     ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥­¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Ë±þ
     ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥­¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½
     ¤·¤¿ºÝ¤Ë¤Ï¤½¤ì¤¾¤ì#Minput_preedit_draw, #Minput_status_draw,
-    #Mcandidate_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
+    #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
 
     @return 
     $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¸Æ¤Ó
@@ -2228,7 +2298,6 @@ minput_filter (MInputContext *ic, MSymbol key, void *arg)
        minput__callback (ic, Minput_status_draw);
       if (ic->candidates_changed)
        minput__callback (ic, Minput_candidates_draw);
-      ic->preedit_changed = ic->status_changed = ic->candidates_changed = 0;
     }
 
   return ret;
@@ -2246,7 +2315,7 @@ minput_filter (MInputContext *ic, MSymbol key, void *arg)
     If a text was produced by the input method, it is concatenated
     to M-text $MT.
 
-    This function calls #MInputDriver::lookup.
+    This function calls #MInputDriver::lookup .
 
     @return
     If $KEY was correctly handled by the input method, this function
@@ -2254,7 +2323,7 @@ minput_filter (MInputContext *ic, MSymbol key, void *arg)
     may be produced in $MT.  */
 
 /***ja
-    @brief ÆþÎϥ᥽¥Ã¥É¤¬ºî¤Ã¤¿¥Æ¥­¥¹¥È¤Î¸¡º÷.
+    @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥­¥¹¥È¤Î¸¡º÷.
 
     ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥­¥¹¥È¤ò¸¡º÷¤¹
     ¤ë¡£$KEY ¤Ï´Ø¿ôminput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î
@@ -2283,16 +2352,16 @@ minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
     @brief Set the spot of the input context.
 
     The minput_set_spot () function set the spot of input context $IC
-    to coordinate ($X, $Y) with the height $ASCENT and $DESCENT.
+    to coordinate ($X, $Y ) with the height $ASCENT and $DESCENT .
     The semantics of these values depend on the input method driver.
     $FONTSIZE specfies the fontsize of a preedit text in 1/10 point.
 
     For instance, an driver designed to work in CUI environment may
     use $X and $Y as column and row numbers, and ignore $ASCENT and
-    $DESCENT.  An driver designed to work on a window system may treat
-    $X and $Y as pixel offsets relative to the origin of the client
-    window, and treat $ASCENT and $DESCENT as ascent and descent
-    pixels of a line at ($X . $Y).
+    $DESCENT .  An driver designed to work on a window system may
+    treat $X and $Y as pixel offsets relative to the origin of the
+    client window, and treat $ASCENT and $DESCENT as ascent and
+    descent pixels of a line at ($X . $Y ).
 
     $MT and $POS is an M-text and a character position at the spot.
     $MT may be @c NULL, in which case, the input method cannot get
@@ -2302,16 +2371,16 @@ minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
     @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë
 
     ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂ
-    É¸ ($X, $Y)¤Ë ¡¢¹â¤µ $ASCENT¡¢$DESCENT ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕ
-    Ì£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£$FONTSIZE ¤Ïpreedit ¥Æ¥­¥¹¥È¤Î
-    ¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
+    É¸ ($X, $Y )¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤÎ
+    °ÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£$FONTSIZE ¤Ïpreedit ¥Æ¥­¥¹¥È
+    ¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
 
-    ¤¿¤È¤¨¤Ð CUI ´Ä¶­¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X, $Y ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ
-    ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT¡¢$DESCENT ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£
-    ¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï $X,$Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î
-    ¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢$ASCENT 
-    ¤È $DESCENT ¤ò ($X . $Y) ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì
-    ¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£  
+    ¤¿¤È¤¨¤Ð CUI ´Ä¶­¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤Î
+    ÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿
+    ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦
+    ¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
+    $ASCENT ¤È $DESCENT ¤ò ($X . $Y ) ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯
+    ¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
 
     $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
     NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ­¥¹¥È¤Ë
@@ -2355,6 +2424,32 @@ minput_toggle (MInputContext *ic)
   ic->active = ! ic->active;
 }
 
+/***en
+    @brief Reset an input context.
+
+    The minput_reset_ic () function resets the input context $IC by
+    calling a callback functions corresponding to #Minput_reset.  It
+    actually shifts the state to the initial one, and thus the current
+    preediting text (if any) is committed.  If necessary, a program
+    can extract that text by calling minput_lookup () just after the
+    call of minput_reset_ic ().  In that case, the arguments @c KEY
+    and @c ARG of minput_lookup () are ignored.  */
+/***ja
+    @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
+
+    ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
+    ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¤³¤ì¤Ï¼ÂºÝ¤Ï
+    ÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˥·¥Õ¥È¤µ¤»¤ë¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î
+    ¥Æ¥­¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£É¬Íפʤ饢¥×¥ê¥±¡¼¥·¥ç¥ó¥×
+    ¥í¥°¥é¥à¤Ï minput_lookup () ¤òÆɤó¤Ç¤½¤Î¥Æ¥­¥¹¥È¤ò¼è¤ê½Ð¤»¤ë¡£¤½¤Î
+    ºÝ¡¢minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG ¤Ï̵»ë¤µ¤ì¤ë¡£ */
+void
+minput_reset_ic (MInputContext *ic)
+{
+  if (ic->im->driver.callback_list)
+    minput__callback (ic, Minput_reset);
+}
+
 
 /*** @} */
 /*=*/