(take_action_list): Move the handling of candidate-list
[m17n/m17n-lib.git] / src / input.c
index 388237e..2de5547 100644 (file)
@@ -1,5 +1,5 @@
 /* input.c -- input method module.
-   Copyright (C) 2003, 2004, 2005, 2006
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
     input event to an input key by himself.  See the documentation of
     the function minput_event_to_key () for the detail.
 
-    <li> Foreign Input Method
+    <li> Foreign Input Method @anchor foreign-input-method
 
     A foreign input method has @c Mnil LANGUAGE, and its body is
     defined in an external resource (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
+    property of key #Minput_driver, and the value must be a pointer
     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
-    stores @c Minput_driver property of the symbol @c Mxim with a
+    stores #Minput_driver property of the symbol @c Mxim with a
     pointer to the driver.  See the documentation of m17n GUI API for
     the detail.
 
     ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
     ÀâÌÀ¤ò»²¾È¡£
 
-    <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
+    <li> ³°ÉôÆþÎϥ᥽¥Ã¥É @anchor foreign-input-method
 
     ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
     Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
-    ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
+    ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï #Minput_driver ¤ò
     ¥­¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
     ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
     ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
 
     ÍøÊØÀ­¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
     ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
-    @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
+    #Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
     ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
 
     </ul> 
 #include <dlfcn.h>
 #endif
 
-#include "m17n-gui.h"
+#include "m17n.h"
 #include "m17n-misc.h"
 #include "internal.h"
 #include "mtext.h"
 #include "database.h"
 #include "charset.h"
 
-static int mdebug_mask = MDEBUG_INPUT;
+static int mdebug_flag = MDEBUG_INPUT;
 
 static int fully_initialized;
 
-static MSymbol Minput_method;
-
 /** Symbols to load an input method data.  */
 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
 
@@ -222,6 +220,7 @@ typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
 
 typedef struct
 {
+  MSymbol name;
   void *handle;
   MPlist *func_list;           /* function name vs (MIMExternalFunc *) */
 } MIMExternalModule;
@@ -271,7 +270,7 @@ static int update_custom_info (void);
 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
 
 \f
-void
+static void
 fully_initialize ()
 {
   char *key_names[32]
@@ -279,23 +278,28 @@ fully_initialize ()
        "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
-  char buf[6], buf2[32];
+  char buf[6], buf2[32], buf3[2];
   int i, j;
-  /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return.  */
-  MSymbol alias[7];
+  /* Maximum case: '\215', C-M-m, C-M-M, M-Return, C-A-m, C-A-M, A-Return
+     plus one for cyclic alias.  */
+  MSymbol alias[8];
 
   M_key_alias = msymbol ("  key-alias");
 
+  buf3[1] = '\0';
+
+  /* Aliases for 0x00-0x1F */
   buf[0] = 'C';
   buf[1] = '-';
   buf[3] = '\0';
   for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
     {
-      one_char_symbol[i] = msymbol (buf);
+      j = 0;
+      buf3[0] = i;
+      alias[j++] = msymbol (buf3);
+      alias[j++] = one_char_symbol[i] = msymbol (buf);
       if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
        {
-         j = 0;
-         alias[j++] = one_char_symbol[i];
          if (key_names[i])
            {
              /* Ex: `Escape' == `C-['  */
@@ -308,12 +312,14 @@ fully_initialize ()
              alias[j++] = msymbol (buf);
              buf[2] -= 32;
            }
-         /* Establish cyclic alias chain.  */
-         alias[j] = alias[0];
-         while (--j >= 0)
-           msymbol_put (alias[j], M_key_alias, alias[j + 1]);
        }
+      /* Establish cyclic alias chain.  */
+      alias[j] = alias[0];
+      while (--j >= 0)
+       msymbol_put (alias[j], M_key_alias, alias[j + 1]);
     }
+
+  /* Aliases for 0x20-0x7E */
   buf[0] = 'S';
   for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
     {
@@ -330,19 +336,26 @@ fully_initialize ()
            msymbol_put (alias[j], M_key_alias, alias[j + 1]);
        }
     }
-  buf[0] = 'C';
 
-  alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
-  alias[1] = msymbol ("C-?");
-  for (j = 0; j < 2; j++)
+  /* Aliases for 0x7F */
+  buf3[0] = 0x7F;
+  alias[0] = alias[3] = msymbol (buf3);
+  alias[1] = one_char_symbol[127] = msymbol ("Delete");
+  alias[2] = msymbol ("C-?");
+  for (j = 0; j < 3; j++)
     msymbol_put (alias[j], M_key_alias, alias[j + 1]);
 
+  /* Aliases for 0x80-0x9F */
+  buf[0] = 'C';
+  /* buf[1] = '-'; -- already done */
   buf[3] = '-';
   buf[5] = '\0';
   buf2[1] = '-';
   for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
     {
       j = 0;
+      buf3[0] = i;
+      alias[j++] = msymbol (buf3);
       /* `C-M-a' == `C-A-a' */
       buf[2] = 'M';
       alias[j++] = one_char_symbol[i] = msymbol (buf);
@@ -367,28 +380,59 @@ fully_initialize ()
          alias[j++] = msymbol (buf);
          buf[4] -= 32;
        }
+
       /* Establish cyclic alias chain.  */
       alias[j] = alias[0];
       while (--j >= 0)
        msymbol_put (alias[j], M_key_alias, alias[j + 1]);
     }
-  for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
+
+  /* Aliases for 0xA0-0xFF */
+  for (i = 160, buf[4] = ' '; i < 255; i++, buf[4]++)
     {
+      j = 0;
+      buf3[0] = i;
+      alias[j++] = msymbol (buf3);
       buf[2] = 'M';
-      alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
+      alias[j++] = one_char_symbol[i] = msymbol (buf + 2);
       buf[2] = 'A';
-      alias[1] = msymbol (buf + 2);
-      for (j = 0; j < 2; j++)
+      alias[j++] = msymbol (buf + 2);
+      alias[j]= alias[0];
+      while (--j >= 0)
        msymbol_put (alias[j], M_key_alias, alias[j + 1]);
     }
 
-  alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
-  alias[1] = msymbol ("A-Delete");
-  alias[2] = msymbol ("C-M-?");
-  alias[3] = msymbol ("C-A-?");
-  for (j = 0; j < 4; j++)
+  buf3[0] = (char) 255;
+  alias[0] = alias[3] = msymbol (buf3);
+  alias[1] = one_char_symbol[255] = msymbol ("M-Delete");
+  alias[2] = msymbol ("A-Delete");
+  for (j = 0; j < 3; j++)
     msymbol_put (alias[j], M_key_alias, alias[j + 1]);
 
