X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Finput.c;h=2de5547311bf64de17a67685c99a0c162b85773c;hb=02c5d90ea3694c6fa6422de2ad4cbdfda46ce854;hp=d9b9380dcf1a6de99e6c9ad2758c4a9662ee28cd;hpb=dd9028abfb947b99a5d471a0de0013ed9eac5847;p=m17n%2Fm17n-lib.git diff --git a/src/input.c b/src/input.c index d9b9380..2de5547 100644 --- a/src/input.c +++ b/src/input.c @@ -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 @@ -50,19 +50,19 @@ input event to an input key by himself. See the documentation of the function minput_event_to_key () for the detail. -
  • Foreign Input Method +
  • 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. @@ -106,11 +106,11 @@ ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î ÀâÌÀ¤ò»²¾È¡£ -
  • ³°ÉôÆþÎϥ᥽¥Ã¥É +
  • ³°ÉôÆþÎϥ᥽¥Ã¥É @anchor foreign-input-method ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ° Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê - ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò + ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï #Minput_driver ¤ò ¥­¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤ ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö @@ -118,7 +118,7 @@ ÍøÊØÀ­¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿ ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î - @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý + #Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ @@ -153,7 +153,7 @@ #include #endif -#include "m17n-gui.h" +#include "m17n.h" #include "m17n-misc.h" #include "internal.h" #include "mtext.h" @@ -163,18 +163,16 @@ #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; /** Symbols for actions. */ static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift; -static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle; +static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop; static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater; static MSymbol Mless_equal, Mgreater_equal; static MSymbol Mcond; @@ -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); -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"); @@ -402,6 +446,7 @@ fully_initialize () Mmove = msymbol ("move"); Mmark = msymbol ("mark"); Mpushback = msymbol ("pushback"); + Mpop = msymbol ("pop"); Mundo = msymbol ("undo"); Mcall = msymbol ("call"); Mshift = msymbol ("shift"); @@ -429,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"); @@ -488,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) { @@ -584,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); @@ -603,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; @@ -617,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); @@ -641,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 == '@') @@ -654,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) @@ -664,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); @@ -716,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); @@ -814,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)) @@ -821,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)) @@ -915,7 +975,8 @@ parse_action_list (MPlist *plist, MPlist *macros) MERROR (MERROR_IM, -1); } else if (action_name == Mshow || action_name == Mhide - || action_name == Mcommit || action_name == Munhandle) + || action_name == Mcommit || action_name == Munhandle + || action_name == Mpop) ; else if (action_name == Mcond) { @@ -1068,34 +1129,48 @@ load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map) if (branch_actions) M17N_OBJECT_REF (branch_actions); } - else if (im_info->maps - && (plist = (MPlist *) mplist_get (im_info->maps, map_name))) + else if (im_info->maps) { - MPLIST_DO (plist, plist) + plist = (MPlist *) mplist_get (im_info->maps, map_name); + if (! plist && im_info->configured_vars) { - MPlist *keylist, *map_actions; + MPlist *p = mplist__assq (im_info->configured_vars, map_name); - if (! MPLIST_PLIST_P (plist)) - MERROR (MERROR_IM, -1); - keylist = MPLIST_PLIST (plist); - map_actions = MPLIST_NEXT (keylist); - if (MPLIST_SYMBOL_P (keylist)) + if (p && MPLIST_PLIST_P (p)) + { + p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)))); + if (MPLIST_SYMBOL_P (p)) + plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p)); + } + } + if (plist) + { + MPLIST_DO (plist, plist) { - MSymbol command = MPLIST_SYMBOL (keylist); - MPlist *pl; + MPlist *keylist, *map_actions; - if (MFAILP (command != Mat_reload)) - continue; - pl = resolve_command (im_info->configured_cmds, command); - if (MFAILP (pl)) - continue; - MPLIST_DO (pl, pl) - load_translation (map, pl, map_actions, branch_actions, + if (! MPLIST_PLIST_P (plist)) + MERROR (MERROR_IM, -1); + keylist = MPLIST_PLIST (plist); + map_actions = MPLIST_NEXT (keylist); + if (MPLIST_SYMBOL_P (keylist)) + { + MSymbol command = MPLIST_SYMBOL (keylist); + MPlist *pl; + + if (MFAILP (command != Mat_reload)) + continue; + pl = resolve_command (im_info->configured_cmds, command); + if (MFAILP (pl)) + continue; + MPLIST_DO (pl, pl) + load_translation (map, pl, map_actions, branch_actions, + im_info->macros); + } + else + load_translation (map, keylist, map_actions, branch_actions, im_info->macros); } - else - load_translation (map, keylist, map_actions, branch_actions, - im_info->macros); } } @@ -1103,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. */ @@ -1117,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); @@ -1127,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; @@ -1146,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)) { @@ -1168,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 @@ -1305,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); @@ -1446,14 +1527,12 @@ update_custom_info (void) if (! MPLIST_SYMBOL_P (p)) continue; name = MPLIST_SYMBOL (p); - if (language == Mnil || name == Mnil) - continue; p = MPLIST_NEXT (p); if (MPLIST_TAIL_P (p)) extra = Mnil; else if (MPLIST_SYMBOL_P (p)) extra = MPLIST_SYMBOL (p); - else + if (language == Mnil || (name == Mnil && extra == Mnil)) continue; im_info = new_im_info (NULL, language, name, extra, im_custom_list); load_im_info (im_data, im_info); @@ -1479,6 +1558,8 @@ update_global_info (void) { MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal); + if (! mdb) + return -1; global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list); } if (! global_info->mdb @@ -1491,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. */ @@ -1548,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)) @@ -1579,6 +1662,19 @@ reload_im_info (MInputMethodInfo *im_info) fini_im_info (im_info); load_im_info (plist, im_info); M17N_OBJECT_UNREF (plist); + if (! im_info->cmds) + im_info->cmds = mplist (); + if (! im_info->vars) + im_info->vars = mplist (); + if (! im_info->title) + { + MSymbol name = im_info->name; + + im_info->title = (name == Mnil ? mtext () + : mtext_from_data (MSYMBOL_NAME (name), + MSYMBOL_NAMELEN (name), + MTEXT_FORMAT_US_ASCII)); + } return 1; } @@ -1627,7 +1723,7 @@ check_description (MPlist *plist) { M17N_OBJECT_UNREF (mt); mt = mtext__from_data (translated, strlen (translated), - MTEXT_FORMAT_UTF_8, 0); + MTEXT_FORMAT_UTF_8, 1); } } #endif @@ -1729,54 +1825,53 @@ config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds, MPlist *config_cmds) { MPlist *global = NULL, *custom = NULL, *config = NULL; - MSymbol name; + MSymbol name = MPLIST_SYMBOL (plist); MSymbol status; - MPlist *description = NULL, *keyseq; + MPlist *description, *keyseq; + + if (global_cmds && (global = mplist__assq (global_cmds, name))) + global = MPLIST_NEXT (MPLIST_PLIST (global)); - name = MPLIST_SYMBOL (plist); plist = MPLIST_NEXT (plist); if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist)) - description = plist; - else if (global_cmds && ((global = mplist__assq (global_cmds, name)))) - description = global = MPLIST_NEXT (MPLIST_PLIST (global)); - if (MPLIST_TAIL_P (plist)) { - if (! global - && global_cmds && ((global = mplist__assq (global_cmds, name)))) - global = MPLIST_NEXT (MPLIST_PLIST (global)); - if (global) - { - keyseq = MPLIST_NEXT (global); - status = Minherited; - } - else - { - keyseq = plist; - status = Mnil; - } + description = plist; + plist = MPLIST_NEXT (plist); } else { - keyseq = MPLIST_NEXT (plist); + description = global; + if (! MPLIST_TAIL_P (plist)) + plist = MPLIST_NEXT (plist); + } + if (MPLIST_TAIL_P (plist) && global) + { + keyseq = MPLIST_NEXT (global); + status = Minherited; + } + else + { + keyseq = plist; status = Mnil; } if (config_cmds && (config = mplist__assq (config_cmds, name))) { + status = Mconfigured; config = MPLIST_NEXT (MPLIST_PLIST (config)); if (! MPLIST_TAIL_P (config)) - { - keyseq = MPLIST_NEXT (config); - status = Mconfigured; - } + keyseq = config; } else if (custom_cmds && (custom = mplist__assq (custom_cmds, name))) { - custom = MPLIST_NEXT (MPLIST_PLIST (custom)); - if (! MPLIST_TAIL_P (custom)) + MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom))); + + if (MPLIST_TAIL_P (this_keyseq)) + mplist__pop_unref (custom); + else { - keyseq = MPLIST_NEXT (custom); status = Mcustomized; + keyseq = this_keyseq; } } @@ -1896,7 +1991,7 @@ check_variable_value (MPlist *val, MPlist *global) } } - return (MPLIST_TAIL_P (valids)); + return (! MPLIST_TAIL_P (valids)); } /* Load variable defitions from PLIST into IM_INFO->vars. @@ -2054,21 +2149,24 @@ config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars, if (config_vars && (config = mplist__assq (config_vars, name))) { + status = Mconfigured; config = MPLIST_NEXT (MPLIST_PLIST (config)); if (! MPLIST_TAIL_P (config)) { - value = MPLIST_NEXT (config); + value = config; if (MFAILP (check_variable_value (value, global ? global : plist))) value = NULL; - status = Mconfigured; } } else if (custom_vars && (custom = mplist__assq (custom_vars, name))) { - custom = MPLIST_NEXT (MPLIST_PLIST (custom)); - if (! MPLIST_TAIL_P (custom)) + MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom))); + + if (MPLIST_TAIL_P (this_value)) + mplist__pop_unref (custom); + else { - value = MPLIST_NEXT (custom); + value = this_value; if (MFAILP (check_variable_value (value, global ? global : plist))) value = NULL; status = Mcustomized; @@ -2198,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) @@ -2289,13 +2391,23 @@ 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); } static int take_action_list (MInputContext *ic, MPlist *action_list); -static void preedit_commit (MInputContext *ic); +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) @@ -2323,7 +2435,15 @@ shift_state (MInputContext *ic, MSymbol state_name) state = (MIMState *) MPLIST_VAL (im_info->states); } - MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name)); + if (MDEBUG_FLAG ()) + { + if (orig_state) + MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n", + MSYMBOL_NAME (orig_state->name), + MSYMBOL_NAME (state->name)); + else + MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name)); + } /* Enter the new state. */ ic_info->state = state; @@ -2332,10 +2452,10 @@ shift_state (MInputContext *ic, MSymbol state_name) if (state == (MIMState *) MPLIST_VAL (im_info->states) && orig_state) /* We have shifted to the initial state. */ - preedit_commit (ic); + 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)) { @@ -2352,12 +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_PRINT (" init-actions:"); - take_action_list (ic, ic_info->map->map_actions); - } + ic_info->state_hook = ic_info->map->map_actions; } } @@ -2439,9 +2554,18 @@ preedit_insert (MInputContext *ic, int pos, MText *mt, int c) int nchars = mt ? mtext_nchars (mt) : 1; if (mt) - mtext_ins (ic->preedit, pos, mt); + { + mtext_ins (ic->preedit, pos, mt); + MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt)); + } else - mtext_ins_char (ic->preedit, pos, c, 1); + { + mtext_ins_char (ic->preedit, pos, c, 1); + if (c < 0x7F) + MDEBUG_PRINT1 ("('%c')", c); + else + MDEBUG_PRINT1 ("(U+%04X)", c); + } adjust_markers (ic, pos, pos, nchars); ic->preedit_changed = 1; } @@ -2477,7 +2601,7 @@ preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c) static void -preedit_commit (MInputContext *ic) +preedit_commit (MInputContext *ic, int need_prefix) { MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; int preedit_len = mtext_nchars (ic->preedit); @@ -2491,10 +2615,13 @@ preedit_commit (MInputContext *ic) 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; + if (need_prefix) + MDEBUG_PRINT1 ("\n [IM] [%s]", + MSYMBOL_NAME (ic_info->state->name)); MDEBUG_PRINT (" (commit"); for (i = 0; i < mtext_nchars (ic->preedit); i++) MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i)); @@ -2571,6 +2698,7 @@ update_candidate (MInputContext *ic, MTextProperty *prop, int idx) int ingroup_index = idx - start; MText *mt; + candidate_list = mplist_copy (candidate_list); if (MPLIST_MTEXT_P (group)) { mt = MPLIST_MTEXT (group); @@ -2589,6 +2717,7 @@ update_candidate (MInputContext *ic, MTextProperty *prop, int idx) to = from + mtext_nchars (mt); } mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list); + M17N_OBJECT_UNREF (candidate_list); mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx); ic->cursor_pos = to; } @@ -2607,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) { @@ -2709,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) { @@ -2721,82 +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 (plist && column > 0) + if (column == 0) + return plist; + + 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); } - 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; @@ -2863,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) @@ -2896,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)); @@ -2915,9 +3057,12 @@ take_action_list (MInputContext *ic, MPlist *action_list) preedit_insert (ic, ic->cursor_pos, mt, 0); len = mtext_nchars (mt); } + pl = mplist_copy (plist); + M17N_OBJECT_UNREF (plist); mtext_put_prop (ic->preedit, ic->cursor_pos - len, ic->cursor_pos, - Mcandidate_list, plist); + Mcandidate_list, pl); + M17N_OBJECT_UNREF (pl); mtext_put_prop (ic->preedit, ic->cursor_pos - len, ic->cursor_pos, Mcandidate_index, (void *) 0); @@ -3017,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) @@ -3041,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) @@ -3140,6 +3286,11 @@ take_action_list (MInputContext *ic, MPlist *action_list) } } } + else if (name == Mpop) + { + if (ic_info->key_head < ic_info->used) + MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1); + } else if (name == Mcall) { MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; @@ -3158,8 +3309,8 @@ take_action_list (MInputContext *ic, MPlist *action_list) = (MIMExternalModule *) mplist_get (im_info->externals, module); if (external) - func = (MIMExternalFunc) mplist_get (external->func_list, - func_name); + func = ((MIMExternalFunc) + mplist_get_func (external->func_list, func_name)); } if (! func) continue; @@ -3197,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); @@ -3226,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) @@ -3245,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) @@ -3307,11 +3457,11 @@ take_action_list (MInputContext *ic, MPlist *action_list) } else if (name == Mcommit) { - preedit_commit (ic); + preedit_commit (ic, 0); } else if (name == Munhandle) { - preedit_commit (ic); + preedit_commit (ic, 0); return -1; } else @@ -3327,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; } @@ -3371,8 +3496,16 @@ handle_key (MInputContext *ic) MSymbol alias = Mnil; int i; - MDEBUG_PRINT2 (" [IM] handle `%s' in state %s", - msymbol_name (key), MSYMBOL_NAME (ic_info->state->name)); + 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)); if (map->submaps) { @@ -3454,11 +3587,14 @@ handle_key (MInputContext *ic) { /* The above branch actions didn't change the state. */ - /* 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) + /* If MAP is the root map of the initial state, and there + still exist an unhandled key, it means that the current + input method can not handle it. */ + if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map + && ic_info->key_head < ic_info->used) { MDEBUG_PRINT (" unhandled\n"); + ic_info->state_hook = map->map_actions; return -1; } @@ -3468,9 +3604,10 @@ handle_key (MInputContext *ic) current state. */ shift_state (ic, ic_info->state->name); } - else + else if (! map->branch_actions) { - /* MAP is the root map. Shift to the initial state. */ + /* MAP is the root map without any default branch + actions. Shift to the initial state. */ shift_state (ic, Mnil); } } @@ -3521,7 +3658,7 @@ init_ic_info (MInputContext *ic) { MIMExternalModule *external = MPLIST_VAL (plist); MIMExternalFunc func - = (MIMExternalFunc) mplist_get (external->func_list, Minit); + = (MIMExternalFunc) mplist_get_func (external->func_list, Minit); if (func) (func) (func_args); @@ -3550,7 +3687,7 @@ fini_ic_info (MInputContext *ic) { MIMExternalModule *external = MPLIST_VAL (plist); MIMExternalFunc func - = (MIMExternalFunc) mplist_get (external->func_list, Mfini); + = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini); if (func) (func) (func_args); @@ -3608,8 +3745,20 @@ re_init_ic (MInputContext *ic, int reload) fini_ic_info (ic); if (reload) reload_im_info (im_info); + if (! im_info->states) + { + struct MIMState *state; + + M17N_OBJECT (state, free_state, MERROR_IM); + state->name = msymbol ("init"); + state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0); + MSTRUCT_CALLOC (state->map, MERROR_IM); + im_info->states = mplist (); + mplist_add (im_info->states, state->name, state); + } init_ic_info (ic); shift_state (ic, Mnil); + ic->status_changed = status_changed; ic->preedit_changed = preedit_changed; ic->cursor_pos_changed = cursor_pos_changed; @@ -3628,7 +3777,7 @@ open_im (MInputMethod *im) { MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil); - if (! im_info) + if (! im_info || ! im_info->states || MPLIST_LENGTH (im_info->states) == 0) MERROR (MERROR_IM, -1); im->info = im_info; @@ -3737,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) @@ -3767,23 +3946,21 @@ filter (MInputContext *ic, MSymbol key, void *arg) /* If the current map is the root of the initial state, we should produce any preedit text in ic->produced. */ if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map) - preedit_commit (ic); + preedit_commit (ic, 1); if (mtext_nchars (ic->produced) > 0) { - MSymbol lang = msymbol_get (ic->im->language, Mlanguage); - - if (mdebug__flag & mdebug_mask) + if (MDEBUG_FLAG ()) { - MDEBUG_PRINT (" (produced"); + MDEBUG_PRINT1 ("\n [IM] [%s] (produced", + MSYMBOL_NAME (ic_info->state->name)); for (i = 0; i < mtext_nchars (ic->produced); i++) MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i)); MDEBUG_PRINT (")"); } - if (lang != Mnil) - mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced), - Mlanguage, ic->im->language); + mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced), + Mlanguage, ic->im->language); } if (ic_info->commit_key_head > 0) { @@ -3846,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, ")"); } @@ -3877,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, ")"); } @@ -3924,8 +4101,8 @@ minput__init () minput_default_driver.filter = filter; minput_default_driver.lookup = lookup; minput_default_driver.callback_list = mplist (); - mplist_put (minput_default_driver.callback_list, Minput_reset, - (void *) reset_ic); + mplist_put_func (minput_default_driver.callback_list, Minput_reset, + M17N_FUNC (reset_ic)); minput_driver = &minput_default_driver; fully_initialized = 0; @@ -3970,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). @@ -3979,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, @@ -4001,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 @@ -4009,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 »²¾È)¡£ @@ -4039,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; @@ -4081,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; @@ -4161,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; /*=*/ @@ -4231,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); @@ -4285,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 () @@ -4297,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 @@ -4349,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 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë. @@ -4358,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 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£ */ @@ -4388,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) @@ -4397,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, @@ -4417,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 ¤òÊÖ¤¹¡£ @@ -4583,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 @@ -4702,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 ¤òÊÖ¤¹¡£ */ @@ -4750,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 ...]) ...) @@ -4761,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 - key assignment is customized by per-user configuration file), or - #Mconfigured (the key assignment is set by the call of + The value is #Mnil (the default key assignment), @b Mcustomized (the + key assignment is customized by per-user customization file), or + @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 @@ -4804,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 ...]) ...) @@ -4814,12 +5006,13 @@ minput_get_description (MSymbol language, MSymbol name) @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë ¤Ï #Mnil ¤Ç¤¢¤ë¡£ - @c STATUS ¤Ï¥­¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢ - ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶ - Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured - ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î - ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë - ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£ + @c STATUS ¤Ï¥­¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë + ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, @b Mcustomized ¡Ê¥æ¡¼ + ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, + @b Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë + ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢ + @b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë + ¤Ç¤â¤è¤¤¡£ @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥­¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢ @@ -4849,8 +5042,8 @@ get_im_command_description (MSymbol language, MSymbol name, MSymbol command) if (! cmds) return NULL; - plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */ - plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */ + plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */ + plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */ return (mplist_key (plist) == Mtext ? (MText *) mplist_value (plist) : NULL); @@ -4886,12 +5079,16 @@ minput_get_command (MSymbol language, MSymbol name, MSymbol command) If $KEYSEQLIST is a non-empty plist, it must be a list of key sequences, and each key sequence must be a plist of symbols. - If $KEYSEQLIST is an empty plist, the command becomes unusable. + If $KEYSEQLIST is an empty plist, any configuration and + customization of the command are cancelled, and default key + sequences become effective. + + If $KEYSEQLIST is NULL, the configuration of the command is + canceled, and the original key sequences (what saved in per-user + customization file, or the default one) become effective. - If $KEYSEQLIST is NULL, the configuration of the command for the - input method is canceled, and the default key sequences become - effective. In such case, if $COMMAND is #Mnil, configurations for - all commands of the input method are canceled. + In the latter two cases, $COMMAND can be #Mnil to make all the + commands of the input method the target of the operation. If $NAME is #Mnil, this function configures the key assignment of a global command, not that of a specific input method. @@ -4899,11 +5096,10 @@ minput_get_command (MSymbol language, MSymbol name, MSymbol command) The configuration takes effect for input methods opened or re-opened later in the current session. In order to make the configuration take effect for the future session, it must be saved - in a per-user configuration file by the function + in a per-user customization file by the function minput_save_config (). @return - If the operation was successful, this function returns 0, otherwise returns -1. The operation fails in these cases: