1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides a input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and the body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those driver utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provides an input method that is not only for a specific language.
44 The database uses @c Mt as LANGUAGE of such an input method.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer have to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and the body is
56 defined in an external resources (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤÏm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë
95 <Minput_method, LANGUAGE, NAME>
96 ¤È¤¤¤¦¥¿¥°¤òÉÕ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£
97 ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç¤Ï
98 CUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ¤¤¤ë¡£
99 ¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍøÍѤ¹¤ë¡£
100 m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄêµÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢
101 ¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
103 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£
104 @c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢
105 ÆþÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
106 ¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤ÎÀâÌÀ¤ò»²¾È¡£
108 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
110 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£
111 ¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê¤É¡£)
112 ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver
113 ¤ò¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
114 ¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â
115 @c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö¤¬¤Ç¤¤ë¡£
117 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot
118 ¤ÎÆþÎÏ¥¹¥¿¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
119 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý¤·¤Æ¤¤¤ë¡£
120 ¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
126 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
128 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
129 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
130 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
131 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
135 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
136 /*** @addtogroup m17nInternal
141 #include <sys/types.h>
143 #include <sys/stat.h>
152 #include "m17n-gui.h"
153 #include "m17n-misc.h"
154 #include "internal.h"
159 #include "database.h"
161 static int mdebug_mask = MDEBUG_INPUT;
163 static MSymbol Minput_method;
165 /** Symbols to load an input method data. */
166 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
168 /** Symbols for actions. */
169 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
170 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
171 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
173 static MSymbol Mcandidate_list, Mcandidate_index;
175 static MSymbol Minit, Mfini;
177 /** Symbols for key events. */
178 static MSymbol one_char_symbol[256];
180 static MSymbol M_key_alias;
182 static MSymbol M_description, M_command, M_variable;
184 /** Structure to hold a map. */
188 /** List of actions to take when we reach the map. In a root map,
189 the actions are executed only when there's no more key. */
192 /** List of deeper maps. If NULL, this is a terminal map. */
195 /** List of actions to take when we leave the map successfully. In
196 a root map, the actions are executed only when none of submaps
197 handle the current key. */
198 MPlist *branch_actions;
201 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
206 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
211 /** Name of the state. */
214 /** Title of the state, or NULL. */
217 /** Key translation map of the state. Built by merging all maps of
224 marker_code (MSymbol sym)
230 name = MSYMBOL_NAME (sym);
231 return ((name[0] == '@'
232 && ((name[1] >= '0' && name[1] <= '9')
233 || name[1] == '<' || name[1] == '>'
234 || name[1] == '=' || name[1] == '+' || name[1] == '-'
235 || name[1] == '[' || name[1] == ']')
241 integer_value (MInputContext *ic, MPlist *arg)
243 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
245 MText *preedit = ic->preedit;
246 int len = mtext_nchars (preedit);
248 if (MPLIST_INTEGER_P (arg))
249 return MPLIST_INTEGER (arg);
250 code = marker_code (MPLIST_SYMBOL (arg));
252 return (int) mplist_get (ic_info->vars, MPLIST_SYMBOL (arg));
253 if (code >= '0' && code <= '9')
255 else if (code == '=')
256 code = ic->cursor_pos;
257 else if (code == '-' || code == '[')
258 code = ic->cursor_pos - 1;
259 else if (code == '+' || code == ']')
260 code = ic->cursor_pos + 1;
261 else if (code == '<')
263 else if (code == '>')
265 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
269 /* Parse PLIST as an action list while modifying the list to regularize
270 actions. PLIST should have this form:
271 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
272 Return 0 if successfully parsed, otherwise return -1. */
275 parse_action_list (MPlist *plist, MPlist *macros)
277 MPLIST_DO (plist, plist)
279 if (MPLIST_MTEXT_P (plist))
281 /* This is a short form of (insert MTEXT). */
282 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
283 MERROR (MERROR_IM, -1); */
285 else if (MPLIST_PLIST_P (plist)
286 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
287 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
291 /* This is a short form of (insert (GROUPS *)). */
292 MPLIST_DO (pl, MPLIST_PLIST (plist))
294 if (MPLIST_PLIST_P (pl))
298 MPLIST_DO (elt, MPLIST_PLIST (pl))
299 if (! MPLIST_MTEXT_P (elt)
300 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
301 MERROR (MERROR_IM, -1);
305 if (! MPLIST_MTEXT_P (pl)
306 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
307 MERROR (MERROR_IM, -1);
311 else if (MPLIST_INTEGER_P (plist))
313 int c = MPLIST_INTEGER (plist);
315 if (c < 0 || c > MCHAR_MAX)
316 MERROR (MERROR_IM, -1);
318 else if (MPLIST_PLIST_P (plist)
319 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
321 MPlist *pl = MPLIST_PLIST (plist);
322 MSymbol action_name = MPLIST_SYMBOL (pl);
324 pl = MPLIST_NEXT (pl);
326 if (action_name == Minsert)
328 if (MPLIST_MTEXT_P (pl))
330 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
331 MERROR (MERROR_IM, -1);
333 else if (MPLIST_PLIST_P (pl))
337 if (MPLIST_PLIST_P (pl))
341 MPLIST_DO (elt, MPLIST_PLIST (pl))
342 if (! MPLIST_MTEXT_P (elt)
343 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
344 MERROR (MERROR_IM, -1);
348 if (! MPLIST_MTEXT_P (pl)
349 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
350 MERROR (MERROR_IM, -1);
354 else if (! MPLIST_SYMBOL_P (pl))
355 MERROR (MERROR_IM, -1);
357 else if (action_name == Mselect
358 || action_name == Mdelete
359 || action_name == Mmove)
361 if (! MPLIST_SYMBOL_P (pl)
362 && ! MPLIST_INTEGER_P (pl))
363 MERROR (MERROR_IM, -1);
365 else if (action_name == Mmark
366 || action_name == Mcall
367 || action_name == Mshift)
369 if (! MPLIST_SYMBOL_P (pl))
370 MERROR (MERROR_IM, -1);
372 else if (action_name == Mundo)
374 if (! MPLIST_TAIL_P (pl))
376 if (! MPLIST_INTEGER_P (pl)
377 || MPLIST_INTEGER (pl) <= 0)
378 MERROR (MERROR_IM, -1);
381 else if (action_name == Mpushback)
383 if (MPLIST_MTEXT_P (pl))
385 MText *mt = MPLIST_MTEXT (pl);
387 if (mtext_nchars (mt) != mtext_nbytes (mt))
388 MERROR (MERROR_IM, -1);
390 else if (MPLIST_PLIST_P (pl))
394 MPLIST_DO (p, MPLIST_PLIST (pl))
395 if (! MPLIST_SYMBOL_P (p))
396 MERROR (MERROR_IM, -1);
398 else if (! MPLIST_INTEGER_P (pl))
399 MERROR (MERROR_IM, -1);
401 else if (action_name == Mset || action_name == Madd
402 || action_name == Msub || action_name == Mmul
403 || action_name == Mdiv)
405 if (! (MPLIST_SYMBOL_P (pl)
406 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
407 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
408 MERROR (MERROR_IM, -1);
410 else if (action_name == Mequal || action_name == Mless
411 || action_name == Mgreater)
413 if (! ((MPLIST_INTEGER_P (pl) || MPLIST_SYMBOL_P (pl))
414 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
415 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
416 MERROR (MERROR_IM, -1);
417 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
418 if (! MPLIST_PLIST_P (pl))
419 MERROR (MERROR_IM, -1);
420 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
421 MERROR (MERROR_IM, -1);
422 pl = MPLIST_NEXT (pl);
423 if (MPLIST_PLIST_P (pl)
424 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
425 MERROR (MERROR_IM, -1);
427 else if (action_name == Mshow || action_name == Mhide
428 || action_name == Mcommit || action_name == Munhandle)
430 else if (! macros || ! mplist_get (macros, action_name))
431 MERROR (MERROR_IM, -1);
434 MERROR (MERROR_IM, -1);
441 /* Load a translation into MAP from PLIST.
443 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
446 load_translation (MIMMap *map, MPlist *plist, MPlist *branch_actions,
452 if (MPLIST_MTEXT_P (plist))
454 MText *mt = MPLIST_MTEXT (plist);
456 len = mtext_nchars (mt);
457 if (len == 0 || len != mtext_nbytes (mt))
458 MERROR (MERROR_IM, -1);
459 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
460 for (i = 0; i < len; i++)
461 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
463 else if (MPLIST_PLIST_P (plist))
465 MPlist *elt = MPLIST_PLIST (plist);
467 len = MPLIST_LENGTH (elt);
469 MERROR (MERROR_IM, -1);
470 keyseq = (MSymbol *) alloca (sizeof (int) * len);
471 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
473 if (MPLIST_INTEGER_P (elt))
475 int c = MPLIST_INTEGER (elt);
477 if (c < 0 || c >= 0x100)
478 MERROR (MERROR_IM, -1);
479 keyseq[i] = one_char_symbol[c];
481 else if (MPLIST_SYMBOL_P (elt))
482 keyseq[i] = MPLIST_SYMBOL (elt);
484 MERROR (MERROR_IM, -1);
488 MERROR (MERROR_IM, -1);
490 for (i = 0; i < len; i++)
492 MIMMap *deeper = NULL;
495 deeper = mplist_get (map->submaps, keyseq[i]);
497 map->submaps = mplist ();
500 /* Fixme: It is better to make all deeper maps at once. */
501 MSTRUCT_CALLOC (deeper, MERROR_IM);
502 mplist_put (map->submaps, keyseq[i], deeper);
507 /* We reach a terminal map. */
509 || map->branch_actions)
510 /* This map is already defined. We avoid overriding it. */
513 plist = MPLIST_NEXT (plist);
514 if (! MPLIST_TAIL_P (plist))
516 if (parse_action_list (plist, macros) < 0)
517 MERROR (MERROR_IM, -1);
518 map->map_actions = plist;
519 M17N_OBJECT_REF (plist);
523 map->branch_actions = branch_actions;
524 M17N_OBJECT_REF (branch_actions);
530 /* Load a branch from PLIST into MAP. PLIST has this form:
531 PLIST ::= ( MAP-NAME BRANCH-ACTION * )
532 MAPS is a plist of raw maps.
533 STATE is the current state. */
536 load_branch (MPlist *plist, MPlist *maps, MIMMap *map, MPlist *macros)
539 MPlist *branch_actions;
541 if (! MPLIST_SYMBOL_P (plist))
542 MERROR (MERROR_IM, -1);
543 map_name = MPLIST_SYMBOL (plist);
544 plist = MPLIST_NEXT (plist);
545 if (MPLIST_TAIL_P (plist))
546 branch_actions = NULL;
547 else if (parse_action_list (plist, macros) < 0)
548 MERROR (MERROR_IM, -1);
550 branch_actions = plist;
551 if (map_name == Mnil)
553 map->branch_actions = branch_actions;
555 M17N_OBJECT_REF (branch_actions);
557 else if (map_name == Mt)
559 map->map_actions = branch_actions;
561 M17N_OBJECT_REF (branch_actions);
565 plist = (MPlist *) mplist_get (maps, map_name);
566 if (! plist || ! MPLIST_PLIST_P (plist))
567 MERROR (MERROR_IM, -1);
568 MPLIST_DO (plist, plist)
569 if (! MPLIST_PLIST_P (plist)
570 || (load_translation (map, MPLIST_PLIST (plist), branch_actions,
573 MERROR (MERROR_IM, -1);
579 /* Load a macro from PLIST into MACROS.
581 PLIST ::= ( MACRO-NAME ACTION * )
582 MACROS is a plist of macro names vs action list. */
584 load_macros (MPlist *plist, MPlist *macros)
588 if (! MPLIST_SYMBOL_P (plist))
589 MERROR (MERROR_IM, -1);
590 name = MPLIST_SYMBOL (plist);
591 plist = MPLIST_NEXT (plist);
592 if (MPLIST_TAIL_P (plist)
593 || parse_action_list (plist, macros) < 0)
594 MERROR (MERROR_IM, -1);
595 mplist_put (macros, name, plist);
596 M17N_OBJECT_REF (plist);
600 /* Load an external module from PLIST into EXTERNALS.
602 PLIST ::= ( MODULE-NAME FUNCTION * )
603 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
606 load_external_module (MPlist *plist, MPlist *externals)
611 MIMExternalModule *external;
615 if (MPLIST_MTEXT_P (plist))
616 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
617 else if (MPLIST_SYMBOL_P (plist))
618 module = MPLIST_SYMBOL (plist);
619 module_file = alloca (strlen (MSYMBOL_NAME (module))
620 + strlen (DLOPEN_SHLIB_EXT) + 1);
621 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
623 handle = dlopen (module_file, RTLD_NOW);
626 fprintf (stderr, "%s\n", dlerror ());
627 MERROR (MERROR_IM, -1);
629 func_list = mplist ();
630 MPLIST_DO (plist, MPLIST_NEXT (plist))
632 if (! MPLIST_SYMBOL_P (plist))
633 MERROR_GOTO (MERROR_IM, err_label);
634 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
636 MERROR_GOTO (MERROR_IM, err_label);
637 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
640 MSTRUCT_MALLOC (external, MERROR_IM);
641 external->handle = handle;
642 external->func_list = func_list;
643 mplist_add (externals, module, external);
648 M17N_OBJECT_UNREF (func_list);
653 /** Load a state from PLIST into a newly allocated state object.
655 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
656 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
657 MAPS is a plist of defined maps.
658 Return the state object. */
661 load_state (MPlist *plist, MPlist *maps, MSymbol language, MPlist *macros)
665 MSTRUCT_CALLOC (state, MERROR_IM);
666 if (! MPLIST_SYMBOL_P (plist))
667 MERROR (MERROR_IM, NULL);
668 state->name = MPLIST_SYMBOL (plist);
669 plist = MPLIST_NEXT (plist);
670 if (MPLIST_MTEXT_P (plist))
672 state->title = MPLIST_MTEXT (plist);
673 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
674 Mlanguage, language);
675 M17N_OBJECT_REF (state->title);
676 plist = MPLIST_NEXT (plist);
678 MSTRUCT_CALLOC (state->map, MERROR_IM);
679 MPLIST_DO (plist, plist)
680 if (! MPLIST_PLIST_P (plist)
681 || load_branch (MPLIST_PLIST (plist), maps, state->map, macros) < 0)
682 MERROR (MERROR_IM, NULL);
688 free_map (MIMMap *map)
692 M17N_OBJECT_UNREF (map->map_actions);
695 MPLIST_DO (plist, map->submaps)
696 free_map ((MIMMap *) MPLIST_VAL (plist));
697 M17N_OBJECT_UNREF (map->submaps);
699 M17N_OBJECT_UNREF (map->branch_actions);
703 static MPlist *load_im_info_keys;
704 static MPlist *load_im_info (MSymbol language, MSymbol name, MSymbol key);
706 /* Load an input method from PLIST into IM_INTO, and return it. */
709 load_input_method (MSymbol language, MSymbol name, MPlist *plist,
710 MInputMethodInfo *im_info)
714 MPlist *states = NULL;
715 MPlist *externals = NULL;
716 MPlist *macros = NULL;
719 while (MPLIST_PLIST_P (plist))
721 elt = MPLIST_PLIST (plist);
722 if (! MPLIST_SYMBOL_P (elt))
723 MERROR_GOTO (MERROR_IM, err);
724 if (MPLIST_SYMBOL (elt) == Mtitle)
726 elt = MPLIST_NEXT (elt);
727 if (! MPLIST_MTEXT_P (elt))
728 MERROR_GOTO (MERROR_IM, err);
729 title = MPLIST_MTEXT (elt);
730 M17N_OBJECT_REF (title);
732 else if (MPLIST_SYMBOL (elt) == Mmap)
734 MPlist *pl = mplist__from_alist (MPLIST_NEXT (elt));
737 MERROR_GOTO (MERROR_IM, err);
741 maps = mplist_conc (maps, pl);
743 else if (MPLIST_SYMBOL (elt) == Mmacro)
747 MPLIST_DO (elt, MPLIST_NEXT (elt))
749 if (! MPLIST_PLIST_P (elt)
750 || load_macros (MPLIST_PLIST (elt), macros) < 0)
751 MERROR_GOTO (MERROR_IM, err);
754 else if (MPLIST_SYMBOL (elt) == Mmodule)
757 externals = mplist ();
758 MPLIST_DO (elt, MPLIST_NEXT (elt))
760 if (! MPLIST_PLIST_P (elt)
761 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
762 MERROR_GOTO (MERROR_IM, err);
765 else if (MPLIST_SYMBOL (elt) == Mstate)
767 MPLIST_DO (elt, MPLIST_NEXT (elt))
771 if (! MPLIST_PLIST_P (elt))
772 MERROR_GOTO (MERROR_IM, err);
773 state = load_state (MPLIST_PLIST (elt), maps, language, macros);
775 MERROR_GOTO (MERROR_IM, err);
778 mplist_put (states, state->name, state);
781 else if (MPLIST_SYMBOL (elt) == Minclude)
783 MSymbol lang, name, key;
786 elt = MPLIST_NEXT (elt);
787 if (! MPLIST_SYMBOL_P (elt))
788 MERROR_GOTO (MERROR_IM, err);
789 lang = MPLIST_SYMBOL (elt);
790 elt = MPLIST_NEXT (elt);
791 if (! MPLIST_SYMBOL_P (elt))
792 MERROR_GOTO (MERROR_IM, err);
793 name = MPLIST_SYMBOL (elt);
794 if (language == Mnil || name == Mnil)
795 MERROR_GOTO (MERROR_IM, err);
796 elt = MPLIST_NEXT (elt);
797 if (! MPLIST_SYMBOL_P (elt))
798 MERROR_GOTO (MERROR_IM, err);
799 key = MPLIST_SYMBOL (elt);
800 elt = MPLIST_NEXT (elt);
801 if (MPLIST_TAIL_P (elt))
803 pl = load_im_info (lang, name, key);
805 MERROR_GOTO (MERROR_IM, err);
806 if (! MPLIST_PLIST_P (pl))
807 MERROR_GOTO (MERROR_IM, include_err);
808 p = MPLIST_PLIST (pl);
809 if (! MPLIST_SYMBOL_P (p) || MPLIST_SYMBOL (p) != key)
810 MERROR_GOTO (MERROR_IM, include_err);
812 while (! MPLIST_TAIL_P (p))
814 if (MPLIST_PLIST_P (p))
816 p0 = MPLIST_PLIST (p);
818 if (! MPLIST_SYMBOL_P (p0))
819 MERROR_GOTO (MERROR_IM, include_err);
822 p0 = mplist_find_by_value (elt, MPLIST_SYMBOL (p0));
837 if (! MPLIST_TAIL_P (p))
838 MERROR_GOTO (MERROR_IM, include_err);
839 mplist_set (plist, Mplist, MPLIST_PLIST (pl));
843 M17N_OBJECT_REF (pl);
844 MERROR_GOTO (MERROR_IM, err);
846 plist = MPLIST_NEXT (plist);
851 MPLIST_DO (elt, maps)
852 M17N_OBJECT_UNREF (MPLIST_VAL (elt));
853 M17N_OBJECT_UNREF (maps);
856 title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
857 MTEXT_FORMAT_US_ASCII);
860 im_info->title = title;
861 im_info->externals = externals;
862 im_info->macros = macros;
863 im_info->states = states;
869 MPLIST_DO (elt, maps)
870 M17N_OBJECT_UNREF (MPLIST_VAL (elt));
871 M17N_OBJECT_UNREF (maps);
874 M17N_OBJECT_UNREF (title);
877 MPLIST_DO (plist, states)
879 MIMState *state = (MIMState *) MPLIST_VAL (plist);
882 M17N_OBJECT_UNREF (state->title);
884 free_map (state->map);
887 M17N_OBJECT_UNREF (states);
891 MPLIST_DO (plist, externals)
893 MIMExternalModule *external = MPLIST_VAL (plist);
895 dlclose (external->handle);
896 M17N_OBJECT_UNREF (external->func_list);
898 MPLIST_KEY (plist) = Mt;
900 M17N_OBJECT_UNREF (externals);
907 static int take_action_list (MInputContext *ic, MPlist *action_list);
908 static void preedit_commit (MInputContext *ic);
911 shift_state (MInputContext *ic, MSymbol state_name)
913 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
914 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
915 MIMState *orig_state = ic_info->state, *state;
917 /* Find a state to shift to. If not found, shift to the initial
919 if (state_name == Mt)
921 if (! ic_info->prev_state)
923 state = ic_info->prev_state;
927 state = (MIMState *) mplist_get (im_info->states, state_name);
929 state = (MIMState *) MPLIST_VAL (im_info->states);
932 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
934 /* Enter the new state. */
935 ic_info->state = state;
936 ic_info->map = state->map;
937 ic_info->state_key_head = ic_info->key_head;
938 if (state == (MIMState *) MPLIST_VAL (im_info->states))
939 /* We have shifted to the initial state. */
941 mtext_cpy (ic_info->preedit_saved, ic->preedit);
942 ic_info->state_pos = ic->cursor_pos;
943 if (state != orig_state )
945 if (state == (MIMState *) MPLIST_VAL (im_info->states))
946 ic_info->prev_state = NULL;
948 ic_info->prev_state = orig_state;
951 ic->status = state->title;
952 else if (! ic->status)
953 ic->status = im_info->title;
954 ic->status_changed = 1;
955 if (ic_info->map == ic_info->state->map
956 && ic_info->map->map_actions)
958 MDEBUG_PRINT (" init-actions:");
959 take_action_list (ic, ic_info->map->map_actions);
964 /* Find a candidate group that contains a candidate number INDEX from
965 PLIST. Set START_INDEX to the first candidate number of the group,
966 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
967 candidate group number if they are non-NULL. If INDEX is -1, find
968 the last candidate group. */
971 find_candidates_group (MPlist *plist, int index,
972 int *start_index, int *end_index, int *group_index)
974 int i = 0, gidx = 0, len;
976 MPLIST_DO (plist, plist)
978 if (MPLIST_MTEXT_P (plist))
979 len = mtext_nchars (MPLIST_MTEXT (plist));
981 len = mplist_length (MPLIST_PLIST (plist));
982 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
988 *end_index = i + len;
1000 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
1002 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1004 int nchars = mt ? mtext_nchars (mt) : 1;
1007 mtext_ins (ic->preedit, pos, mt);
1009 mtext_ins_char (ic->preedit, pos, c, 1);
1010 MPLIST_DO (markers, ic_info->markers)
1011 if (MPLIST_INTEGER (markers) > pos)
1012 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
1013 if (ic->cursor_pos >= pos)
1014 ic->cursor_pos += nchars;
1015 ic->preedit_changed = 1;
1020 preedit_delete (MInputContext *ic, int from, int to)
1022 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1025 mtext_del (ic->preedit, from, to);
1026 MPLIST_DO (markers, ic_info->markers)
1028 if (MPLIST_INTEGER (markers) > to)
1029 MPLIST_VAL (markers)
1030 = (void *) (MPLIST_INTEGER (markers) - (to - from));
1031 else if (MPLIST_INTEGER (markers) > from);
1032 MPLIST_VAL (markers) = (void *) from;
1034 if (ic->cursor_pos >= to)
1035 ic->cursor_pos -= to - from;
1036 else if (ic->cursor_pos > from)
1037 ic->cursor_pos = from;
1038 ic->preedit_changed = 1;
1042 preedit_commit (MInputContext *ic)
1044 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1045 int preedit_len = mtext_nchars (ic->preedit);
1047 if (preedit_len > 0)
1051 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1052 Mcandidate_list, NULL, 0);
1053 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1054 Mcandidate_index, NULL, 0);
1055 mtext_cat (ic->produced, ic->preedit);
1056 if ((mdebug__flag & mdebug_mask)
1057 && mtext_nchars (ic->produced) > 0)
1061 MDEBUG_PRINT (" (produced");
1062 for (i = 0; i < mtext_nchars (ic->produced); i++)
1063 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
1066 mtext_reset (ic->preedit);
1067 mtext_reset (ic_info->preedit_saved);
1068 MPLIST_DO (p, ic_info->markers)
1070 ic->cursor_pos = ic_info->state_pos = 0;
1071 ic->preedit_changed = 1;
1073 if (ic->candidate_list)
1075 ic->candidate_list = NULL;
1076 ic->candidate_show = 0;
1077 ic->candidates_changed = 1;
1080 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
1081 sizeof (int) * (ic_info->used - ic_info->key_head));
1082 ic_info->used -= ic_info->key_head;
1083 ic_info->state_key_head = ic_info->key_head = 0;
1087 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
1089 int code = marker_code (sym);
1091 if (mt && (code == '[' || code == ']'))
1095 if (code == '[' && current > 0)
1097 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
1101 else if (code == ']' && current < mtext_nchars (mt))
1103 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
1109 return (code == '<' ? 0
1110 : code == '>' ? limit
1111 : code == '-' ? current - 1
1112 : code == '+' ? current + 1
1113 : code == '=' ? current
1114 : code - '0' > limit ? limit
1118 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1122 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1124 int from = mtext_property_start (prop);
1125 int to = mtext_property_end (prop);
1127 MPlist *candidate_list = mtext_property_value (prop);
1128 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1130 int ingroup_index = idx - start;
1133 preedit_delete (ic, from, to);
1134 if (MPLIST_MTEXT_P (group))
1136 mt = MPLIST_MTEXT (group);
1137 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1145 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1146 i++, plist = MPLIST_NEXT (plist));
1147 mt = MPLIST_MTEXT (plist);
1148 preedit_insert (ic, from, mt, 0);
1149 to = from + mtext_nchars (mt);
1151 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1152 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1153 ic->cursor_pos = to;
1158 take_action_list (MInputContext *ic, MPlist *action_list)
1160 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1161 MPlist *candidate_list = ic->candidate_list;
1162 int candidate_index = ic->candidate_index;
1163 int candidate_show = ic->candidate_show;
1164 MTextProperty *prop;
1166 MPLIST_DO (action_list, action_list)
1172 if (MPLIST_MTEXT_P (action_list)
1173 || MPLIST_INTEGER_P (action_list))
1174 name = Minsert, args = action_list;
1175 else if (MPLIST_PLIST_P (action_list)
1176 && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list))
1177 || MPLIST_PLIST_P (MPLIST_PLIST (action_list))))
1178 name = Minsert, args = action_list;
1181 action = MPLIST_PLIST (action_list);
1182 name = MPLIST_SYMBOL (action);
1183 args = MPLIST_NEXT (action);
1186 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1187 if (name == Minsert)
1189 if (MPLIST_MTEXT_P (args))
1190 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1191 else if (MPLIST_INTEGER_P (args))
1192 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1193 else if (MPLIST_SYMBOL_P (args))
1195 int c = integer_value (ic, args);
1197 if (c >= 0 && c <= MCHAR_MAX)
1198 preedit_insert (ic, ic->cursor_pos, NULL, c);
1205 args = MPLIST_PLIST (args);
1206 if (MPLIST_MTEXT_P (args))
1208 preedit_insert (ic, ic->cursor_pos, NULL,
1209 mtext_ref_char (MPLIST_MTEXT (args), 0));
1214 mt = MPLIST_MTEXT (MPLIST_PLIST (args));
1215 preedit_insert (ic, ic->cursor_pos, mt, 0);
1216 len = mtext_nchars (mt);
1218 mtext_put_prop (ic->preedit,
1219 ic->cursor_pos - len, ic->cursor_pos,
1220 Mcandidate_list, args);
1221 mtext_put_prop (ic->preedit,
1222 ic->cursor_pos - len, ic->cursor_pos,
1223 Mcandidate_index, (void *) 0);
1226 else if (name == Mselect)
1229 int code, idx, gindex;
1230 int pos = ic->cursor_pos;
1234 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1237 if (MPLIST_SYMBOL_P (args))
1239 code = marker_code (MPLIST_SYMBOL (args));
1245 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1246 group = find_candidates_group (mtext_property_value (prop), idx,
1247 &start, &end, &gindex);
1249 if (code != '[' && code != ']')
1253 ? new_index (NULL, ic->candidate_index - start,
1254 end - start - 1, MPLIST_SYMBOL (args),
1256 : MPLIST_INTEGER (args)));
1259 find_candidates_group (mtext_property_value (prop), -1,
1264 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1269 int ingroup_index = idx - start;
1272 group = mtext_property_value (prop);
1273 len = mplist_length (group);
1286 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1287 idx += (MPLIST_MTEXT_P (group)
1288 ? mtext_nchars (MPLIST_MTEXT (group))
1289 : mplist_length (MPLIST_PLIST (group)));
1290 len = (MPLIST_MTEXT_P (group)
1291 ? mtext_nchars (MPLIST_MTEXT (group))
1292 : mplist_length (MPLIST_PLIST (group)));
1293 if (ingroup_index >= len)
1294 ingroup_index = len - 1;
1295 idx += ingroup_index;
1297 update_candidate (ic, prop, idx);
1299 else if (name == Mshow)
1300 ic->candidate_show = 1;
1301 else if (name == Mhide)
1302 ic->candidate_show = 0;
1303 else if (name == Mdelete)
1305 int len = mtext_nchars (ic->preedit);
1306 int to = (MPLIST_SYMBOL_P (args)
1307 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1309 : MPLIST_INTEGER (args));
1315 if (to < ic->cursor_pos)
1316 preedit_delete (ic, to, ic->cursor_pos);
1317 else if (to > ic->cursor_pos)
1318 preedit_delete (ic, ic->cursor_pos, to);
1320 else if (name == Mmove)
1322 int len = mtext_nchars (ic->preedit);
1324 = (MPLIST_SYMBOL_P (args)
1325 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1327 : MPLIST_INTEGER (args));
1333 if (pos != ic->cursor_pos)
1335 ic->cursor_pos = pos;
1336 ic->preedit_changed = 1;
1339 else if (name == Mmark)
1341 int code = marker_code (MPLIST_SYMBOL (args));
1344 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1345 (void *) ic->cursor_pos);
1347 else if (name == Mpushback)
1349 if (MPLIST_INTEGER_P (args))
1351 int num = MPLIST_INTEGER (args);
1354 ic_info->key_head -= num;
1356 ic_info->key_head = num;
1357 if (ic_info->key_head > ic_info->used)
1358 ic_info->key_head = ic_info->used;
1360 else if (MPLIST_MTEXT_P (args))
1362 MText *mt = MPLIST_MTEXT (args);
1363 int i, len = mtext_nchars (mt);
1366 ic_info->key_head--;
1367 for (i = 0; i < len; i++)
1369 key = one_char_symbol[MTEXT_DATA (mt)[i]];
1370 if (ic_info->key_head + i < ic_info->used)
1371 ic_info->keys[ic_info->key_head + i] = key;
1373 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1378 MPlist *plist = MPLIST_PLIST (args), *pl;
1382 ic_info->key_head--;
1384 MPLIST_DO (pl, plist)
1386 key = MPLIST_SYMBOL (pl);
1387 if (ic_info->key_head < ic_info->used)
1388 ic_info->keys[ic_info->key_head + i] = key;
1390 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1395 else if (name == Mcall)
1397 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1398 MIMExternalFunc func = NULL;
1399 MSymbol module, func_name;
1400 MPlist *func_args, *val;
1403 module = MPLIST_SYMBOL (args);
1404 args = MPLIST_NEXT (args);
1405 func_name = MPLIST_SYMBOL (args);
1407 if (im_info->externals)
1409 MIMExternalModule *external
1410 = (MIMExternalModule *) mplist_get (im_info->externals,
1413 func = (MIMExternalFunc) mplist_get (external->func_list,
1418 func_args = mplist ();
1419 mplist_add (func_args, Mt, ic);
1420 MPLIST_DO (args, MPLIST_NEXT (args))
1424 if (MPLIST_KEY (args) == Msymbol
1425 && MPLIST_KEY (args) != Mnil
1426 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1428 code = new_index (ic, ic->cursor_pos,
1429 mtext_nchars (ic->preedit),
1430 MPLIST_SYMBOL (args), ic->preedit);
1431 mplist_add (func_args, Minteger, (void *) code);
1434 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1436 val = (func) (func_args);
1437 M17N_OBJECT_UNREF (func_args);
1438 if (val && ! MPLIST_TAIL_P (val))
1439 ret = take_action_list (ic, val);
1440 M17N_OBJECT_UNREF (val);
1444 else if (name == Mshift)
1446 shift_state (ic, MPLIST_SYMBOL (args));
1448 else if (name == Mundo)
1450 int intarg = MPLIST_TAIL_P (args) ? 2 : MPLIST_INTEGER (args);
1453 mtext_reset (ic->preedit);
1454 mtext_reset (ic_info->preedit_saved);
1455 ic->cursor_pos = ic_info->state_pos = 0;
1456 ic_info->state_key_head = ic_info->key_head = 0;
1457 ic_info->used -= intarg;
1458 if (ic_info->used < 0)
1459 ic_info->used = 0, unhandled = 1;
1460 shift_state (ic, Mnil);
1465 else if (name == Mset || name == Madd || name == Msub
1466 || name == Mmul || name == Mdiv)
1468 MSymbol sym = MPLIST_SYMBOL (args);
1469 int val1 = (int) mplist_get (ic_info->vars, sym), val2;
1472 args = MPLIST_NEXT (args);
1473 val2 = integer_value (ic, args);
1475 val1 = val2, op = "=";
1476 else if (name == Madd)
1477 val1 += val2, op = "+=";
1478 else if (name == Msub)
1479 val1 -= val2, op = "-=";
1480 else if (name == Mmul)
1481 val1 *= val2, op = "*=";
1483 val1 /= val2, op = "/=";
1484 mplist_put (ic_info->vars, sym, (void *) val1);
1485 MDEBUG_PRINT3 ("(%s %s %d)", MSYMBOL_NAME (sym), op, val1);
1487 else if (name == Mequal || name == Mless || name == Mgreater)
1490 MPlist *actions1, *actions2;
1493 val1 = integer_value (ic, args);
1494 args = MPLIST_NEXT (args);
1495 val2 = integer_value (ic, args);
1496 args = MPLIST_NEXT (args);
1497 actions1 = MPLIST_PLIST (args);
1498 args = MPLIST_NEXT (args);
1499 if (MPLIST_TAIL_P (args))
1502 actions2 = MPLIST_PLIST (args);
1503 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
1504 if (name == Mequal ? val1 == val2
1505 : name == Mless ? val1 < val2
1508 MDEBUG_PRINT ("ok");
1509 ret = take_action_list (ic, actions1);
1513 MDEBUG_PRINT ("no");
1515 ret = take_action_list (ic, actions2);
1520 else if (name == Mcommit)
1522 preedit_commit (ic);
1524 else if (name == Munhandle)
1526 preedit_commit (ic);
1532 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1536 && (actions = mplist_get (im_info->macros, name)))
1538 if (take_action_list (ic, actions) < 0)
1545 ic->candidate_list = NULL;
1546 if (ic->cursor_pos > 0
1547 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
1550 ic->candidate_list = mtext_property_value (prop);
1552 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
1554 ic->candidate_from = mtext_property_start (prop);
1555 ic->candidate_to = mtext_property_end (prop);
1558 ic->candidates_changed |= (candidate_list != ic->candidate_list
1559 || candidate_index != ic->candidate_index
1560 || candidate_show != ic->candidate_show);
1565 /* Handle the input key KEY in the current state and map specified in
1566 the input context IC. If KEY is handled correctly, return 0.
1567 Otherwise, return -1. */
1570 handle_key (MInputContext *ic)
1572 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1573 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1574 MIMMap *map = ic_info->map;
1575 MIMMap *submap = NULL;
1576 MSymbol key = ic_info->keys[ic_info->key_head];
1579 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
1580 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
1586 submap = mplist_get (map->submaps, key);
1587 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
1588 submap = mplist_get (map->submaps, alias);
1593 MDEBUG_PRINT (" submap-found");
1594 mtext_cpy (ic->preedit, ic_info->preedit_saved);
1595 ic->preedit_changed = 1;
1596 ic->cursor_pos = ic_info->state_pos;
1597 ic_info->key_head++;
1598 ic_info->map = map = submap;
1599 if (map->map_actions)
1601 MDEBUG_PRINT (" map-actions:");
1602 if (take_action_list (ic, map->map_actions) < 0)
1604 MDEBUG_PRINT ("\n");
1608 else if (map->submaps)
1610 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
1612 MSymbol key = ic_info->keys[i];
1613 char *name = msymbol_name (key);
1615 if (! name[0] || ! name[1])
1616 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
1620 /* If this is the terminal map or we have shifted to another
1621 state, perform branch actions (if any). */
1622 if (! map->submaps || map != ic_info->map)
1624 if (map->branch_actions)
1626 MDEBUG_PRINT (" branch-actions:");
1627 if (take_action_list (ic, map->branch_actions) < 0)
1629 MDEBUG_PRINT ("\n");
1633 /* If MAP is still not the root map, shift to the current
1635 if (ic_info->map != ic_info->state->map)
1636 shift_state (ic, ic_info->state->name);
1641 /* MAP can not handle KEY. */
1643 /* If MAP is the root map of the initial state, it means that
1644 the current input method can not handle KEY. */
1645 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
1647 MDEBUG_PRINT (" unhandled\n");
1651 if (map != ic_info->state->map)
1653 /* If MAP is not the root map... */
1654 /* If MAP has branch actions, perform them. */
1655 if (map->branch_actions)
1657 MDEBUG_PRINT (" branch-actions:");
1658 if (take_action_list (ic, map->branch_actions) < 0)
1660 MDEBUG_PRINT ("\n");
1664 /* If MAP is still not the root map, shift to the current
1666 if (ic_info->map != ic_info->state->map)
1668 shift_state (ic, ic_info->state->name);
1670 /* If MAP has branch_actions, perform them. */
1671 if (ic_info->map->branch_actions)
1673 MDEBUG_PRINT (" brank-actions:");
1674 take_action_list (ic, ic_info->map->branch_actions);
1681 /* MAP is the root map, perform branch actions (if any) or
1682 shift to the initial state. */
1683 if (map->branch_actions)
1685 MDEBUG_PRINT (" branch-actions:");
1686 if (take_action_list (ic, map->branch_actions) < 0)
1688 MDEBUG_PRINT ("\n");
1693 shift_state (ic, Mnil);
1696 MDEBUG_PRINT ("\n");
1701 reset_ic (MInputContext *ic, MSymbol ignore)
1703 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1704 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1707 MDEBUG_PRINT ("\n [IM] reset\n");
1709 ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
1710 ic_info->prev_state = NULL;
1711 ic_info->map = ic_info->state->map;
1712 ic_info->state_key_head = ic_info->key_head;
1713 MLIST_RESET (ic_info);
1714 ic_info->key_unhandled = 0;
1716 if (mtext_nchars (ic->produced) > 0)
1717 mtext_reset (ic->produced);
1718 if (mtext_nchars (ic->preedit) > 0)
1722 mtext_reset (ic->preedit);
1723 MPLIST_DO (plist, ic_info->markers)
1724 MPLIST_VAL (plist) = 0;
1725 ic->preedit_changed = 1;
1727 if (ic->candidate_show)
1729 ic->candidate_show = 0;
1730 if (ic->candidate_list)
1732 ic->candidate_list = NULL;
1733 ic->candidates_changed = 1;
1736 mtext_reset (ic_info->preedit_saved);
1737 ic_info->state_pos = ic->cursor_pos = 0;
1739 status = ic_info->state->title ? ic_info->state->title : im_info->title;
1740 if (ic->status != status)
1742 ic->status = status;
1743 ic->status_changed = 1;
1748 open_im (MInputMethod *im)
1751 MInputMethodInfo *im_info;
1755 mdb = mdatabase_find (Minput_method, im->language, im->name, Mnil);
1758 plist = mdatabase_load (mdb);
1760 MERROR (MERROR_IM, -1);
1761 MSTRUCT_CALLOC (im_info, MERROR_IM);
1763 result = load_input_method (im->language, im->name, plist, im_info);
1764 M17N_OBJECT_UNREF (plist);
1766 MERROR (MERROR_IM, -1);
1771 close_im (MInputMethod *im)
1773 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1777 M17N_OBJECT_UNREF (im_info->title);
1778 if (im_info->states)
1780 MPLIST_DO (plist, im_info->states)
1782 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1785 M17N_OBJECT_UNREF (state->title);
1787 free_map (state->map);
1790 M17N_OBJECT_UNREF (im_info->states);
1793 if (im_info->macros)
1795 MPLIST_DO (plist, im_info->macros)
1796 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1797 M17N_OBJECT_UNREF (im_info->macros);
1800 if (im_info->externals)
1802 MPLIST_DO (plist, im_info->externals)
1804 MIMExternalModule *external = MPLIST_VAL (plist);
1806 dlclose (external->handle);
1807 M17N_OBJECT_UNREF (external->func_list);
1809 MPLIST_KEY (plist) = Mt;
1811 M17N_OBJECT_UNREF (im_info->externals);
1819 create_ic (MInputContext *ic)
1821 MInputMethod *im = ic->im;
1822 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1823 MInputContextInfo *ic_info;
1826 ic_info = (MInputContextInfo *) ic->info;
1829 MSTRUCT_CALLOC (ic_info, MERROR_IM);
1832 MLIST_INIT1 (ic_info, keys, 8);
1833 ic_info->markers = mplist ();
1834 ic_info->vars = mplist ();
1835 ic_info->preedit_saved = mtext ();
1836 if (im_info->externals)
1838 MPlist *func_args = mplist (), *plist;
1840 mplist_add (func_args, Mt, ic);
1841 MPLIST_DO (plist, im_info->externals)
1843 MIMExternalModule *external = MPLIST_VAL (plist);
1844 MIMExternalFunc func
1845 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
1850 M17N_OBJECT_UNREF (func_args);
1852 reset_ic (ic, Mnil);
1857 destroy_ic (MInputContext *ic)
1859 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1860 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1862 if (im_info->externals)
1864 MPlist *func_args = mplist (), *plist;
1866 mplist_add (func_args, Mt, ic);
1867 MPLIST_DO (plist, im_info->externals)
1869 MIMExternalModule *external = MPLIST_VAL (plist);
1870 MIMExternalFunc func
1871 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
1876 M17N_OBJECT_UNREF (func_args);
1878 MLIST_FREE1 (ic_info, keys);
1879 M17N_OBJECT_UNREF (ic_info->preedit_saved);
1880 M17N_OBJECT_UNREF (ic_info->markers);
1881 M17N_OBJECT_UNREF (ic_info->vars);
1886 /** Handle the input key KEY in the current state and map of IC->info.
1887 If KEY is handled but no text is produced, return 0, otherwise
1893 filter (MInputContext *ic, MSymbol key, void *arg)
1895 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1896 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1899 if (! ic_info->state)
1901 ic_info->key_unhandled = 1;
1904 mtext_reset (ic->produced);
1905 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
1906 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1907 ic_info->key_unhandled = 0;
1909 if (handle_key (ic) < 0)
1911 /* KEY was not handled. Delete it from the current key sequence. */
1912 if (ic_info->used > 0)
1914 memmove (ic_info->keys, ic_info->keys + 1,
1915 sizeof (int) * (ic_info->used - 1));
1918 /* This forces returning 1. */
1919 ic_info->key_unhandled = 1;
1925 reset_ic (ic, Mnil);
1926 ic_info->key_unhandled = 1;
1929 /* Break the loop if all keys were handled. */
1930 } while (ic_info->key_head < ic_info->used);
1932 /* If the current map is the root of the initial state, we should
1933 produce any preedit text in ic->produced. */
1934 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
1935 && mtext_nchars (ic->preedit) > 0)
1936 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1938 if (mtext_nchars (ic->produced) > 0)
1940 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
1943 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1944 Mlanguage, ic->im->language);
1947 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
1951 /** Return 1 if the last event or key was not handled, otherwise
1954 There is no need of looking up because ic->produced should already
1955 contain the produced text (if any).
1960 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1962 mtext_cat (mt, ic->produced);
1963 mtext_reset (ic->produced);
1964 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
1968 load_im_info (MSymbol language, MSymbol name, MSymbol key)
1973 if (language == Mnil || name == Mnil)
1974 MERROR (MERROR_IM, NULL);
1976 mdb = mdatabase_find (Minput_method, language, name, Mnil);
1978 MERROR (MERROR_IM, NULL);
1980 mplist_push (load_im_info_keys, Mmap, Mt);
1981 mplist_push (load_im_info_keys, key, Mt);
1982 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
1983 mplist_pop (load_im_info_keys);
1985 mplist_pop (load_im_info_keys);
1990 /* Input method command handler. */
1992 /* List of all (global and local) commands.
1993 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
1994 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
1995 Global commands are storead as (t (t COMMAND ...)) */
1996 static MPlist *command_list;
1998 /* Check if PLIST is a valid command key sequence.
1999 PLIST must be NULL or:
2000 [ symbol:KEY | integer:KEY ] ... */
2003 check_command_keyseq (MPlist *plist)
2007 MPLIST_DO (plist, plist)
2009 if (MPLIST_SYMBOL_P (plist))
2011 else if (MPLIST_INTEGER_P (plist))
2013 int n = MPLIST_INTEGER (plist);
2017 MPLIST_KEY (plist) = Msymbol;
2018 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2027 get_description_advance (MPlist *plist)
2032 if (! MPLIST_MTEXT_P (plist))
2034 mt = mplist_pop (plist);
2035 pos = mtext_chr (mt, '\n');
2038 MText *detail = mtext_copy (mtext (), 0, mt, pos + 1, mtext_nchars (mt));
2039 mtext_del (mt, pos, mtext_nchars (mt));
2040 mtext_put_prop (mt, 0, pos, Mdetail_text, detail);
2041 M17N_OBJECT_UNREF (detail);
2047 parse_command_list (MPlist *plist, MPlist *global_list)
2049 MPlist *val = mplist ();
2051 /* PLIST ::= (sym:CMD mtext:DESCRIPTION ? (sym:KEY ...) ...) ... */
2052 MPLIST_DO (plist, plist)
2056 MPlist *this_val, *pl, *p;
2058 if (! MPLIST_PLIST_P (plist))
2060 pl = MPLIST_PLIST (plist);
2061 if (! MPLIST_SYMBOL_P (pl))
2063 cmd = MPLIST_SYMBOL (pl);
2064 pl = MPLIST_NEXT (pl);
2065 mt = get_description_advance (pl);
2066 this_val = mplist ();
2068 if (! mt && global_list)
2070 /* Get the description from global_list. */
2071 p = mplist_get (global_list, cmd);
2072 if (p && MPLIST_MTEXT (p))
2074 mt = MPLIST_MTEXT (p);
2075 M17N_OBJECT_REF (mt);
2080 mplist_add (this_val, Mtext, mt);
2081 M17N_OBJECT_UNREF (mt);
2083 /* PL ::= (sym:KEY ...) ... */
2086 if (MPLIST_PLIST_P (pl)
2087 && check_command_keyseq (MPLIST_PLIST (pl)) >= 0)
2088 /* All the elements are valid keys. */
2089 mplist_add (this_val, Mplist, MPLIST_PLIST (pl));
2092 mplist_put (val, cmd, this_val);
2098 get_command_list (MSymbol language, MSymbol name)
2104 language = name = Mt;
2108 MDatabase *mdb = mdatabase_find (msymbol ("input"), M_command,
2111 if (mdb && (plist = mdatabase_load (mdb)))
2113 pl = parse_command_list (plist, NULL);
2114 M17N_OBJECT_UNREF (plist);
2119 mplist_add (plist, Mt, pl);
2120 command_list = mplist ();
2121 mplist_add (command_list, Mt, plist);
2124 per_lang = mplist_get (command_list, language);
2127 plist = mplist_find_by_key (per_lang, name);
2129 return (MPLIST_VAL (plist));
2133 per_lang = mplist ();
2134 mplist_add (command_list, language, per_lang);
2137 /* Now we are sure that we are loading per-im info. */
2138 /* Get the global command list. */
2139 plist = load_im_info (language, name, M_command);
2140 if (! plist || mplist_key (plist) == Mnil)
2144 mplist_add (per_lang, name, plist);
2147 pl = parse_command_list (mplist_value (plist),
2148 mplist_get ((MPlist *) mplist_get (command_list, Mt),
2150 M17N_OBJECT_UNREF (plist);
2151 mplist_put (per_lang, name, pl);
2156 /* Input method variable handler. */
2158 /* List of all variables.
2159 (LANG:(IM-NAME:(VAR ...) ...) ...) ...
2160 VAR is VAR-NAME:(mtext:DESCRIPTION TYPE:VALUE ...)) */
2162 static MPlist *variable_list;
2165 parse_variable_list (MPlist *plist)
2167 MPlist *val = mplist (), *pl, *p;
2169 /* PLIST ::= (sym:VAR mtext:DESCRIPTION TYPE:INIT-VAL ...) ... */
2170 MPLIST_DO (plist, plist)
2176 if (! MPLIST_PLIST_P (plist))
2178 pl = MPLIST_PLIST (plist);
2179 if (! MPLIST_SYMBOL_P (pl))
2181 var = MPLIST_SYMBOL (pl);
2182 pl = MPLIST_NEXT (pl);
2183 mt = get_description_advance (pl);
2184 if (! mt || MPLIST_TAIL_P (pl))
2186 this_val = mplist ();
2187 mplist_add (this_val, Mtext, mt);
2188 M17N_OBJECT_UNREF (mt);
2189 type = MPLIST_KEY (pl);
2190 mplist_add (this_val, type, MPLIST_VAL (pl));
2191 MPLIST_DO (pl, MPLIST_NEXT (pl))
2193 if (type != MPLIST_KEY (pl)
2194 && (type != Minteger || ! MPLIST_PLIST_P (pl)))
2196 if (MPLIST_PLIST_P (pl))
2198 MPLIST_DO (p, MPLIST_PLIST (pl))
2199 if (! MPLIST_INTEGER_P (p))
2201 if (! MPLIST_TAIL_P (p))
2204 mplist_add (this_val, MPLIST_KEY (pl), MPLIST_VAL (pl));
2207 mplist_put (val, var, this_val);
2214 get_variable_list (MSymbol language, MSymbol name)
2219 if (language == Mnil || name == Mnil)
2220 MERROR (MERROR_IM, NULL);
2221 if (! variable_list)
2222 variable_list = mplist ();
2223 per_lang = mplist_get (variable_list, language);
2226 plist = mplist_find_by_key (per_lang, name);
2228 return (MPLIST_VAL (plist));
2232 per_lang = mplist ();
2233 mplist_add (variable_list, language, per_lang);
2235 plist = load_im_info (language, name, M_variable);
2236 if (! plist || mplist_key (plist) == Mnil)
2240 mplist_add (per_lang, name, plist);
2243 pl = parse_variable_list (mplist_value (plist));
2244 M17N_OBJECT_UNREF (plist);
2245 mplist_put (per_lang, name, pl);
2249 typedef struct _MDatabaseStatList
2252 time_t mtime, ctime;
2253 struct _MDatabaseStatList *next;
2254 } MDatabaseStatList;
2256 static MDatabaseStatList *imdir_stat_list;
2258 /* This function is called before any operation with tag0 specified as
2259 `input-method' on the m17n database. It lists all *.mim files and
2260 add them to the database. */
2263 input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
2265 MPlist *plist, *pl, *p;
2266 char path[PATH_MAX];
2269 mplist_push (load_im_info_keys, Mmap, Mt);
2270 mplist_push (load_im_info_keys, M_description, Mt);
2271 MPLIST_DO (plist, mdatabase__dir_list)
2273 char *dirname = (char *) MPLIST_VAL (plist);
2275 MDatabaseStatList *stlist;
2280 if (stat (dirname, &st) < 0
2281 || ! S_ISDIR (st.st_mode))
2283 for (stlist = imdir_stat_list; stlist; stlist = stlist->next)
2284 if (strcmp (stlist->dirname, dirname) == 0)
2288 MSTRUCT_MALLOC (stlist, MERROR_IM);
2289 stlist->dirname = strdup (dirname);
2290 stlist->next = imdir_stat_list;
2291 imdir_stat_list = stlist;
2293 else if (stlist->mtime == st.st_mtime
2294 && stlist->ctime == st.st_ctime)
2295 /* This directory is not changed since we checked last
2298 stlist->mtime = st.st_mtime;
2299 stlist->ctime = st.st_ctime;
2301 dir = opendir (dirname);
2304 dirlen = strlen (dirname);
2305 strcpy (path, dirname);
2306 while ((dp = readdir (dir)) != NULL)
2308 /* We can't trust dp->d_nameln. */
2309 int len = strlen (dp->d_name);
2312 if (len > 4 && memcmp (dp->d_name + len - 4, ".mim", 4) == 0)
2314 strcpy (path + dirlen, dp->d_name);
2315 fp = fopen (path, "r");
2318 pl = mplist__from_file (fp, load_im_info_keys);
2322 if (MPLIST_PLIST_P (pl))
2324 p = MPLIST_PLIST (pl);
2325 p = MPLIST_NEXT (p);
2326 if (MPLIST_SYMBOL_P (p))
2328 tag1 = MPLIST_VAL (p);
2329 p = MPLIST_NEXT (p);
2330 if (MPLIST_SYMBOL_P (p))
2334 tag2 = MPLIST_VAL (p);
2335 mdb = mdatabase_find (tag0, tag2, tag2, tag3);
2337 mdatabase_define (tag0, tag1, tag2, tag3,
2342 M17N_OBJECT_UNREF (pl);
2348 mplist_pop (load_im_info_keys);
2349 mplist_pop (load_im_info_keys);
2353 /* Support functions for mdebug_dump_im. */
2356 dump_im_map (MPlist *map_list, int indent)
2359 MSymbol key = MPLIST_KEY (map_list);
2360 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2362 prefix = (char *) alloca (indent + 1);
2363 memset (prefix, 32, indent);
2364 prefix[indent] = '\0';
2366 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2367 if (map->map_actions)
2368 mdebug_dump_plist (map->map_actions, indent + 2);
2371 MPLIST_DO (map_list, map->submaps)
2373 fprintf (stderr, "\n%s ", prefix);
2374 dump_im_map (map_list, indent + 2);
2377 if (map->branch_actions)
2379 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2380 mdebug_dump_plist (map->branch_actions, indent + 4);
2381 fprintf (stderr, ")");
2383 fprintf (stderr, ")");
2388 dump_im_state (MIMState *state, int indent)
2393 prefix = (char *) alloca (indent + 1);
2394 memset (prefix, 32, indent);
2395 prefix[indent] = '\0';
2397 fprintf (stderr, "(%s", msymbol_name (state->name));
2398 if (state->map->submaps)
2400 MPLIST_DO (map_list, state->map->submaps)
2402 fprintf (stderr, "\n%s ", prefix);
2403 dump_im_map (map_list, indent + 2);
2406 fprintf (stderr, ")");
2415 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2416 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2417 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2418 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2419 char buf[6], buf2[256];
2423 Minput_method = msymbol ("input-method");
2424 msymbol_put (Minput_method, M_database_hook, (void *) input_method_hook);
2425 Minput_driver = msymbol ("input-driver");
2426 Mtitle = msymbol ("title");
2427 Mmacro = msymbol ("macro");
2428 Mmodule = msymbol ("module");
2429 Mmap = msymbol ("map");
2430 Mstate = msymbol ("state");
2431 Minclude = msymbol ("include");
2432 Minsert = msymbol ("insert");
2433 Mdelete = msymbol ("delete");
2434 Mmove = msymbol ("move");
2435 Mmark = msymbol ("mark");
2436 Mpushback = msymbol ("pushback");
2437 Mundo = msymbol ("undo");
2438 Mcall = msymbol ("call");
2439 Mshift = msymbol ("shift");
2440 Mselect = msymbol ("select");
2441 Mshow = msymbol ("show");
2442 Mhide = msymbol ("hide");
2443 Mcommit = msymbol ("commit");
2444 Munhandle = msymbol ("unhandle");
2445 Mset = msymbol ("set");
2446 Madd = msymbol ("add");
2447 Msub = msymbol ("sub");
2448 Mmul = msymbol ("mul");
2449 Mdiv = msymbol ("div");
2450 Mequal = msymbol ("=");
2451 Mless = msymbol ("<");
2452 Mgreater = msymbol (">");
2454 Minput_preedit_start = msymbol ("input-preedit-start");
2455 Minput_preedit_done = msymbol ("input-preedit-done");
2456 Minput_preedit_draw = msymbol ("input-preedit-draw");
2457 Minput_status_start = msymbol ("input-status-start");
2458 Minput_status_done = msymbol ("input-status-done");
2459 Minput_status_draw = msymbol ("input-status-draw");
2460 Minput_candidates_start = msymbol ("input-candidates-start");
2461 Minput_candidates_done = msymbol ("input-candidates-done");
2462 Minput_candidates_draw = msymbol ("input-candidates-draw");
2463 Minput_set_spot = msymbol ("input-set-spot");
2464 Minput_focus_move = msymbol ("input-focus-move");
2465 Minput_focus_in = msymbol ("input-focus-in");
2466 Minput_focus_out = msymbol ("input-focus-out");
2467 Minput_toggle = msymbol ("input-toggle");
2468 Minput_reset = msymbol ("input-reset");
2470 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2471 Mcandidate_index = msymbol (" candidate-index");
2473 Minit = msymbol ("init");
2474 Mfini = msymbol ("fini");
2476 M_key_alias = msymbol (" key-alias");
2477 M_description = msymbol ("description");
2478 M_command = msymbol ("command");
2479 M_variable = msymbol ("variable");
2481 Mdetail_text = msymbol_as_managing_key (" detail-text");
2483 load_im_info_keys = mplist ();
2484 plist = mplist_add (load_im_info_keys, Mstate, Mnil);
2489 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2493 one_char_symbol[i] = msymbol (buf);
2496 alias = msymbol (key_names[i]);
2497 msymbol_put (one_char_symbol[i], M_key_alias, alias);
2500 alias = one_char_symbol[i];
2501 buf[2] += (i == 0) ? -32 : 32;
2502 msymbol_put (alias, M_key_alias, msymbol (buf));
2503 buf[2] -= (i == 0) ? -32 : 32;
2505 for (buf[2] = i; i < 127; i++, buf[2]++)
2506 one_char_symbol[i] = msymbol (buf + 2);
2507 one_char_symbol[i++] = msymbol ("Delete");
2513 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2515 one_char_symbol[i] = msymbol (buf);
2516 if (key_names[i - 128])
2518 strcpy (buf2 + 2, key_names[i - 128]);
2519 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2522 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2523 one_char_symbol[i] = msymbol (buf + 2);
2524 one_char_symbol[i] = msymbol ("M-Delete");
2526 command_list = variable_list = NULL;
2528 minput_default_driver.open_im = open_im;
2529 minput_default_driver.close_im = close_im;
2530 minput_default_driver.create_ic = create_ic;
2531 minput_default_driver.destroy_ic = destroy_ic;
2532 minput_default_driver.filter = filter;
2533 minput_default_driver.lookup = lookup;
2534 minput_default_driver.callback_list = mplist ();
2535 mplist_put (minput_default_driver.callback_list, Minput_reset,
2537 minput_driver = &minput_default_driver;
2544 MPlist *par_lang, *par_im, *p;
2548 MPLIST_DO (par_lang, command_list)
2550 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2552 MPLIST_DO (p, MPLIST_VAL (par_im))
2553 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2554 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2556 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2558 M17N_OBJECT_UNREF (command_list);
2559 command_list = NULL;
2563 MPLIST_DO (par_lang, variable_list)
2565 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2567 MPLIST_DO (p, MPLIST_VAL (par_im))
2568 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2569 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2571 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2573 M17N_OBJECT_UNREF (variable_list);
2574 variable_list = NULL;
2577 if (minput_default_driver.callback_list)
2579 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2580 minput_default_driver.callback_list = NULL;
2582 if (minput_driver->callback_list)
2584 M17N_OBJECT_UNREF (minput_driver->callback_list);
2585 minput_driver->callback_list = NULL;
2588 M17N_OBJECT_UNREF (load_im_info_keys);
2590 while (imdir_stat_list)
2592 MDatabaseStatList *next = imdir_stat_list->next;
2594 free (imdir_stat_list->dirname);
2595 free (imdir_stat_list);
2596 imdir_stat_list = next;
2601 minput__callback (MInputContext *ic, MSymbol command)
2603 if (ic->im->driver.callback_list)
2605 MInputCallbackFunc func
2606 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2610 (func) (ic, command);
2615 minput__char_to_key (int c)
2617 if (c < 0 || c >= 0x100)
2620 return one_char_symbol[c];
2624 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2629 /*** @addtogroup m17nInputMethod */
2634 @name Variables: Predefined symbols for callback commands.
2636 These are the predefined symbols that are used as the @c COMMAND
2637 argument of callback functions of an input method driver (see
2638 #MInputDriver::callback_list ). */
2640 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2642 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2643 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2648 MSymbol Minput_preedit_start;
2649 MSymbol Minput_preedit_done;
2650 MSymbol Minput_preedit_draw;
2651 MSymbol Minput_status_start;
2652 MSymbol Minput_status_done;
2653 MSymbol Minput_status_draw;
2654 MSymbol Minput_candidates_start;
2655 MSymbol Minput_candidates_done;
2656 MSymbol Minput_candidates_draw;
2657 MSymbol Minput_set_spot;
2658 MSymbol Minput_toggle;
2659 MSymbol Minput_reset;
2665 @name Variables: Predefined symbols for special input events.
2667 These are the predefined symbols that are used as the @c KEY
2668 argument of minput_filter (). */
2673 MSymbol Minput_focus_out;
2674 MSymbol Minput_focus_in;
2675 MSymbol Minput_focus_move;
2682 @brief The default driver for internal input methods.
2684 The variable #minput_default_driver is the default driver for
2685 internal input methods.
2687 The member MInputDriver::open_im () searches the m17n database for
2688 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2689 $NAME\> and loads it.
2691 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2692 programmers responsibility to set it to a plist of proper callback
2693 functions. Otherwise, no feedback information (e.g. preedit text)
2694 can be shown to users.
2696 The macro M17N_INIT () sets the variable #minput_driver to the
2697 pointer to this driver so that all internal input methods use it.
2699 Therefore, unless @c minput_driver is set differently, the driver
2700 dependent arguments $ARG of the functions whose name begin with
2701 "minput_" are all ignored. */
2704 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2706 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2708 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2709 \< #Minput_method, $LANGUAGE, $NAME\>
2710 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2712 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2713 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2714 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2715 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2717 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2718 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2720 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2721 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2723 MInputDriver minput_default_driver;
2727 @brief The driver for internal input methods.
2729 The variable #minput_driver is a pointer to the input method
2730 driver that is used by internal input methods. The macro
2731 M17N_INIT () initializes it to a pointer to #minput_default_driver
2732 if <m17n<EM></EM>.h> is included. */
2734 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
2736 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
2737 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
2738 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
2739 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
2741 MInputDriver *minput_driver;
2743 MSymbol Minput_driver;
2748 @brief Open an input method.
2750 The minput_open_im () function opens an input method that matches
2751 language $LANGUAGE and name $NAME, and returns a pointer to the
2752 input method object newly allocated.
2754 This function at first decides an driver for the input method as
2757 If $LANGUAGE is not #Mnil, the driver pointed by the variable
2758 #minput_driver is used.
2760 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
2761 driver pointed to by the property value is used to open the input
2762 method. If $NAME has no such property, @c NULL is returned.
2764 Then, the member MInputDriver::open_im () of the driver is
2767 $ARG is set in the member @c arg of the structure MInputMethod so
2768 that the driver can refer to it. */
2771 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
2773 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
2774 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2776 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
2778 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
2779 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
2781 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
2782 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
2783 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2785 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
2787 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
2789 @latexonly \IPAlabel{minput_open} @endlatexonly
2794 minput_open_im (MSymbol language, MSymbol name, void *arg)
2797 MInputDriver *driver;
2799 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
2800 msymbol_name (language), msymbol_name (name));
2802 driver = minput_driver;
2805 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
2807 MERROR (MERROR_IM, NULL);
2810 MSTRUCT_CALLOC (im, MERROR_IM);
2811 im->language = language;
2814 im->driver = *driver;
2815 if ((*im->driver.open_im) (im) < 0)
2817 MDEBUG_PRINT (" failed\n");
2821 MDEBUG_PRINT (" ok\n");
2828 @brief Close an input method.
2830 The minput_close_im () function closes the input method $IM, which
2831 must have been created by minput_open_im (). */
2834 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
2836 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
2837 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
2840 minput_close_im (MInputMethod *im)
2842 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
2843 msymbol_name (im->name), msymbol_name (im->language));
2844 (*im->driver.close_im) (im);
2846 MDEBUG_PRINT (" done\n");
2852 @brief Create an input context.
2854 The minput_create_ic () function creates an input context object
2855 associated with input method $IM, and calls callback functions
2856 corresponding to #Minput_preedit_start, #Minput_status_start, and
2857 #Minput_status_draw in this order.
2861 If an input context is successfully created, minput_create_ic ()
2862 returns a pointer to it. Otherwise it returns @c NULL. */
2865 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
2867 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
2868 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
2869 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
2870 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2874 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
2875 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2879 minput_create_ic (MInputMethod *im, void *arg)
2883 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
2884 msymbol_name (im->name), msymbol_name (im->language));
2885 MSTRUCT_CALLOC (ic, MERROR_IM);
2888 ic->preedit = mtext ();
2889 ic->candidate_list = NULL;
2890 ic->produced = mtext ();
2891 ic->spot.x = ic->spot.y = 0;
2893 ic->plist = mplist ();
2894 if ((*im->driver.create_ic) (ic) < 0)
2896 MDEBUG_PRINT (" failed\n");
2897 M17N_OBJECT_UNREF (ic->preedit);
2898 M17N_OBJECT_UNREF (ic->produced);
2899 M17N_OBJECT_UNREF (ic->plist);
2904 if (im->driver.callback_list)
2906 minput__callback (ic, Minput_preedit_start);
2907 minput__callback (ic, Minput_status_start);
2908 minput__callback (ic, Minput_status_draw);
2911 MDEBUG_PRINT (" ok\n");
2918 @brief Destroy an input context.
2920 The minput_destroy_ic () function destroys the input context $IC,
2921 which must have been created by minput_create_ic (). It calls
2922 callback functions corresponding to #Minput_preedit_done,
2923 #Minput_status_done, and #Minput_candidates_done in this order. */
2926 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
2928 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
2929 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
2930 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
2931 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
2932 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2936 minput_destroy_ic (MInputContext *ic)
2938 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
2939 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
2940 if (ic->im->driver.callback_list)
2942 minput__callback (ic, Minput_preedit_done);
2943 minput__callback (ic, Minput_status_done);
2944 minput__callback (ic, Minput_candidates_done);
2946 (*ic->im->driver.destroy_ic) (ic);
2947 M17N_OBJECT_UNREF (ic->preedit);
2948 M17N_OBJECT_UNREF (ic->produced);
2949 M17N_OBJECT_UNREF (ic->plist);
2950 MDEBUG_PRINT (" done\n");
2957 @brief Filter an input key.
2959 The minput_filter () function filters input key $KEY according to
2960 input context $IC, and calls callback functions corresponding to
2961 #Minput_preedit_draw, #Minput_status_draw, and
2962 #Minput_candidates_draw if the preedit text, the status, and the
2963 current candidate are changed respectively.
2965 To make the input method commit the current preedit text (if any)
2966 and shift to the initial state, call this function with #Mnil as
2969 To inform the input method about the focus-out event, call this
2970 function with #Minput_focus_out as $KEY.
2972 To inform the input method about the focus-in event, call this
2973 function with #Minput_focus_in as $KEY.
2975 To inform the input method about the focus-move event (i.e. input
2976 spot change within the same input context), call this function
2977 with #Minput_focus_move as $KEY.
2980 If $KEY is filtered out, this function returns 1. In that case,
2981 the caller should discard the key. Otherwise, it returns 0, and
2982 the caller should handle the key, for instance, by calling the
2983 function minput_lookup () with the same key. */
2986 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
2988 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2989 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
2990 #Minput_preedit_draw, #Minput_status_draw,
2991 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
2994 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
2995 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
2996 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
2997 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
2999 @latexonly \IPAlabel{minput_filter} @endlatexonly
3003 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3010 ret = (*ic->im->driver.filter) (ic, key, arg);
3012 if (ic->im->driver.callback_list)
3014 if (ic->preedit_changed)
3015 minput__callback (ic, Minput_preedit_draw);
3016 if (ic->status_changed)
3017 minput__callback (ic, Minput_status_draw);
3018 if (ic->candidates_changed)
3019 minput__callback (ic, Minput_candidates_draw);
3028 @brief Look up a text produced in the input context.
3030 The minput_lookup () function looks up a text in the input context
3031 $IC. $KEY must be the same one provided to the previous call of
3034 If a text was produced by the input method, it is concatenated
3037 This function calls #MInputDriver::lookup .
3040 If $KEY was correctly handled by the input method, this function
3041 returns 0. Otherwise, returns -1, even in that case, some text
3042 may be produced in $MT. */
3045 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3047 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3048 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3050 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3053 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3056 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3057 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3058 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3060 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3063 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3065 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3070 @brief Set the spot of the input context.
3072 The minput_set_spot () function set the spot of input context $IC
3073 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3074 The semantics of these values depend on the input method driver.
3076 For instance, a driver designed to work in a CUI environment may
3077 use $X and $Y as column and row numbers, and ignore $ASCENT and
3078 $DESCENT . A driver designed to work in a window system may
3079 interpret $X and $Y as pixel offsets relative to the origin of the
3080 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3081 descent pixels of the line at ($X . $Y ).
3083 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3085 $MT and $POS is the M-text and the character position at the spot.
3086 $MT may be @c NULL, in which case, the input method cannot get
3087 information about the text around the spot. */
3090 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3092 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3093 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3094 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3096 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3097 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3098 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3099 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3100 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3101 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3103 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3105 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3106 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3110 minput_set_spot (MInputContext *ic, int x, int y,
3111 int ascent, int descent, int fontsize,
3116 ic->spot.ascent = ascent;
3117 ic->spot.descent = descent;
3118 ic->spot.fontsize = fontsize;
3121 if (ic->im->driver.callback_list)
3122 minput__callback (ic, Minput_set_spot);
3127 @brief Toggle input method.
3129 The minput_toggle () function toggles the input method associated
3130 with input context $IC. */
3132 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3134 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3135 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3139 minput_toggle (MInputContext *ic)
3141 if (ic->im->driver.callback_list)
3142 minput__callback (ic, Minput_toggle);
3143 ic->active = ! ic->active;
3147 @brief Reset an input context.
3149 The minput_reset_ic () function resets input context $IC by
3150 calling a callback function corresponding to #Minput_reset. It
3151 resets the status of $IC to the one of just after created. As the
3152 current preedit text is deleted without commitment, if necessary,
3153 call minput_filter () with the arg @r key #Mnil to force the input
3154 method to commit the preedit in advance. */
3157 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3159 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3160 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3161 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3162 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3163 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3164 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3167 minput_reset_ic (MInputContext *ic)
3169 if (ic->im->driver.callback_list)
3170 minput__callback (ic, Minput_reset);
3175 @brief Key of a text property for detailed description.
3177 The symbol #Mdetail_text is a managing key usually used for a
3178 text property whose value is an M-text that contains detailed
3181 @brief ¾ÜºÙÀâÌÀÍѥƥ¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼.
3183 ¥·¥ó¥Ü¥ë #Mdetail_text ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ê¡¢Ä̾ï¾ÜºÙ¤ÊÀâÌÀ¤ò´Þ¤à
3184 M-text ¤òÃͤȤ·¤Æ»ý¤Ä¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ËÍѤ¤¤é¤ì¤ë¡£
3186 MSymbol Mdetail_text;
3189 @brief Get description text of an input method.
3191 The minput_get_description () function returns an M-text that
3192 briefly describes the input method specified by $LANGUAGE and
3193 $NAME. The returned M-text may have a text property, from its
3194 beginning to end, #Mdetail_text whose value is an M-text
3195 describing the input method in more detail.
3198 If the specified input method has a description text, a pointer to
3199 #MText is returned. A caller have to free it by m17n_object_unref ().
3200 If the input method does not have a description text, @c NULL is
3203 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3205 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME
3206 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£ÊÖ¤µ¤ì¤ë M-text
3207 ¤Ë¤Ï¡¢¤½¤ÎÁ´ÂΤËÂФ·¤Æ #Mdetail_text
3208 ¤È¤¤¤¦¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬Éղ䵤ì¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ê¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¤µ¤é¤Ë¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3212 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3213 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3214 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3217 minput_get_description (MSymbol language, MSymbol name)
3219 MPlist *plist = load_im_info (language, name, M_description);
3225 if (! MPLIST_PLIST_P (plist))
3227 M17N_OBJECT_UNREF (plist);
3230 pl = MPLIST_PLIST (plist);
3231 while (! MPLIST_TAIL_P (pl) && ! MPLIST_MTEXT_P (pl))
3232 pl = MPLIST_NEXT (pl);
3233 if (MPLIST_MTEXT_P (pl))
3234 mt = get_description_advance (pl);
3235 M17N_OBJECT_UNREF (plist);
3240 @brief Get information about input method commands.
3242 The minput_get_commands () function returns information about
3243 input method commands of the input method specified by $LANGUAGE
3244 and $NAME. An input method command is a pseudo key event to which
3245 one or more actual input key sequences are assigned.
3247 There are two kinds of commands, global and local. Global
3248 commands are used by multiple input methods for the same purpose,
3249 and have global key assignments. Local commands are used only in
3250 a specific input method, and have only local key assignments.
3252 Each input method may locally change key assignments for global
3253 commands. A global key assignment for a global command are
3254 effective only when the current input method does not have local
3255 key assignments for that command.
3257 If $NAME is #Mnil, information about global commands is returned.
3258 In this case $LANGUAGE is ignored.
3260 If $NAME is not #Mnil, information about those commands that have
3261 local key assignments in the input method specified by $LANGUAGE
3262 and $NAME is returned.
3265 If no input method commands are found, this function returns @c NULL.
3267 Otherwise, a pointer to a plist is returned. The key of each
3268 element in the plist is a symbol representing a command, and the
3269 value is a plist of the form COMMAND-INFO described below.
3271 The first element of COMMAND-INFO has the key #Mtext, and the
3272 value is an M-text describing the command briefly. This M-text
3273 may have a text property whose key is #Mdetail_text and whose
3274 value is an M-text describing the command in more detail.
3276 If there are no more elements, that means no key sequences are
3277 assigned to the command. Otherwise, each of the remaining
3278 elements has the key #Mplist, and the value is a plist whose keys are
3279 #Msymbol and values are symbols representing input keys, which are
3280 currently assigned to the command.
3282 As the returned plist is kept in the library, the caller must not
3283 modify nor free it. */
3285 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3287 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3288 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3289 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3291 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£
3292 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ÇÍѤ¤¤é¤ì¤ë¡£
3293 ¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3295 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
3296 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ß͸ú¤Ç¤¢¤ë¡£
3298 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3299 ¤³¤Î¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3301 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME
3302 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3305 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3307 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3308 ¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î
3309 COMMAND-INFO ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3311 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext
3312 ¤ò¡¢ÃͤȤ·¤Æ¤½¤Î¥³¥Þ¥ó¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤ò»ý¤Ä¡£¤³¤Î M-text
3314 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤Î¥³¥Þ¥ó¥É¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3317 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
3318 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ#Mplist
3319 ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£
3320 ¤³¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol
3321 ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3323 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3326 minput_get_commands (MSymbol language, MSymbol name)
3328 MPlist *plist = get_command_list (language, name);
3330 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3334 @brief Assign a key sequence to an input method command.
3336 The minput_assign_command_keys () function assigns input key
3337 sequence $KEYSEQ to input method command $COMMAND for the input
3338 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3339 key sequence is assigned globally no matter what $LANGUAGE is.
3340 Otherwise the key sequence is assigned locally.
3342 Each element of $KEYSEQ must have the key $Msymbol and the value
3343 must be a symbol representing an input key.
3345 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3346 globally or locally.
3348 This assignment gets effective in a newly opened input method.
3351 If the operation was successful, 0 is returned. Otherwise -1 is
3352 returned, and #merror_code is set to #MERROR_IM. */
3354 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3356 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3357 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND
3358 ¤ËÂФ·¤Æ¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil
3359 ¤Ê¤é¤Ð¡¢$LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
3360 ¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3362 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol
3363 ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3365 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£
3366 ¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3368 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤Ë¤Ê¤ë¡£
3371 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3372 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3375 minput_assign_command_keys (MSymbol language, MSymbol name,
3376 MSymbol command, MPlist *keyseq)
3378 MPlist *plist, *pl, *p;
3380 if (check_command_keyseq (keyseq) < 0
3381 || ! (plist = get_command_list (language, name)))
3382 MERROR (MERROR_IM, -1);
3383 pl = mplist_get (plist, command);
3386 pl = MPLIST_NEXT (pl);
3388 while ((p = mplist_pop (pl)))
3389 M17N_OBJECT_UNREF (p);
3392 keyseq = mplist_copy (keyseq);
3393 mplist_push (pl, Mplist, keyseq);
3394 M17N_OBJECT_UNREF (keyseq);
3400 MERROR (MERROR_IM, -1);
3403 pl = get_command_list (Mnil, Mnil); /* Get global commands. */
3404 pl = mplist_get (pl, command);
3406 MERROR (MERROR_IM, -1);
3408 mplist_add (p, Mtext, mplist_value (pl));
3409 keyseq = mplist_copy (keyseq);
3410 mplist_add (p, Mplist, keyseq);
3411 M17N_OBJECT_UNREF (keyseq);
3412 mplist_push (plist, command, p);
3418 @brief Get a list of variables of an input method.
3420 The minput_get_variables () function returns a plist (#MPlist) of
3421 variables used to control the behavior of the input method
3422 specified by $LANGUAGE and $NAME. The key of an element of the
3423 plist is a symbol representing a variable, and the value is a
3424 plist of the form VAR-INFO (described below) that carries the
3425 information about the variable.
3427 The first element of VAR-INFO has the key #Mtext, and the value is
3428 an M-text describing the variable briefly. This M-text may have a
3429 text property #Mdetail_text whose value is an M-text describing
3430 the variable in more detail.
3432 The second element of VAR-INFO is for the value of the variable.
3433 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3434 integer, a symbol, or an M-text, respectively. The variable is
3435 set to this value when an input context is created for the input
3438 If there are no more elements, the variable can take any value
3439 that matches with the above type. Otherwise, the remaining
3440 elements of VAR-INFO are to specify valid values of the variable.
3442 If the type of the variable is integer, the following elements
3443 have the key #Minteger or #Mplist. If it is #Minteger, the value
3444 is a valid integer value. If it is #Mplist, the value is a plist
3445 of two of elements. Both of them have the key #Minteger, and
3446 values are the minimum and maximum bounds of the valid value
3449 If the type of the variable is symbol or M-text, the following
3450 elements of the plist have the key #Msymbol or #Mtext,
3451 respectively, and the value must be a valid one.
3453 For instance, suppose an input method has the variables:
3455 @li name:intvar, description: "value is an integer",
3456 initial value:0, value-range:0..3,10,20
3458 @li name:symvar, description: "value is a symbol",
3459 initial value:nil, value-range:a, b, c, nil
3461 @li name:txtvar, description: "value is an M-text",
3462 initial value:empty text, no value-range (i.e. any text)
3464 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3465 a value, and '(...)' means a plist):
3468 plist:(intvar:(mtext:'value is an integer'
3470 plist:(integer:0 integer:3)
3473 symvar:(mtext:"value is a symbol"
3479 txtvar:(mtext:"value is an M-text"
3484 If the input method uses any variables, a pointer to #MPlist is
3485 returned. As the plist is kept in the library, a caller must not
3486 modify nor free it. If the input method does not use any
3487 variable, @c NULL is returned. */
3489 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3491 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3492 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3493 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3494 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3495 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3497 VAR-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext ¤ò¡¢ÃͤȤ·¤Æ¤½¤ÎÊÑ¿ô¤ò´Êñ¤ËÀâÌÀ¤¹¤ë
3498 M-text ¤ò»ý¤Ä¡£¤³¤Î M-text ¤Ï¡¢#Mdetail_text
3499 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤ÎÊÑ¿ô¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3502 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3503 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3504 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3506 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3507 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3509 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3510 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3511 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3512 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3514 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3515 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3517 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3519 @li name:intvar, ÀâÌÀ:"value is an integer",
3520 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3522 @li name:symvar, ÀâÌÀ:"value is a symbol",
3523 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3525 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3526 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3528 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3529 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3532 plist:(intvar:(mtext:"value is an integer"
3534 plist:(integer:0 integer:3)
3537 symvar:(mtext:"value is a symbol"
3543 txtvar:(mtext:"value is an M-text"
3548 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3549 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3550 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3553 minput_get_variables (MSymbol language, MSymbol name)
3555 MPlist *plist = get_variable_list (language, name);
3557 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3561 @brief Set the initial value of an input method variable.
3563 The minput_set_variable () function sets the initial value of
3564 input method variable $VARIABLE to $VALUE for the input method
3565 specified by $LANGUAGE and $NAME.
3567 By default, the initial value is 0.
3569 This setting gets effective in a newly opened input method.
3572 If the operation was successful, 0 is returned. Otherwise -1 is
3573 returned, and #merror_code is set to #MERROR_IM. */
3575 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3577 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3578 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3579 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3581 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3583 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3586 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3587 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3590 minput_set_variable (MSymbol language, MSymbol name,
3591 MSymbol variable, void *value)
3593 MPlist *plist, *val_element, *range_element;
3596 if (language == Mnil || name == Mnil)
3597 MERROR (MERROR_IM, -1);
3598 plist = get_variable_list (language, name);
3600 MERROR (MERROR_IM, -1);
3601 plist = (MPlist *) mplist_get (plist, variable);
3603 MERROR (MERROR_IM, -1);
3604 val_element = MPLIST_NEXT (plist);
3605 type = MPLIST_KEY (val_element);
3606 range_element = MPLIST_NEXT (val_element);
3608 if (! MPLIST_TAIL_P (range_element))
3610 if (type == Minteger)
3612 int val = (int) value, this_val;
3614 MPLIST_DO (plist, range_element)
3616 this_val = (int) MPLIST_VAL (plist);
3617 if (MPLIST_PLIST_P (plist))
3619 int min_bound, max_bound;
3620 MPlist *pl = MPLIST_PLIST (plist);
3622 min_bound = (int) MPLIST_VAL (pl);
3623 pl = MPLIST_NEXT (pl);
3624 max_bound = (int) MPLIST_VAL (pl);
3625 if (val >= min_bound && val <= max_bound)
3628 else if (val == this_val)
3631 if (MPLIST_TAIL_P (plist))
3632 MERROR (MERROR_IM, -1);
3634 else if (type == Msymbol)
3636 MPLIST_DO (plist, range_element)
3637 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3639 if (MPLIST_TAIL_P (plist))
3640 MERROR (MERROR_IM, -1);
3642 else /* type == Mtext */
3644 MPLIST_DO (plist, range_element)
3645 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3647 if (MPLIST_TAIL_P (plist))
3648 MERROR (MERROR_IM, -1);
3649 M17N_OBJECT_REF (value);
3653 mplist_set (val_element, type, value);
3659 /*** @addtogroup m17nDebug */
3665 @brief Dump an input method.
3667 The mdebug_dump_im () function prints the input method $IM in a
3668 human readable way to the stderr. $INDENT specifies how many
3669 columns to indent the lines but the first one.
3672 This function returns $IM. */
3674 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3676 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3677 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3680 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3683 mdebug_dump_im (MInputMethod *im, int indent)
3685 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3688 prefix = (char *) alloca (indent + 1);
3689 memset (prefix, 32, indent);
3690 prefix[indent] = '\0';
3692 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3693 msymbol_name (im->name));
3694 mdebug_dump_mtext (im_info->title, 0, 0);
3695 if (im->name != Mnil)
3699 MPLIST_DO (state, im_info->states)
3701 fprintf (stderr, "\n%s ", prefix);
3702 dump_im_state (MPLIST_VAL (state), indent + 2);
3705 fprintf (stderr, ")");