X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Finput.c;h=2de5547311bf64de17a67685c99a0c162b85773c;hb=02c5d90ea3694c6fa6422de2ad4cbdfda46ce854;hp=388237e3bcfdaad5f472ddd1fc31d345715a89bc;hpb=c8334bb214bce5e8c6e1dd784e630778b9f6c59c;p=m17n%2Fm17n-lib.git diff --git a/src/input.c b/src/input.c index 388237e..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,12 +163,10 @@ #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); -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, ")"); } @@ -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 ${HOME}/.m17n.d (${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 +#include +#include + +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; }