+  /* Aliases for keys that can't be mapped to one-char-symbol
+     (e.g. C-A-1) */
+  /* buf is already set to "C-?-".  */
+  for (i = ' '; i <= '~'; i++)
+    {
+      if (i == '@')
+       {
+         i = '_';
+         continue;
+       }
+      if (i == 'a')
+       {
+         i = 'z';
+         continue;
+       }
+      buf[2] = 'M';
+      buf[4] = i;
+      alias[0] = alias[2] = msymbol (buf);
+      buf[2] = 'A';
+      alias[1] = msymbol (buf);
+      for (j = 0; j < 2; j++)
+       msymbol_put (alias[j], M_key_alias, alias[j + 1]);
+    }
+
   Minput_method = msymbol ("input-method");
   Mtitle = msymbol ("title");
   Mmacro = msymbol ("macro");
@@ -430,7 +474,7 @@ fully_initialize ()
   Mor = msymbol ("|");
   Mnot = msymbol ("!");
 
-  Mat_reload = msymbol ("@reload");
+  Mat_reload = msymbol ("-reload");
 
   Mcandidates_group_size = msymbol ("candidates-group-size");
   Mcandidates_charset = msymbol ("candidates-charset");
@@ -489,6 +533,9 @@ marker_code (MSymbol sym, int surrounding)
 }
 
 
+/* Return a plist containing an integer value of VAR.  The plist must
+   not be UNREFed. */
+
 static MPlist *
 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
 {
@@ -585,10 +632,10 @@ get_following_char (MInputContext *ic, int pos)
   if (ic_info->following_text)
     {
       len = mtext_nchars (ic_info->following_text);
-      if (pos <= len)
-       return mtext_ref_char (ic_info->following_text, pos - 1);
+      if (pos < len)
+       return mtext_ref_char (ic_info->following_text, pos);
     }
-  mt = get_surrounding_text (ic, pos);
+  mt = get_surrounding_text (ic, pos + 1);
   if (! mt)
     return -2;
   len = mtext_nchars (mt);
@@ -604,13 +651,13 @@ get_following_char (MInputContext *ic, int pos)
     }
   else
     ic_info->following_text = mt;
-  if (pos > len)
+  if (pos >= len)
     return -1;
-  return mtext_ref_char (ic_info->following_text, pos - 1);
+  return mtext_ref_char (ic_info->following_text, pos);
 }
 
 static int
-surrounding_pos (MSymbol sym)
+surrounding_pos (MSymbol sym, int *pos)
 {
   char *name;
 
@@ -618,22 +665,24 @@ surrounding_pos (MSymbol sym)
     return 0;
   name = MSYMBOL_NAME (sym);
   if (name[0] == '@'
-      && (name[1] == '-' || name[1] == '+')
-      && name[2] >= '1' && name[2] <= '9')
-    return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
+      && (name[1] == '-' ? (name[2] >= '1' && name[2] <= '9')
+         : name[1] == '+' ? (name[2] >= '0' && name[2] <= '9')
+         : 0))
+    {
+      *pos = name[1] == '-' ? - atoi (name + 2) : atoi (name + 2);
+      return 1;
+    }
   return 0;
 }
 
 static int
-integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
+integer_value (MInputContext *ic, MPlist *arg, int surrounding)
 {
   MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
   int code, pos;
   MText *preedit = ic->preedit;
   int len = mtext_nchars (preedit);
 
-  if (value)
-    *value = NULL;
   if (MPLIST_INTEGER_P (arg))
     return MPLIST_INTEGER (arg);
 
@@ -642,8 +691,6 @@ integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
     {
       MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
 
-      if (value)
-       *value = val;
       return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
     }
   if (code == '@')
@@ -655,7 +702,7 @@ integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
       if (name[2])
        {
          pos = atoi (name + 1);
-         if (pos == 0)
+         if (pos == 0 && code == '-')
            return get_preceding_char (ic, 0);
          pos = ic->cursor_pos + pos;
          if (pos < 0)
@@ -665,8 +712,8 @@ integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
                                       mtext_len (ic->produced) + pos);
              return get_preceding_char (ic, - pos);
            }
-         if (pos >= len)
-           return get_following_char (ic, pos - len + 1);
+         else if (pos >= len)
+           return get_following_char (ic, pos - len);
        }
       else
        pos = ic->cursor_pos + (code == '+' ? 1 : -1);
@@ -717,7 +764,7 @@ resolve_expression (MInputContext *ic, MPlist *plist)
   if (MPLIST_INTEGER_P (plist))
     return MPLIST_INTEGER (plist);
   if (MPLIST_SYMBOL_P (plist))
-    return integer_value (ic, plist, NULL, 1);
+    return integer_value (ic, plist, 1);
   if (! MPLIST_PLIST_P (plist))
     return 0;
   plist = MPLIST_PLIST (plist);
@@ -815,6 +862,11 @@ parse_action_list (MPlist *plist, MPlist *macros)
 
          pl = MPLIST_NEXT (pl);
 
+         if (action_name == M_candidates)
+           {
+             /* This is an already regularised action.  */
+             continue;
+           }
          if (action_name == Minsert)
            {
              if (MPLIST_MTEXT_P (pl))
@@ -822,6 +874,13 @@ parse_action_list (MPlist *plist, MPlist *macros)
                  if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
                    MERROR (MERROR_IM, -1);
                }
+             else if (MPLIST_INTEGER_P (pl))
+               {
+                 int c = MPLIST_INTEGER (pl);
+
+                 if (c < 0 || c > MCHAR_MAX)
+                   MERROR (MERROR_IM, -1);
+               }
              else if (MPLIST_PLIST_P (pl))
                {
                  MPLIST_DO (pl, MPLIST_PLIST (pl))
@@ -1119,7 +1178,7 @@ load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
 }
 
 /* Load a macro from PLIST into IM_INFO->macros.
-   PLIST has this from:
+   PLIST has this form:
       PLIST ::= ( MACRO-NAME ACTION * )
    IM_INFO->macros is a plist of macro names vs action list.  */
 
@@ -1133,8 +1192,7 @@ load_macros (MInputMethodInfo *im_info, MPlist *plist)
     MERROR (MERROR_IM, -1);
   name = MPLIST_SYMBOL (plist);
   plist = MPLIST_NEXT (plist);
-  if (MPLIST_TAIL_P (plist)
-      || parse_action_list (plist, im_info->macros) < 0)
+  if (MFAILP (! MPLIST_TAIL_P (plist)))
     MERROR (MERROR_IM, -1);
   pl = mplist_get (im_info->macros, name);
   M17N_OBJECT_UNREF (pl);
@@ -1143,13 +1201,17 @@ load_macros (MInputMethodInfo *im_info, MPlist *plist)
   return 0;
 }
 
-/* Load an external module from PLIST into IM_INFO->externals.
+/* Load an external module from PLIST, and return a pointer to
+   MIMExternalModule.
+
    PLIST has this form:
       PLIST ::= ( MODULE-NAME FUNCTION * )
-   IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *).  */
+   IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *).
 
