From ff331a603939979c8a0af6c600607679340349c3 Mon Sep 17 00:00:00 2001 From: handa Date: Thu, 22 Sep 2005 08:04:16 +0000 Subject: [PATCH] Include and . (Minclude, Mcommit, Munhandle): New variables. (minput__init): Initialize them. Push only Mstate to load_im_info_keys. Add aliases C-lowercase for C-uppercase. (parse_action_list): Allow integer arg for undo. Handle Mcommit and Munhandle. (load_input_method): Handle "include" directive. If no states are loaded, return -1. (shift_state): If state_name is Mt, shift back to the previous state. Call preedit_commit to commit preedit text. (preedit_commit): New function. (take_action_list): Improve debug printing. Handle commit and unhandle commands. (handle_key): Check the return value of take_action_list. Don't take branch_actions just after changing to the root map. (reset_ic): Reset all ic_info members. (filter): When a key is not handled, just move ic_info->keys instead fo calling reset_ic. (load_im_info): If key is not Mstate, push Mmap to load_im_info_keys. (MDatabaseStatList): New type. (imdir_stat_list): New variable. (input_method_hook): Don't cancel the hook. Check the modification time of directories. (minput__fini): Free imdir_stat_list; --- src/input.c | 531 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 391 insertions(+), 140 deletions(-) diff --git a/src/input.c b/src/input.c index 3c3d55e..039a1f0 100644 --- a/src/input.c +++ b/src/input.c @@ -140,6 +140,8 @@ #include #include #include +#include +#include #include "config.h" @@ -161,11 +163,11 @@ static int mdebug_mask = MDEBUG_INPUT; static MSymbol Minput_method; /** Symbols to load an input method data. */ -static MSymbol Mtitle, Mmacro, Mmodule, Mstate; +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; +static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle; static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater; static MSymbol Mcandidate_list, Mcandidate_index; @@ -367,11 +369,14 @@ parse_action_list (MPlist *plist, MPlist *macros) if (! MPLIST_SYMBOL_P (pl)) MERROR (MERROR_IM, -1); } - else if (action_name == Mshow || action_name == Mhide - || action_name == Mundo) + else if (action_name == Mundo) { if (! MPLIST_TAIL_P (pl)) - MERROR (MERROR_IM, -1); + { + if (! MPLIST_INTEGER_P (pl) + || MPLIST_INTEGER (pl) <= 0) + MERROR (MERROR_IM, -1); + } } else if (action_name == Mpushback) { @@ -419,6 +424,9 @@ parse_action_list (MPlist *plist, MPlist *macros) && parse_action_list (MPLIST_PLIST (pl), macros) < 0) MERROR (MERROR_IM, -1); } + else if (action_name == Mshow || action_name == Mhide + || action_name == Mcommit || action_name == Munhandle) + ; else if (! macros || ! mplist_get (macros, action_name)) MERROR (MERROR_IM, -1); } @@ -692,6 +700,9 @@ free_map (MIMMap *map) free (map); } +static MPlist *load_im_info_keys; +static MPlist *load_im_info (MSymbol language, MSymbol name, MSymbol key); + /* Load an input method from PLIST into IM_INTO, and return it. */ static int @@ -705,7 +716,7 @@ load_input_method (MSymbol language, MSymbol name, MPlist *plist, MPlist *macros = NULL; MPlist *elt; - for (; MPLIST_PLIST_P (plist); plist = MPLIST_NEXT (plist)) + while (MPLIST_PLIST_P (plist)) { elt = MPLIST_PLIST (plist); if (! MPLIST_SYMBOL_P (elt)) @@ -713,55 +724,126 @@ load_input_method (MSymbol language, MSymbol name, MPlist *plist, if (MPLIST_SYMBOL (elt) == Mtitle) { elt = MPLIST_NEXT (elt); - if (MPLIST_MTEXT_P (elt)) - { - title = MPLIST_MTEXT (elt); - M17N_OBJECT_REF (title); - } - else + if (! MPLIST_MTEXT_P (elt)) MERROR_GOTO (MERROR_IM, err); + title = MPLIST_MTEXT (elt); + M17N_OBJECT_REF (title); } else if (MPLIST_SYMBOL (elt) == Mmap) { - maps = mplist__from_alist (MPLIST_NEXT (elt)); - if (! maps) + MPlist *pl = mplist__from_alist (MPLIST_NEXT (elt)); + + if (! pl) MERROR_GOTO (MERROR_IM, err); + if (! maps) + maps = pl; + else + maps = mplist_conc (maps, pl); } else if (MPLIST_SYMBOL (elt) == Mmacro) { - macros = mplist (); + if (! macros) + macros = mplist (); MPLIST_DO (elt, MPLIST_NEXT (elt)) - { - if (! MPLIST_PLIST_P (elt) - || load_macros (MPLIST_PLIST (elt), macros) < 0) - MERROR_GOTO (MERROR_IM, err); - } + { + if (! MPLIST_PLIST_P (elt) + || load_macros (MPLIST_PLIST (elt), macros) < 0) + MERROR_GOTO (MERROR_IM, err); + } } else if (MPLIST_SYMBOL (elt) == Mmodule) { - externals = mplist (); + if (! externals) + externals = mplist (); MPLIST_DO (elt, MPLIST_NEXT (elt)) - { - if (! MPLIST_PLIST_P (elt) - || load_external_module (MPLIST_PLIST (elt), externals) < 0) - MERROR_GOTO (MERROR_IM, err); - } + { + if (! MPLIST_PLIST_P (elt) + || load_external_module (MPLIST_PLIST (elt), externals) < 0) + MERROR_GOTO (MERROR_IM, err); + } } else if (MPLIST_SYMBOL (elt) == Mstate) { - states = mplist (); MPLIST_DO (elt, MPLIST_NEXT (elt)) - { - MIMState *state; - - if (! MPLIST_PLIST_P (elt)) - MERROR_GOTO (MERROR_IM, err); - state = load_state (MPLIST_PLIST (elt), maps, language, macros); - if (! state) - MERROR_GOTO (MERROR_IM, err); - mplist_put (states, state->name, state); - } + { + MIMState *state; + + if (! MPLIST_PLIST_P (elt)) + MERROR_GOTO (MERROR_IM, err); + state = load_state (MPLIST_PLIST (elt), maps, language, macros); + if (! state) + MERROR_GOTO (MERROR_IM, err); + if (! states) + states = mplist (); + mplist_put (states, state->name, state); + } + } + else if (MPLIST_SYMBOL (elt) == Minclude) + { + MSymbol lang, name, key; + MPlist *pl, *p, *p0; + + elt = MPLIST_NEXT (elt); + if (! MPLIST_SYMBOL_P (elt)) + MERROR_GOTO (MERROR_IM, err); + lang = MPLIST_SYMBOL (elt); + elt = MPLIST_NEXT (elt); + if (! MPLIST_SYMBOL_P (elt)) + MERROR_GOTO (MERROR_IM, err); + name = MPLIST_SYMBOL (elt); + if (language == Mnil || name == Mnil) + MERROR_GOTO (MERROR_IM, err); + elt = MPLIST_NEXT (elt); + if (! MPLIST_SYMBOL_P (elt)) + MERROR_GOTO (MERROR_IM, err); + key = MPLIST_SYMBOL (elt); + elt = MPLIST_NEXT (elt); + if (MPLIST_TAIL_P (elt)) + elt = NULL; + pl = load_im_info (lang, name, key); + if (! pl) + MERROR_GOTO (MERROR_IM, err); + if (! MPLIST_PLIST_P (pl)) + MERROR_GOTO (MERROR_IM, include_err); + p = MPLIST_PLIST (pl); + if (! MPLIST_SYMBOL_P (p) || MPLIST_SYMBOL (p) != key) + MERROR_GOTO (MERROR_IM, include_err); + p = MPLIST_NEXT (p); + while (! MPLIST_TAIL_P (p)) + { + if (MPLIST_PLIST_P (p)) + { + p0 = MPLIST_PLIST (p); + + if (! MPLIST_SYMBOL_P (p0)) + MERROR_GOTO (MERROR_IM, include_err); + if (elt) + { + p0 = mplist_find_by_value (elt, MPLIST_SYMBOL (p0)); + if (p0) + { + mplist_pop (p0); + p = MPLIST_NEXT (p); + } + else + mplist_pop (p); + } + else + p = MPLIST_NEXT (p); + } + else + mplist_pop (p); + } + if (! MPLIST_TAIL_P (p)) + MERROR_GOTO (MERROR_IM, include_err); + mplist_set (plist, Mplist, MPLIST_PLIST (pl)); + continue; + + include_err: + M17N_OBJECT_REF (pl); + MERROR_GOTO (MERROR_IM, err); } + plist = MPLIST_NEXT (plist); } if (maps) @@ -773,6 +855,8 @@ load_input_method (MSymbol language, MSymbol name, MPlist *plist, if (! title) title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name), MTEXT_FORMAT_US_ASCII); + if (! states) + goto err; im_info->title = title; im_info->externals = externals; im_info->macros = macros; @@ -821,19 +905,29 @@ load_input_method (MSymbol language, MSymbol name, MPlist *plist, static int take_action_list (MInputContext *ic, MPlist *action_list); +static void preedit_commit (MInputContext *ic); static void shift_state (MInputContext *ic, MSymbol state_name) { MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; - MIMState *state; + MIMState *orig_state = ic_info->state, *state; /* Find a state to shift to. If not found, shift to the initial state. */ - state = (MIMState *) mplist_get (im_info->states, state_name); - if (! state) - state = (MIMState *) MPLIST_VAL (im_info->states); + if (state_name == Mt) + { + if (! ic_info->prev_state) + return; + state = ic_info->prev_state; + } + else + { + state = (MIMState *) mplist_get (im_info->states, state_name); + if (! state) + state = (MIMState *) MPLIST_VAL (im_info->states); + } MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name)); @@ -842,48 +936,28 @@ shift_state (MInputContext *ic, MSymbol state_name) ic_info->map = state->map; ic_info->state_key_head = ic_info->key_head; if (state == (MIMState *) MPLIST_VAL (im_info->states)) - { - /* We have shifted to the initial state. */ - MPlist *p; - - mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit), - Mcandidate_list, NULL, 0); - mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit), - Mcandidate_index, NULL, 0); - mtext_cat (ic->produced, ic->preedit); - if ((mdebug__flag & mdebug_mask) - && mtext_nchars (ic->produced) > 0) - { - int i; - - MDEBUG_PRINT (" (produced"); - for (i = 0; i < mtext_nchars (ic->produced); i++) - MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i)); - MDEBUG_PRINT (")"); - } - mtext_reset (ic->preedit); - ic->candidate_list = NULL; - ic->candidate_show = 0; - ic->preedit_changed = ic->candidates_changed = 1; - MPLIST_DO (p, ic_info->markers) - MPLIST_VAL (p) = 0; - ic->cursor_pos = 0; - memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head, - sizeof (int) * (ic_info->used - ic_info->state_key_head)); - ic_info->used -= ic_info->state_key_head; - ic_info->state_key_head = ic_info->key_head = 0; - } + /* We have shifted to the initial state. */ + preedit_commit (ic); mtext_cpy (ic_info->preedit_saved, ic->preedit); ic_info->state_pos = ic->cursor_pos; - ic->status = state->title; - if (! ic->status) - ic->status = im_info->title; - ic->status_changed = 1; - if (ic_info->map == ic_info->state->map - && ic_info->map->map_actions) + if (state != orig_state ) { - MDEBUG_PRINT (" init-actions:"); - take_action_list (ic, ic_info->map->map_actions); + if (state == (MIMState *) MPLIST_VAL (im_info->states)) + ic_info->prev_state = NULL; + else + ic_info->prev_state = orig_state; + + if (state->title) + ic->status = state->title; + else if (! ic->status) + 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); + } } } @@ -964,6 +1038,50 @@ preedit_delete (MInputContext *ic, int from, int to) ic->preedit_changed = 1; } +static void +preedit_commit (MInputContext *ic) +{ + MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; + int preedit_len = mtext_nchars (ic->preedit); + + if (preedit_len > 0) + { + MPlist *p; + + mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit), + Mcandidate_list, NULL, 0); + mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit), + Mcandidate_index, NULL, 0); + mtext_cat (ic->produced, ic->preedit); + if ((mdebug__flag & mdebug_mask) + && mtext_nchars (ic->produced) > 0) + { + int i; + + MDEBUG_PRINT (" (produced"); + for (i = 0; i < mtext_nchars (ic->produced); i++) + MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i)); + MDEBUG_PRINT (")"); + } + mtext_reset (ic->preedit); + mtext_reset (ic_info->preedit_saved); + MPLIST_DO (p, ic_info->markers) + MPLIST_VAL (p) = 0; + ic->cursor_pos = ic_info->state_pos = 0; + ic->preedit_changed = 1; + } + if (ic->candidate_list) + { + ic->candidate_list = NULL; + ic->candidate_show = 0; + ic->candidates_changed = 1; + } + + memmove (ic_info->keys, ic_info->keys + ic_info->key_head, + sizeof (int) * (ic_info->used - ic_info->key_head)); + ic_info->used -= ic_info->key_head; + ic_info->state_key_head = ic_info->key_head = 0; +} static int new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt) @@ -1329,21 +1447,18 @@ take_action_list (MInputContext *ic, MPlist *action_list) } else if (name == Mundo) { - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - int unhandle = 0; + int intarg = MPLIST_TAIL_P (args) ? 2 : MPLIST_INTEGER (args); + int unhandled = 0; mtext_reset (ic->preedit); mtext_reset (ic_info->preedit_saved); ic->cursor_pos = ic_info->state_pos = 0; ic_info->state_key_head = ic_info->key_head = 0; - ic_info->used -= 2; + ic_info->used -= intarg; if (ic_info->used < 0) - { - ic_info->used = 0; - unhandle = 1; - } - shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name); - if (unhandle) + ic_info->used = 0, unhandled = 1; + shift_state (ic, Mnil); + if (unhandled) return -1; break; } @@ -1352,21 +1467,22 @@ take_action_list (MInputContext *ic, MPlist *action_list) { MSymbol sym = MPLIST_SYMBOL (args); int val1 = (int) mplist_get (ic_info->vars, sym), val2; + char *op; args = MPLIST_NEXT (args); val2 = integer_value (ic, args); if (name == Mset) - val1 = val2; + val1 = val2, op = "="; else if (name == Madd) - val1 += val2; + val1 += val2, op = "+="; else if (name == Msub) - val1 -= val2; + val1 -= val2, op = "-="; else if (name == Mmul) - val1 *= val2; + val1 *= val2, op = "*="; else - val1 /= val2; + val1 /= val2, op = "/="; mplist_put (ic_info->vars, sym, (void *) val1); - MDEBUG_PRINT2 ("(%s=%d)", MSYMBOL_NAME (sym), val1); + MDEBUG_PRINT3 ("(%s %s %d)", MSYMBOL_NAME (sym), op, val1); } else if (name == Mequal || name == Mless || name == Mgreater) { @@ -1384,7 +1500,7 @@ take_action_list (MInputContext *ic, MPlist *action_list) actions2 = NULL; else actions2 = MPLIST_PLIST (args); - MDEBUG_PRINT2 ("(%d,%d)", val1, val2); + MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2); if (name == Mequal ? val1 == val2 : name == Mless ? val1 < val2 : val1 > val2) @@ -1401,6 +1517,16 @@ take_action_list (MInputContext *ic, MPlist *action_list) if (ret < 0) return ret; } + else if (name == Mcommit) + { + preedit_commit (ic); + } + else if (name == Munhandle) + { + preedit_commit (ic); + ic_info->used = 0; + return -1; + } else { MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; @@ -1466,6 +1592,7 @@ handle_key (MInputContext *ic) { MDEBUG_PRINT (" submap-found"); mtext_cpy (ic->preedit, ic_info->preedit_saved); + ic->preedit_changed = 1; ic->cursor_pos = ic_info->state_pos; ic_info->key_head++; ic_info->map = map = submap; @@ -1488,7 +1615,6 @@ handle_key (MInputContext *ic) if (! name[0] || ! name[1]) mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1); } - ic->preedit_changed = 1; } /* If this is the terminal map or we have shifted to another @@ -1529,19 +1655,25 @@ handle_key (MInputContext *ic) if (map->branch_actions) { MDEBUG_PRINT (" branch-actions:"); - take_action_list (ic, map->branch_actions); + if (take_action_list (ic, map->branch_actions) < 0) + { + MDEBUG_PRINT ("\n"); + return -1; + } } /* If MAP is still not the root map, shift to the current state. */ if (ic_info->map != ic_info->state->map) { shift_state (ic, ic_info->state->name); +#if 0 /* If MAP has branch_actions, perform them. */ if (ic_info->map->branch_actions) { - MDEBUG_PRINT (" init-actions:"); + MDEBUG_PRINT (" brank-actions:"); take_action_list (ic, ic_info->map->branch_actions); } +#endif } } else @@ -1551,11 +1683,14 @@ handle_key (MInputContext *ic) if (map->branch_actions) { MDEBUG_PRINT (" branch-actions:"); - take_action_list (ic, map->branch_actions); + if (take_action_list (ic, map->branch_actions) < 0) + { + MDEBUG_PRINT ("\n"); + return -1; + } } else - shift_state (ic, - ((MIMState *) MPLIST_VAL (im_info->states))->name); + shift_state (ic, Mnil); } } MDEBUG_PRINT ("\n"); @@ -1567,23 +1702,46 @@ reset_ic (MInputContext *ic, MSymbol ignore) { MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; + MText *status; - if (im_info->states) - /* Shift to the initial state. */ - shift_state (ic, Mnil); - else - ic_info->state = NULL; + MDEBUG_PRINT ("\n [IM] reset\n"); + + ic_info->state = (MIMState *) MPLIST_VAL (im_info->states); + ic_info->prev_state = NULL; + ic_info->map = ic_info->state->map; + ic_info->state_key_head = ic_info->key_head; MLIST_RESET (ic_info); - ic_info->map = ic_info->state ? ic_info->state->map : NULL; - ic_info->state_key_head = ic_info->key_head = 0; ic_info->key_unhandled = 0; - ic->cursor_pos = ic_info->state_pos = 0; - ic->status = ic_info->state ? ic_info->state->title : NULL; - if (! ic->status) - ic->status = im_info->title; - ic->candidate_list = NULL; - ic->candidate_show = 0; - ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1; + + if (mtext_nchars (ic->produced) > 0) + mtext_reset (ic->produced); + if (mtext_nchars (ic->preedit) > 0) + { + MPlist *plist; + + mtext_reset (ic->preedit); + MPLIST_DO (plist, ic_info->markers) + MPLIST_VAL (plist) = 0; + ic->preedit_changed = 1; + } + if (ic->candidate_show) + { + ic->candidate_show = 0; + if (ic->candidate_list) + { + ic->candidate_list = NULL; + ic->candidates_changed = 1; + } + } + mtext_reset (ic_info->preedit_saved); + ic_info->state_pos = ic->cursor_pos = 0; + + status = ic_info->state->title ? ic_info->state->title : im_info->title; + if (ic->status != status) + { + ic->status = status; + ic->status_changed = 1; + } } static int @@ -1750,9 +1908,13 @@ filter (MInputContext *ic, MSymbol key, void *arg) do { if (handle_key (ic) < 0) { - /* KEY was not handled. Reset the status and break the - loop. */ - reset_ic (ic, Mnil); + /* KEY was not handled. Delete it from the current key sequence. */ + if (ic_info->used > 0) + { + memmove (ic_info->keys, ic_info->keys + 1, + sizeof (int) * (ic_info->used - 1)); + ic_info->used--; + } /* This forces returning 1. */ ic_info->key_unhandled = 1; break; @@ -1802,8 +1964,6 @@ lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt) return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0); } -static MPlist *load_im_info_keys; - static MPlist * load_im_info (MSymbol language, MSymbol name, MSymbol key) { @@ -1816,9 +1976,13 @@ load_im_info (MSymbol language, MSymbol name, MSymbol key) mdb = mdatabase_find (Minput_method, language, name, Mnil); if (! mdb) MERROR (MERROR_IM, NULL); + if (key != Mstate) + mplist_push (load_im_info_keys, Mmap, Mt); mplist_push (load_im_info_keys, key, Mt); plist = mdatabase__load_for_keys (mdb, load_im_info_keys); mplist_pop (load_im_info_keys); + if (key != Mstate) + mplist_pop (load_im_info_keys); return plist; } @@ -2082,24 +2246,59 @@ get_variable_list (MSymbol language, MSymbol name) return pl; } +typedef struct _MDatabaseStatList +{ + char *dirname; + time_t mtime, ctime; + struct _MDatabaseStatList *next; +} MDatabaseStatList; + +static MDatabaseStatList *imdir_stat_list; + +/* This function is called before any operation with tag0 specified as + `input-method' on the m17n database. It lists all *.mim files and + add them to the database. */ + static void input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3) { MPlist *plist, *pl, *p; char path[PATH_MAX]; - /* Cancel the hook. */ - msymbol_put (tag0, M_database_hook, NULL); tag3 = Mnil; - + mplist_push (load_im_info_keys, Mmap, Mt); mplist_push (load_im_info_keys, M_description, Mt); MPLIST_DO (plist, mdatabase__dir_list) { char *dirname = (char *) MPLIST_VAL (plist); + struct stat st; + MDatabaseStatList *stlist; int dirlen; - DIR *dir = opendir (dirname); + DIR *dir; struct dirent *dp; + + if (stat (dirname, &st) < 0 + || ! S_ISDIR (st.st_mode)) + continue; + for (stlist = imdir_stat_list; stlist; stlist = stlist->next) + if (strcmp (stlist->dirname, dirname) == 0) + break; + if (! stlist) + { + MSTRUCT_MALLOC (stlist, MERROR_IM); + stlist->dirname = strdup (dirname); + stlist->next = imdir_stat_list; + imdir_stat_list = stlist; + } + else if (stlist->mtime == st.st_mtime + && stlist->ctime == st.st_ctime) + /* This directory is not changed since we checked last + time. */ + continue; + stlist->mtime = st.st_mtime; + stlist->ctime = st.st_ctime; + dir = opendir (dirname); if (! dir) continue; dirlen = strlen (dirname); @@ -2130,9 +2329,13 @@ input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3) p = MPLIST_NEXT (p); if (MPLIST_SYMBOL_P (p)) { + MDatabase *mdb; + tag2 = MPLIST_VAL (p); - mdatabase_define (tag0, tag1, tag2, tag3, - NULL, path); + mdb = mdatabase_find (tag0, tag2, tag2, tag3); + if (! mdb) + mdatabase_define (tag0, tag1, tag2, tag3, + NULL, path); } } } @@ -2143,6 +2346,7 @@ input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3) closedir (dir); } mplist_pop (load_im_info_keys); + mplist_pop (load_im_info_keys); } @@ -2224,6 +2428,7 @@ minput__init () Mmodule = msymbol ("module"); Mmap = msymbol ("map"); Mstate = msymbol ("state"); + Minclude = msymbol ("include"); Minsert = msymbol ("insert"); Mdelete = msymbol ("delete"); Mmove = msymbol ("move"); @@ -2235,6 +2440,8 @@ minput__init () Mselect = msymbol ("select"); Mshow = msymbol ("show"); Mhide = msymbol ("hide"); + Mcommit = msymbol ("commit"); + Munhandle = msymbol ("unhandle"); Mset = msymbol ("set"); Madd = msymbol ("add"); Msub = msymbol ("sub"); @@ -2274,19 +2481,26 @@ minput__init () Mdetail_text = msymbol_as_managing_key (" detail-text"); load_im_info_keys = mplist (); - plist = mplist_add (load_im_info_keys, Mmap, Mnil); - plist = mplist_add (plist, Mstate, Mnil); - plist = mplist_add (plist, Mmacro, Mnil); - plist = mplist_add (plist, Mmodule, Mnil); + plist = mplist_add (load_im_info_keys, Mstate, Mnil); buf[0] = 'C'; buf[1] = '-'; buf[3] = '\0'; for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++) { + MSymbol alias; + one_char_symbol[i] = msymbol (buf); if (key_names[i]) - msymbol_put (one_char_symbol[i], M_key_alias, msymbol (key_names[i])); + { + alias = msymbol (key_names[i]); + msymbol_put (one_char_symbol[i], M_key_alias, alias); + } + else + alias = one_char_symbol[i]; + buf[2] += (i == 0) ? -32 : 32; + msymbol_put (alias, M_key_alias, msymbol (buf)); + buf[2] -= (i == 0) ? -32 : 32; } for (buf[2] = i; i < 127; i++, buf[2]++) one_char_symbol[i] = msymbol (buf + 2); @@ -2372,6 +2586,15 @@ minput__fini () } M17N_OBJECT_UNREF (load_im_info_keys); + + while (imdir_stat_list) + { + MDatabaseStatList *next = imdir_stat_list->next; + + free (imdir_stat_list->dirname); + free (imdir_stat_list); + imdir_stat_list = next; + } } void @@ -2432,9 +2655,6 @@ MSymbol Minput_candidates_start; MSymbol Minput_candidates_done; MSymbol Minput_candidates_draw; MSymbol Minput_set_spot; -MSymbol Minput_focus_move; -MSymbol Minput_focus_in; -MSymbol Minput_focus_out; MSymbol Minput_toggle; MSymbol Minput_reset; /*** @} */ @@ -2442,6 +2662,23 @@ MSymbol Minput_reset; /*=*/ /***en + @name Variables: Predefined symbols for special input events. + + These are the predefined symbols that are used as the @c KEY + argument of minput_filter (). */ + +/*** @{ */ +/*=*/ + +MSymbol Minput_focus_out; +MSymbol Minput_focus_in; +MSymbol Minput_focus_move; + +/*** @} */ + +/*=*/ + +/***en @brief The default driver for internal input methods. The variable #minput_default_driver is the default driver for @@ -2725,6 +2962,20 @@ minput_destroy_ic (MInputContext *ic) #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) + and shift to the initial state, call this function with #Mnil as + $KEY. + + To inform the input method about the focus-out event, call this + function with #Minput_focus_out as $KEY. + + To inform the input method about the focus-in event, call this + function with #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. + @return If $KEY is filtered out, this function returns 1. In that case, the caller should discard the key. Otherwise, it returns 0, and @@ -2897,11 +3148,11 @@ minput_toggle (MInputContext *ic) The minput_reset_ic () function resets input context $IC by calling a callback function corresponding to #Minput_reset. It - actually shifts the state to the initial one, and thus the current - preediting text (if any) is committed. If necessary, a program - can extract that committed text by calling minput_lookup () just - after the call of minput_reset_ic (). In that case, the arguments - @c KEY and @c ARG of minput_lookup () are ignored. */ + resets the status of $IC to the one of just after created. As the + current preedit text is deleted without commitment, if necessary, + call minput_filter () with the arg @r key #Mnil to force the input + method to commit the preedit in advance. */ + /***ja @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë. -- 1.7.10.4