-static int
-load_external_module (MInputMethodInfo *im_info, MPlist *plist)
+   On error, return NULL.  */
+
+static MIMExternalModule *
+load_external_module (MPlist *plist)
 {
   void *handle;
   MSymbol module;
@@ -1162,16 +1224,15 @@ load_external_module (MInputMethodInfo *im_info, MPlist *plist)
     module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
   else if (MPLIST_SYMBOL_P (plist))
     module = MPLIST_SYMBOL (plist);
-  module_file = alloca (strlen (MSYMBOL_NAME (module))
+  module_file = alloca (strlen (M17N_MODULE_DIR) + 1
+                       + strlen (MSYMBOL_NAME (module))
                        + strlen (DLOPEN_SHLIB_EXT) + 1);
-  sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
+  sprintf (module_file, "%s/%s%s",
+          M17N_MODULE_DIR, MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
 
   handle = dlopen (module_file, RTLD_NOW);
   if (MFAILP (handle))
-    {
-      fprintf (stderr, "%s\n", dlerror ());
-      return -1;
-    }
+    return NULL;
   func_list = mplist ();
   MPLIST_DO (plist, MPLIST_NEXT (plist))
     {
@@ -1184,15 +1245,23 @@ load_external_module (MInputMethodInfo *im_info, MPlist *plist)
     }
 
   MSTRUCT_MALLOC (external, MERROR_IM);
+  external->name = module;
   external->handle = handle;
   external->func_list = func_list;
-  mplist_add (im_info->externals, module, external);
-  return 0;
+  return external;
 
  err_label:
-  dlclose (handle);
   M17N_OBJECT_UNREF (func_list);
-  return -1;
+  dlclose (handle);
+  return NULL;
+}
+
+static void
+unload_external_module (MIMExternalModule *external)
+{
+  dlclose (external->handle);
+  M17N_OBJECT_UNREF (external->func_list);
+  free (external);
 }
 
 static void
@@ -1321,11 +1390,7 @@ fini_im_info (MInputMethodInfo *im_info)
     {
       MPLIST_DO (plist, im_info->externals)
        {
-         MIMExternalModule *external = MPLIST_VAL (plist);
-
-         dlclose (external->handle);
-         M17N_OBJECT_UNREF (external->func_list);
-         free (external);
+         unload_external_module (MPLIST_VAL (plist));
          MPLIST_KEY (plist) = Mt;
        }
       M17N_OBJECT_UNREF (im_info->externals);
@@ -1507,7 +1572,7 @@ update_global_info (void)
 }
 
 
-/* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
+/* Return an IM_INFO for the input method specified by LANGUAGE, NAME,
    and EXTRA.  KEY, if not Mnil, tells which kind of information about
    the input method is necessary, and the returned IM_INFO may contain
    only that information.  */
@@ -1564,6 +1629,8 @@ get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
        im_info->cmds = mplist ();
       if (! im_info->vars)
        im_info->vars = mplist ();
+      if (! im_info->states)
+       im_info->states = mplist ();
     }
   if (! im_info->title
       && (key == Mnil || key == Mtitle))
@@ -2229,9 +2296,13 @@ load_im_info (MPlist *plist, MInputMethodInfo *im_info)
              im_info->externals = mplist ();
            MPLIST_DO (elt, MPLIST_NEXT (elt))
              {
+               MIMExternalModule *external;
+
                if (MFAILP (MPLIST_PLIST_P (elt)))
                  continue;
-               load_external_module (im_info, MPLIST_PLIST (elt));
+               external = load_external_module (MPLIST_PLIST (elt));
+               if (external)
+                 mplist_add (im_info->externals, external->name, external);
              }
          }
        else if (key == Mstate)
@@ -2320,6 +2391,12 @@ load_im_info (MPlist *plist, MInputMethodInfo *im_info)
            M17N_OBJECT_REF (im_info->description);
          }
       }
+  if (im_info->macros)
+    {
+      MPLIST_DO (pl, im_info->macros)
+       parse_action_list (MPLIST_PLIST (pl), im_info->macros);
+    }
+
   im_info->tick = time (NULL);
 }
 
@@ -2328,6 +2405,10 @@ load_im_info (MPlist *plist, MInputMethodInfo *im_info)
 static int take_action_list (MInputContext *ic, MPlist *action_list);
 static void preedit_commit (MInputContext *ic, int need_prefix);
 
+/* Shift to the state of name STATE_NAME.  If STATE_NAME is `t', shift
+   to the previous state (if any).  If STATE_NAME is `nil', shift to
+   the initial state.  */
+
 static void
 shift_state (MInputContext *ic, MSymbol state_name)
 {
@@ -2354,7 +2435,7 @@ shift_state (MInputContext *ic, MSymbol state_name)
        state = (MIMState *) MPLIST_VAL (im_info->states);
     }
 
-  if (mdebug__flag & mdebug_mask)
+  if (MDEBUG_FLAG ())
     {
       if (orig_state)
        MDEBUG_PRINT2 ("\n  [IM] [%s] (shift %s)\n",
@@ -2374,7 +2455,7 @@ shift_state (MInputContext *ic, MSymbol state_name)
     preedit_commit (ic, 0);
   mtext_cpy (ic_info->preedit_saved, ic->preedit);
   ic_info->state_pos = ic->cursor_pos;
-  if (state != orig_state)
+  if (state != orig_state || state_name == Mnil)
     {
       if (state == (MIMState *) MPLIST_VAL (im_info->states))
        {
@@ -2391,13 +2472,7 @@ shift_state (MInputContext *ic, MSymbol state_name)
       else
        ic->status = im_info->title;
       ic->status_changed = 1;
-      if (ic_info->map == ic_info->state->map
-         && ic_info->map->map_actions)
-       {
-         MDEBUG_PRINT1 ("  [IM] [%s] init-actions:",
-                        MSYMBOL_NAME (state->name));
-         take_action_list (ic, ic_info->map->map_actions);
-       }
+      ic_info->state_hook = ic_info->map->map_actions;
     }
 }
 
@@ -2486,7 +2561,10 @@ preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
   else
     {
       mtext_ins_char (ic->preedit, pos, c, 1);
-      MDEBUG_PRINT1 ("('%c')", c);
+      if (c < 0x7F)
+       MDEBUG_PRINT1 ("('%c')", c);
+      else
+       MDEBUG_PRINT1 ("(U+%04X)", c);
     }
   adjust_markers (ic, pos, pos, nchars);
   ic->preedit_changed = 1;
@@ -2537,7 +2615,7 @@ preedit_commit (MInputContext *ic, int need_prefix)
       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)
+      if (MDEBUG_FLAG ())
        {
          int i;
 
@@ -2658,6 +2736,8 @@ get_select_charset (MInputContextInfo * ic_info)
   return MCHARSET (sym);
 }
 
+/* The returned plist must be UNREFed.  */
+
 static MPlist *
 adjust_candidates (MPlist *plist, MCharset *charset)
 {
@@ -2760,6 +2840,8 @@ adjust_candidates (MPlist *plist, MCharset *charset)
   return plist;
 }
 
+/* The returned Plist must be UNREFed.  */
+
 static MPlist *
 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
 {
@@ -2772,83 +2854,90 @@ get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
   column = MPLIST_INTEGER (plist);
 
   plist = MPLIST_PLIST (args);
+  if (! plist)
+    return NULL;
   if (charset)
-    plist = adjust_candidates (plist, charset);
+    {
+      plist = adjust_candidates (plist, charset);
+      if (! plist)
+       return NULL;
+    }
+  else
+    M17N_OBJECT_REF (plist);
+
+  if (column == 0)
+    return plist;
 
-  if (plist && column > 0)
+  if (MPLIST_MTEXT_P (plist))
     {
-      if (MPLIST_MTEXT_P (plist))
-       {
-         MText *mt = MPLIST_MTEXT (plist);
-         MPlist *next = MPLIST_NEXT (plist);
+      MText *mt = MPLIST_MTEXT (plist);
+      MPlist *next = MPLIST_NEXT (plist);
 
-         if (MPLIST_TAIL_P (next))
-           M17N_OBJECT_REF (mt);
-         else
+      if (MPLIST_TAIL_P (next))
+       M17N_OBJECT_REF (mt);
+      else
+       {
+         mt = mtext_dup (mt);
+         while (! MPLIST_TAIL_P (next))
            {
-             mt = mtext_dup (mt);
-             while (! MPLIST_TAIL_P (next))
-               {
-                 mt = mtext_cat (mt, MPLIST_MTEXT (next));
-                 next = MPLIST_NEXT (next);
-               }
+             mt = mtext_cat (mt, MPLIST_MTEXT (next));
+             next = MPLIST_NEXT (next);
            }
-         if (charset)
-           M17N_OBJECT_UNREF (plist);
-         plist = mplist ();
-         len = mtext_nchars (mt);
-         if (len <= column)
-           mplist_add (plist, Mtext, mt);
-         else
+       }
+      M17N_OBJECT_UNREF (plist);
+      plist = mplist ();
+      len = mtext_nchars (mt);
+      if (len <= column)
+       mplist_add (plist, Mtext, mt);
+      else
+       {
+         for (i = 0; i < len; i += column)
            {
-             for (i = 0; i < len; i += column)
-               {
-                 int to = (i + column < len ? i + column : len);
-                 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
+             int to = (i + column < len ? i + column : len);
+             MText *sub = mtext_copy (mtext (), 0, mt, i, to);
                                                       
-                 mplist_add (plist, Mtext, sub);
-                 M17N_OBJECT_UNREF (sub);
-               }
+             mplist_add (plist, Mtext, sub);
+             M17N_OBJECT_UNREF (sub);
            }
-         M17N_OBJECT_UNREF (mt);
        }
-      else if (! MPLIST_TAIL_P (plist))
+      M17N_OBJECT_UNREF (mt);
+    }
+  else if (MPLIST_PLIST_P (plist))
+    {
+      MPlist *tail = plist;
+      MPlist *new = mplist ();
+      MPlist *this = mplist ();
+      int count = 0;
+
+      MPLIST_DO (tail, tail)
        {
-         MPlist *tail = plist;
-         MPlist *new = mplist ();
-         MPlist *this = mplist ();
-         int count = 0;
+         MPlist *p = MPLIST_PLIST (tail);
 
-         MPLIST_DO (tail, tail)
+         MPLIST_DO (p, p)
            {
-             MPlist *p = MPLIST_PLIST (tail);
+             MText *mt = MPLIST_MTEXT (p);
 
-             MPLIST_DO (p, p)
+             if (count == column)
                {
-                 MText *mt = MPLIST_MTEXT (p);
-
-                 if (count == column)
-                   {
-                     mplist_add (new, Mplist, this);
-                     M17N_OBJECT_UNREF (this);
-                     this = mplist ();
-                     count = 0;
-                   }
-                 mplist_add (this, Mtext, mt);
-                 count++;
+                 mplist_add (new, Mplist, this);
+                 M17N_OBJECT_UNREF (this);
+                 this = mplist ();
+                 count = 0;
                }
+             mplist_add (this, Mtext, mt);
+             count++;
            }
-         mplist_add (new, Mplist, this);
-         M17N_OBJECT_UNREF (this);
-         mplist_set (plist, Mnil, NULL);
-         MPLIST_DO (tail, new)
-           {
-             MPlist *elt = MPLIST_PLIST (tail);
+       }
+      mplist_add (new, Mplist, this);
+      M17N_OBJECT_UNREF (this);
+      mplist_set (plist, Mnil, NULL);
+      MPLIST_DO (tail, new)
+       {
+         MPlist *elt = MPLIST_PLIST (tail);
 
-             mplist_add (plist, Mplist, elt);
-           }
-         M17N_OBJECT_UNREF (new);
+         mplist_add (plist, Mplist, elt);
        }
+      M17N_OBJECT_UNREF (new);
     }
 
   return plist;
@@ -2915,9 +3004,6 @@ static int
 take_action_list (MInputContext *ic, MPlist *action_list)
 {
   MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
-  MPlist *candidate_list = ic->candidate_list;
-  int candidate_index = ic->candidate_index;
-  int candidate_show = ic->candidate_show;
   MTextProperty *prop;
 
   MPLIST_DO (action_list, action_list)
@@ -2948,18 +3034,22 @@ take_action_list (MInputContext *ic, MPlist *action_list)
       else if (name == M_candidates)
        {
          MPlist *plist = get_candidate_list (ic_info, args);
+         MPlist *pl;
          int len;
 
-         if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
+         if (! plist)
            continue;
+         if (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist))
+           {
+             M17N_OBJECT_UNREF (plist);
+             continue;
+           }
          if (MPLIST_MTEXT_P (plist))
            {
              preedit_insert (ic, ic->cursor_pos, NULL,
                              mtext_ref_char (MPLIST_MTEXT (plist), 0));
              len = 1;
            }
-         else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
-           continue;
          else
            {
              MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
@@ -2967,11 +3057,12 @@ take_action_list (MInputContext *ic, MPlist *action_list)
              preedit_insert (ic, ic->cursor_pos, mt, 0);
              len = mtext_nchars (mt);
            }
-         plist = mplist_copy (plist);
+         pl = mplist_copy (plist);
+         M17N_OBJECT_UNREF (plist);
          mtext_put_prop (ic->preedit,
                          ic->cursor_pos - len, ic->cursor_pos,
-                         Mcandidate_list, plist);
-         M17N_OBJECT_UNREF (plist);
+                         Mcandidate_list, pl);
+         M17N_OBJECT_UNREF (pl);
          mtext_put_prop (ic->preedit,
                          ic->cursor_pos - len, ic->cursor_pos,
                          Mcandidate_index, (void *) 0);
@@ -3071,7 +3162,7 @@ take_action_list (MInputContext *ic, MPlist *action_list)
          int to;
 
          if (MPLIST_SYMBOL_P (args)
-             && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
+             && surrounding_pos (MPLIST_SYMBOL (args), &pos))
            {
              to = ic->cursor_pos + pos;
              if (to < 0)
@@ -3095,8 +3186,9 @@ take_action_list (MInputContext *ic, MPlist *action_list)
                to = 0;
              else if (to > len)
                to = len;
+             pos = to - ic->cursor_pos;
            }
-         MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
+         MDEBUG_PRINT1 ("(%d)", pos);
          if (to < ic->cursor_pos)
            preedit_delete (ic, to, ic->cursor_pos);
          else if (to > ic->cursor_pos)
@@ -3256,7 +3348,7 @@ take_action_list (MInputContext *ic, MPlist *action_list)
        {
          int intarg = (MPLIST_TAIL_P (args)
                        ? ic_info->used - 2
-                       : integer_value (ic, args, NULL, 0));
+                       : integer_value (ic, args, 0));
 
          mtext_reset (ic->preedit);
          mtext_reset (ic_info->preedit_saved);
@@ -3285,11 +3377,11 @@ take_action_list (MInputContext *ic, MPlist *action_list)
               || name == Mmul || name == Mdiv)
        {
          MSymbol sym = MPLIST_SYMBOL (args);
+         MPlist *value = resolve_variable (ic_info, sym);
          int val1, val2;
-         MPlist *value;
          char *op;
 
-         val1 = integer_value (ic, args, &value, 0);
+         val1 = MPLIST_INTEGER (value);
          args = MPLIST_NEXT (args);
          val2 = resolve_expression (ic, args);
          if (name == Mset)
@@ -3304,8 +3396,7 @@ take_action_list (MInputContext *ic, MPlist *action_list)
            val1 /= val2, op = "/=";
          MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
                         MSYMBOL_NAME (sym), op, val1, val1);
-         if (value)
-           mplist_set (value, Minteger, (void *) val1);
+         mplist_set (value, Minteger, (void *) val1);
        }
       else if (name == Mequal || name == Mless || name == Mgreater
               || name == Mless_equal || name == Mgreater_equal)
@@ -3386,31 +3477,6 @@ take_action_list (MInputContext *ic, MPlist *action_list)
            };
        }
     }
-
-  if (ic->candidate_list)
-    {
-      M17N_OBJECT_UNREF (ic->candidate_list);
-      ic->candidate_list = NULL;
-    }
-  if (ic->cursor_pos > 0
-      && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
-                                    Mcandidate_list)))
-    {
-      ic->candidate_list = mtext_property_value (prop);
-      M17N_OBJECT_REF (ic->candidate_list);
-      ic->candidate_index
-       = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
-                               Mcandidate_index);
-      ic->candidate_from = mtext_property_start (prop);
-      ic->candidate_to = mtext_property_end (prop);
-    }
-
-  if (candidate_list != ic->candidate_list)
-    ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
-  if (candidate_index != ic->candidate_index)
-    ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
-  if (candidate_show != ic->candidate_show)
-    ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;    
   return 0;
 }
 
@@ -3430,6 +3496,14 @@ handle_key (MInputContext *ic)
   MSymbol alias = Mnil;
   int i;
 
+  if (ic_info->state_hook)
+    {
+      MDEBUG_PRINT1 ("  [IM] [%s] init-actions:",
+                    MSYMBOL_NAME (ic_info->state->name));
+      take_action_list (ic, ic_info->state_hook);
+      ic_info->state_hook = NULL;
+    }
+
   MDEBUG_PRINT2 ("  [IM] [%s] handle `%s'", 
                 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
 
@@ -3520,6 +3594,7 @@ handle_key (MInputContext *ic)
              && ic_info->key_head < ic_info->used)
            {
              MDEBUG_PRINT (" unhandled\n");
+             ic_info->state_hook = map->map_actions;
              return -1;
            }
 
@@ -3702,7 +3777,7 @@ open_im (MInputMethod *im)
 {
   MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
 
-  if (! im_info || ! im_info->states)
+  if (! im_info || ! im_info->states || MPLIST_LENGTH (im_info->states) == 0)
     MERROR (MERROR_IM, -1);
   im->info = im_info;
 
@@ -3811,7 +3886,37 @@ filter (MInputContext *ic, MSymbol key, void *arg)
   ic_info->key_unhandled = 0;
 
   do {
-    if (handle_key (ic) < 0)
+    MPlist *candidate_list = ic->candidate_list;
+    int candidate_index = ic->candidate_index;
+    int candidate_show = ic->candidate_show;
+    MTextProperty *prop;
+    int result = handle_key (ic);
+
+    if (ic->candidate_list)
+      {
+       M17N_OBJECT_UNREF (ic->candidate_list);
+       ic->candidate_list = NULL;
+      }
+    if (ic->cursor_pos > 0
+       && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
+                                      Mcandidate_list)))
+      {
+       ic->candidate_list = mtext_property_value (prop);
+       M17N_OBJECT_REF (ic->candidate_list);
+       ic->candidate_index
+         = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
+                                 Mcandidate_index);
+       ic->candidate_from = mtext_property_start (prop);
+       ic->candidate_to = mtext_property_end (prop);
+      }
+    if (candidate_list != ic->candidate_list)
+      ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
+    if (candidate_index != ic->candidate_index)
+      ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
+    if (candidate_show != ic->candidate_show)
+      ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;    
+
+    if (result < 0)
       {
        /* KEY was not handled.  Delete it from the current key sequence.  */
        if (ic_info->used > 0)
@@ -3845,7 +3950,7 @@ filter (MInputContext *ic, MSymbol key, void *arg)
 
   if (mtext_nchars (ic->produced) > 0)
     {
-      if (mdebug__flag & mdebug_mask)
+      if (MDEBUG_FLAG ())
        {
          MDEBUG_PRINT1 ("\n  [IM] [%s] (produced",
                         MSYMBOL_NAME (ic_info->state->name));
@@ -3918,24 +4023,24 @@ dump_im_map (MPlist *map_list, int indent)
   memset (prefix, 32, indent);
   prefix[indent] = '\0';
 
-  fprintf (stderr, "(\"%s\" ", msymbol_name (key));
+  fprintf (mdebug__output, "(\"%s\" ", msymbol_name (key));
   if (map->map_actions)
     mdebug_dump_plist (map->map_actions, indent + 2);
   if (map->submaps)
     {
       MPLIST_DO (map_list, map->submaps)
        {
-         fprintf (stderr, "\n%s  ", prefix);
+         fprintf (mdebug__output, "\n%s  ", prefix);
          dump_im_map (map_list, indent + 2);
        }
     }
   if (map->branch_actions)
     {
-      fprintf (stderr, "\n%s  (branch\n%s    ", prefix, prefix);
+      fprintf (mdebug__output, "\n%s  (branch\n%s    ", prefix, prefix);
       mdebug_dump_plist (map->branch_actions, indent + 4);
-      fprintf (stderr, ")");      
+      fprintf (mdebug__output, ")");      
     }
-  fprintf (stderr, ")");
+  fprintf (mdebug__output, ")");
 }
 
 
@@ -3949,16 +4054,16 @@ dump_im_state (MIMState *state, int indent)
   memset (prefix, 32, indent);
   prefix[indent] = '\0';
 
-  fprintf (stderr, "(%s", msymbol_name (state->name));
+  fprintf (mdebug__output, "(%s", msymbol_name (state->name));
   if (state->map->submaps)
     {
       MPLIST_DO (map_list, state->map->submaps)
        {
-         fprintf (stderr, "\n%s  ", prefix);
+         fprintf (mdebug__output, "\n%s  ", prefix);
          dump_im_map (map_list, indent + 2);
        }
     }
-  fprintf (stderr, ")");
+  fprintf (mdebug__output, ")");
 }
 
 \f
@@ -4042,8 +4147,19 @@ minput__char_to_key (int c)
 /*=*/
 
 /***en
-    @name Variables: Predefined symbols for callback commands.
+    @brief Symbol whose name is "input-method".
+ */
+/***ja
+    @brief "input-method" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
+ */
+MSymbol Minput_method;
 
+/***en
+    @name Variables: Predefined symbols for callback commands.  */
+/***ja
+    @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.  */
+/*** @{ */ 
+/***en
     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).  
@@ -4051,7 +4167,7 @@ minput__char_to_key (int c)
     Most of them do not require extra argument nor return any value;
     exceptions are these:
 
-    Minput_get_surrounding_text: When a callback function assigned for
+    @b Minput_get_surrounding_text: When a callback function assigned for
     this command is called, the first element of #MInputContext::plist
     has key #Minteger and the value specifies which portion of the
     surrounding text should be retrieved.  If the value is positive,
@@ -4073,7 +4189,7 @@ minput__char_to_key (int c)
     function should return without changing the first element of
     #MInputContext::plist.
 
-    Minput_delete_surrounding_text: When a callback function assigned
+    @b Minput_delete_surrounding_text: When a callback function assigned
     for this command is called, the first element of
     #MInputContext::plist has key #Minteger and the value specifies
     which portion of the surrounding text should be deleted in the
@@ -4081,8 +4197,6 @@ minput__char_to_key (int c)
     function must delete the specified text.  It should not alter
     #MInputContext::plist.  */ 
 /***ja
-    @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
-
     ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND 
     °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
 
@@ -4111,9 +4225,6 @@ minput__char_to_key (int c)
     Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
     ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥­¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
     #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£  */ 
-/*** @{ */ 
-/*=*/
-
 MSymbol Minput_preedit_start;
 MSymbol Minput_preedit_done;
 MSymbol Minput_preedit_draw;
@@ -4153,18 +4264,18 @@ MSymbol Minput_focus_move;
 
 /*=*/
 /***en
-    @name Variables: Predefined symbols used in input method information.
-
+    @name Variables: Predefined symbols used in input method information.  */
+/***ja
+    @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.  */
+/*** @{ */ 
+/*=*/
+/***en
     These are the predefined symbols describing status of input method
     command and variable, and are used in a return value of
     minput_get_command () and minput_get_variable ().  */
 /***ja
-    @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
-
     ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
     minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£  */
-/*** @{ */ 
-/*=*/
 MSymbol Minherited;
 MSymbol Mcustomized;
 MSymbol Mconfigured;
@@ -4233,6 +4344,10 @@ MInputDriver minput_default_driver;
 
 MInputDriver *minput_driver;
 
+/*=*/
+/***
+    The variable #Minput_driver is a symbol for a foreign input method.
+    See @ref foreign-input-method "foreign input method" for the detail.  */
 MSymbol Minput_driver;
 
 /*=*/
@@ -4303,7 +4418,11 @@ minput_open_im (MSymbol language, MSymbol name, void *arg)
   MDEBUG_PRINT2 ("  [IM] opening (%s %s) ... ",
                 msymbol_name (language), msymbol_name (name));
   if (language)
-    driver = minput_driver;
+    {
+      if (name == Mnil)
+       MERROR (MERROR_IM, NULL);
+      driver = minput_driver;
+    }
   else
     {
       driver = (MInputDriver *) msymbol_get (name, Minput_driver);
@@ -4357,8 +4476,8 @@ minput_close_im (MInputMethod *im)
 
     The minput_create_ic () function creates an input context object
     associated with input method $IM, and calls callback functions
-    corresponding to #Minput_preedit_start, #Minput_status_start, and
-    #Minput_status_draw in this order.
+    corresponding to @b Minput_preedit_start, @b Minput_status_start, and
+    @b Minput_status_draw in this order.
 
     @return
     If an input context is successfully created, minput_create_ic ()
@@ -4369,7 +4488,7 @@ minput_close_im (MInputMethod *im)
 
     ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
     ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
-    #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
+    @b Minput_preedit_start, @b Minput_status_start, @b Minput_status_draw
     ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
 
     @return
@@ -4421,8 +4540,8 @@ 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 #Minput_candidates_done in this order.  */
+    callback functions corresponding to @b Minput_preedit_done,
+    @b Minput_status_done, and @b Minput_candidates_done in this order.  */
 
 /***ja
     @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
@@ -4430,7 +4549,7 @@ minput_create_ic (MInputMethod *im, void *arg)
     ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
     ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic () 
     ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï 
-    #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done 
+    @b Minput_preedit_done, @b Minput_status_done, @b Minput_candidates_done 
     ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
   */
 
@@ -4460,8 +4579,8 @@ 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
-    #Minput_candidates_draw if the preedit text, the status, and the
+    @b Minput_preedit_draw, @b Minput_status_draw, and
+    @b Minput_candidates_draw if the preedit text, the status, and the
     current candidate are changed respectively.
 
     To make the input method commit the current preedit text (if any)
@@ -4469,14 +4588,14 @@ minput_destroy_ic (MInputContext *ic)
     $KEY.
 
     To inform the input method about the focus-out event, call this
-    function with #Minput_focus_out as $KEY.
+    function with @b Minput_focus_out as $KEY.
 
     To inform the input method about the focus-in event, call this
-    function with #Minput_focus_in as $KEY.
+    function with @b Minput_focus_in as $KEY.
 
     To inform the input method about the focus-move event (i.e. input
     spot change within the same input context), call this function
-    with #Minput_focus_move as $KEY.
+    with @b Minput_focus_move as $KEY.
 
     @return
     If $KEY is filtered out, this function returns 1.  In that case,
@@ -4489,8 +4608,8 @@ minput_destroy_ic (MInputContext *ic)
 
     ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥­¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC 
     ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥­¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
-    #Minput_preedit_draw, #Minput_status_draw,
-    #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
+    @b Minput_preedit_draw, @b Minput_status_draw,
+    @b Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
 
     @return 
     $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
@@ -4655,20 +4774,20 @@ minput_toggle (MInputContext *ic)
     @brief Reset an input context.
 
     The minput_reset_ic () function resets input context $IC by
-    calling a callback function corresponding to #Minput_reset.  It
+    calling a callback function corresponding to @b Minput_reset.  It
     resets the status of $IC to its initial one.  As the
     current preedit text is deleted without commitment, if necessary,
-    call minput_filter () with the arg @r key #Mnil to force the input
+    call minput_filter () with the arg @b key #Mnil to force the input
     method to commit the preedit in advance.  */
 
 /***ja
     @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
 
-    ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
+    ´Ø¿ô minput_reset_ic () ¤Ï @b Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
     ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
     ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥­¥¹
     ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
-    ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
+    ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @b key #Mnil ¤Ç¸Æ¤ó¤Ç
     ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥­¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£  */
 
 void
@@ -4774,7 +4893,8 @@ minput_get_title_icon (MSymbol language, MSymbol name)
     ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
     ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
 
-    @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥­¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
+    @return
+    »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥­¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
     #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
     () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥­¥¹¥È¤¬Ìµ¤±
     ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
@@ -4822,7 +4942,7 @@ minput_get_description (MSymbol language, MSymbol name)
 
     If $COMMAND is #Mnil, information about all commands is returned.
 
-    The return value is a @e well-formed plist (#m17nPlist) of this
+    The return value is a @e well-formed plist (@ref m17nPlist) of this
     format:
 @verbatim
   ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
@@ -4833,11 +4953,11 @@ minput_get_description (MSymbol language, MSymbol name)
     command has no description.
 
     @c STATUS is a symbol representing how the key assignment is decided.
-    The value is #Mnil (the default key assignment), #Mcustomized (the
+    The value is #Mnil (the default key assignment), @b Mcustomized (the
     key assignment is customized by per-user customization file), or
-    #Mconfigured (the key assignment is set by the call of
+    @b Mconfigured (the key assignment is set by the call of
     minput_config_command ()).  For a local command only, it may also
-    be #Minherited (the key assignment is inherited from the
+    be @b Minherited (the key assignment is inherited from the
     corresponding global command).
 
     @c KEYSEQ is a plist of one or more symbols representing a key
@@ -4876,7 +4996,7 @@ minput_get_description (MSymbol language, MSymbol name)
 
     $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
 
-    Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
+    Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
 
 @verbatim
   ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
@@ -4887,11 +5007,11 @@ minput_get_description (MSymbol language, MSymbol name)
     ¤Ï #Mnil ¤Ç¤¢¤ë¡£
 
     @c STATUS ¤Ï¥­¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
-    ¤Ç¤¢¤ê¡¢¤½¤ÎÃͤϠ#Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
+    ¤Ç¤¢¤ê¡¢¤½¤ÎÃͤϠ#Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, @b Mcustomized ¡Ê¥æ¡¼
     ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
-    #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
+    @b Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
     ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
-    #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
+    @b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
     ¤Ç¤â¤è¤¤¡£
 
     @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
@@ -5220,7 +5340,7 @@ minput_config_command (MSymbol language, MSymbol name, MSymbol command,
     If $VARIABLE is #Mnil, information about all variables is
     returned.
 
-    The return value is a @e well-formed plist (#m17nPlist) of this
+    The return value is a @e well-formed plist (@ref m17nPlist) of this
     format:
 @verbatim
   ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
@@ -5231,10 +5351,10 @@ minput_config_command (MSymbol language, MSymbol name, MSymbol command,
     variable has no description.
 
     @c STATUS is a symbol representing how the value is decided.  The
-    value is #Mnil (the default value), #Mcustomized (the value is
-    customized by per-user customization file), or #Mconfigured (the
+    value is #Mnil (the default value), @b Mcustomized (the value is
+    customized by per-user customization file), or @b Mconfigured (the
     value is set by the call of minput_config_variable ()).  For a
-    local variable only, it may also be #Minherited (the value is
+    local variable only, it may also be @b Minherited (the value is
     inherited from the corresponding global variable).
 
     @c VALUE is the initial value of the variable.  If the key of this
@@ -5280,7 +5400,7 @@ minput_config_command (MSymbol language, MSymbol name, MSymbol command,
 
     $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
 
-    Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
+    Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
 @verbatim
   ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
 @endverbatim
@@ -5291,10 +5411,10 @@ minput_config_command (MSymbol language, MSymbol name, MSymbol command,
     #Mnil ¤Ç¤¢¤ë¡£
 
     @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
-    @c STATUS ¤ÎÃͤϠ#Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
-    ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
+    @c STATUS ¤ÎÃͤϠ#Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, @b Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
+    ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, @b Mconfigured
     ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
-    ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
+    ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢@b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
     ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
 
     @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ­¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
@@ -5559,12 +5679,12 @@ minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
     
     The minput_config_file () function returns the absolute path name
     of per-user customization file into which minput_save_config ()
-    save configurations.  It is usually @c "config.mic" under the
-    directory @c ".m17n.d" of user's home directory.  It is not assured
-    that the file of the returned name exists nor is
-    readable/writable.  If minput_save_config () fails and returns -1,
-    an application program might check the file, make it
-    writable (if possible), and try minput_save_config () again.
+    save configurations.  It is usually @c config.mic under the
+    directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
+    directory).  It is not assured that the file of the returned name
+    exists nor is readable/writable.  If minput_save_config () fails
+    and returns -1, an application program might check the file, make
+    it writable (if possible), and try minput_save_config () again.
 
     @return
 
@@ -5815,6 +5935,153 @@ minput_save_config (void)
   return (ret < 0 ? -1 : 1);
 }
 
+/***en
+    @brief List available input methods.
+
+    The minput_list () function returns a list of currently available
+    input methods whose language is $LANGUAGE.  If $LANGUAGE is #Mnil,
+    all input methods are listed.
+
+    @return
+    The returned value is a plist of this form:
+       ((LANGUAGE-NAME INPUT-METHOD-NAME SANE) ...)
+    The third element SANE of each input method is #Mt if it can be
+    successfully used, or #Mnil if it has some problem (e.g. syntax
+    error of MIM file, unavailable external module, unavailable
+    including input method).  */
+
+#if EXAMPLE_CODE
+#include <stdio.h>
+#include <string.h>
+#include <m17n.h>
+
+int
+main (int argc, char **argv)
+{
+  MPlist *imlist, *pl;
+
+  M17N_INIT ();
+  imlist = minput_list ((argc > 1) ? msymbol (argv[1]) : Mnil);
+  for (pl = imlist; mplist_key (pl) != Mnil; pl = mplist_next (pl))
+    {
+      MPlist *p = mplist_value (pl);
+      MSymbol lang, name, sane;
+
+      lang = mplist_value (p);
+      p = mplist_next (p);
+      name = mplist_value (p);
+      p = mplist_next (p);
+      sane = mplist_value (p);
+
+      printf ("%s %s %s\n", msymbol_name (lang), msymbol_name (name),
+             sane == Mt ? "ok" : "no");
+    }
+
+  m17n_object_unref (imlist);
+  M17N_FINI ();
+  exit (0);
+}
+#endif
+
+MPlist *
+minput_list (MSymbol language)
+{
+  MPlist *plist, *pl;
+  MPlist *imlist = mplist ();
+  
+  MINPUT__INIT ();
+  plist = mdatabase_list (Minput_method, language, Mnil, Mnil);
+  if (! plist)
+    return imlist;
+  MPLIST_DO (pl, plist)
+    {
+      MDatabase *mdb = MPLIST_VAL (pl);
+      MSymbol *tag = mdatabase_tag (mdb);
+      MPlist *imdata, *p, *elm;
+      int num_maps = 0, num_states = 0;
+
+      if (tag[2] == Mnil)
+       continue;
+      imdata = mdatabase_load (mdb);
+      if (! imdata)
+       continue;
+      MPLIST_DO (p, imdata)
+       if (MPLIST_PLIST_P (p))
+         {
+           /* Check these basic functionarity:
+              All external modules (if any) are loadable.
+              All included input method (if any) are loadable.
+              At least one map is defined or included.
+              At least one state is defined or included. */
+           MPlist *elt = MPLIST_PLIST (p);
+           MSymbol key;
+
+           if (MFAILP (MPLIST_SYMBOL_P (elt)))
+             break;
+           key = MPLIST_SYMBOL (elt);
+           if (key == Mmap)
+             num_maps++;
+           else if (key == Mstate)
+             num_states++;
+           else if (key == Mmodule)
+             {
+               MPLIST_DO (elt, MPLIST_NEXT (elt))
+                 {
+                   MIMExternalModule *external;
+
+                   if (MFAILP (MPLIST_PLIST_P (elt)))
+                     break;
+                   external = load_external_module (MPLIST_PLIST (elt));
+                   if (MFAILP (external))
+                     break;
+                   unload_external_module (external);
+                 }
+               if (! MPLIST_TAIL_P (elt))
+                 break;
+             }
+           else if (key == Minclude)
+             {
+               MInputMethodInfo *im_info;
+
+               elt = MPLIST_NEXT (elt);
+               if (MFAILP (MPLIST_PLIST_P (elt)))
+                 break;
+               im_info = get_im_info_by_tags (MPLIST_PLIST (elt));
+               if (MFAILP (im_info))
+                 break;
+               elt = MPLIST_NEXT (elt);
+               if (MFAILP (MPLIST_SYMBOL_P (elt)))
+                 break;
+               key = MPLIST_SYMBOL (elt);
+               if (key == Mmap)
+                 {
+                   if (! im_info->maps)
+                     break;
+                   num_maps++;
+                 }
+               else if (key == Mstate)
+                 {
+                   if (! im_info->states)
+                     break;
+                   num_states++;
+                 }
+             }
+         }
+      elm = mplist ();
+      mplist_add (elm, Msymbol, tag[1]);
+      mplist_add (elm, Msymbol, tag[2]);
+      if (MPLIST_TAIL_P (p) && num_maps > 0 && num_states > 0)
+       mplist_add (elm, Msymbol, Mt);
+      else
+       mplist_add (elm, Msymbol, Mnil);
+      mplist_push (imlist, Mplist, elm);
+      M17N_OBJECT_UNREF (elm);
+      M17N_OBJECT_UNREF (imdata);
+    }
+  M17N_OBJECT_UNREF (plist);
+  return imlist;
+}
+
 /*=*/
 /*** @} */
 /*=*/
@@ -5835,7 +6102,7 @@ minput_save_config (void)
     The minput_get_variables () function returns a plist (#MPlist) of
     variables used to control the behavior of the input method
     specified by $LANGUAGE and $NAME.  The plist is @e well-formed
-    (#m17nPlist) of the following format:
+    (@ref m17nPlist) of the following format:
 
 @verbatim
     (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
@@ -5884,7 +6151,7 @@ minput_save_config (void)
 
     ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
     ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
-    (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
+    (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
     ²¼¤Î·Á¼°¤Ç¤¢¤ë¡£
 
 @verbatim
@@ -5971,7 +6238,7 @@ minput_get_variables (MSymbol language, MSymbol name)
 
     @return
     If the operation was successful, 0 is returned.  Otherwise -1 is
-    returned, and #merror_code is set to #MERROR_IM.  */
+    returned, and #merror_code is set to @c MERROR_IM.  */
 /***ja
     @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
 
@@ -5985,7 +6252,7 @@ minput_get_variables (MSymbol language, MSymbol name)
 
     @return
     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
-    #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£  */
+    #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£  */
 
 int
 minput_set_variable (MSymbol language, MSymbol name,
@@ -6154,7 +6421,7 @@ minput_get_commands (MSymbol language, MSymbol name)
 
     @return
     If the operation was successful, 0 is returned.  Otherwise -1 is
-    returned, and #merror_code is set to #MERROR_IM.  */
+    returned, and #merror_code is set to @c MERROR_IM.  */
 /***ja
     @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥­¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
 
@@ -6173,8 +6440,9 @@ minput_get_commands (MSymbol language, MSymbol name)
     ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ­
     ¸ú¤Ë¤Ê¤ë¡£
 
-    @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
-    #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£  */
+    @return 
+    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
+    #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£  */
 
 int
 minput_assign_command_keys (MSymbol language, MSymbol name,
@@ -6244,16 +6512,18 @@ minput_callback (MInputContext *ic, MSymbol command)
     @brief Dump an input method.
 
     The mdebug_dump_im () function prints the input method $IM in a
-    human readable way to the stderr.  $INDENT specifies how many
-    columns to indent the lines but the first one.
+    human readable way to the stderr or to what specified by the
+    environment variable MDEBUG_OUTPUT_FILE.  $INDENT specifies how
+    many columns to indent the lines but the first one.
 
     @return
     This function returns $IM.  */
 /***ja
     @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
 
-    ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr 
-    ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
+    ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤òɸ½à¥¨¥é¡¼½ÐÎϤ⤷¤¯¤Ï
+    ´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç½Ð
+    ÎϤ¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£  */
@@ -6268,7 +6538,7 @@ mdebug_dump_im (MInputMethod *im, int indent)
   memset (prefix, 32, indent);
   prefix[indent] = '\0';
 
-  fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
+  fprintf (mdebug__output, "(input-method %s %s ", msymbol_name (im->language),
           msymbol_name (im->name));
   mdebug_dump_mtext (im_info->title, 0, 0);
   if (im->name != Mnil)
@@ -6277,11 +6547,11 @@ mdebug_dump_im (MInputMethod *im, int indent)
 
       MPLIST_DO (state, im_info->states)
        {
-         fprintf (stderr, "\n%s  ", prefix);
+         fprintf (mdebug__output, "\n%s  ", prefix);
          dump_im_state (MPLIST_VAL (state), indent + 2);
        }
     }
-  fprintf (stderr, ")");
+  fprintf (mdebug__output, ")");
   return im;
 }