1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004
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>
150 #include "m17n-gui.h"
151 #include "m17n-misc.h"
152 #include "internal.h"
157 #include "database.h"
159 static int mdebug_mask = MDEBUG_INPUT;
161 static MSymbol Minput_method;
163 /** Symbols to load an input method data. */
164 static MSymbol Mtitle, Mmacro, Mmodule, Mstate;
166 /** Symbols for actions. */
167 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
168 static MSymbol Mselect, Mshow, Mhide;
169 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
171 static MSymbol Mcandidate_list, Mcandidate_index;
173 static MSymbol Minit, Mfini;
175 /** Symbols for key events. */
176 static MSymbol one_char_symbol[256];
178 static MSymbol M_key_alias;
180 static MSymbol M_description, M_command, M_variable;
182 /** Structure to hold a map. */
186 /** List of actions to take when we reach the map. In a root map,
187 the actions are executed only when there's no more key. */
190 /** List of deeper maps. If NULL, this is a terminal map. */
193 /** List of actions to take when we leave the map successfully. In
194 a root map, the actions are executed only when none of submaps
195 handle the current key. */
196 MPlist *branch_actions;
199 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
204 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
209 /** Name of the state. */
212 /** Title of the state, or NULL. */
215 /** Key translation map of the state. Built by merging all maps of
222 marker_code (MSymbol sym)
228 name = MSYMBOL_NAME (sym);
229 return ((name[0] == '@'
230 && ((name[1] >= '0' && name[1] <= '9')
231 || name[1] == '<' || name[1] == '>'
232 || name[1] == '=' || name[1] == '+' || name[1] == '-'
233 || name[1] == '[' || name[1] == ']')
239 integer_value (MInputContext *ic, MPlist *arg)
241 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
243 MText *preedit = ic->preedit;
244 int len = mtext_nchars (preedit);
246 if (MPLIST_INTEGER_P (arg))
247 return MPLIST_INTEGER (arg);
248 code = marker_code (MPLIST_SYMBOL (arg));
250 return (int) mplist_get (ic_info->vars, MPLIST_SYMBOL (arg));
251 if (code >= '0' && code <= '9')
253 else if (code == '=')
254 code = ic->cursor_pos;
255 else if (code == '-' || code == '[')
256 code = ic->cursor_pos - 1;
257 else if (code == '+' || code == ']')
258 code = ic->cursor_pos + 1;
259 else if (code == '<')
261 else if (code == '>')
263 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
267 /* Parse PLIST as an action list while modifying the list to regularize
268 actions. PLIST should have this form:
269 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
270 Return 0 if successfully parsed, otherwise return -1. */
273 parse_action_list (MPlist *plist, MPlist *macros)
275 MPLIST_DO (plist, plist)
277 if (MPLIST_MTEXT_P (plist))
279 /* This is a short form of (insert MTEXT). */
280 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
281 MERROR (MERROR_IM, -1); */
283 else if (MPLIST_PLIST_P (plist)
284 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
285 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
289 /* This is a short form of (insert (GROUPS *)). */
290 MPLIST_DO (pl, MPLIST_PLIST (plist))
292 if (MPLIST_PLIST_P (pl))
296 MPLIST_DO (elt, MPLIST_PLIST (pl))
297 if (! MPLIST_MTEXT_P (elt)
298 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
299 MERROR (MERROR_IM, -1);
303 if (! MPLIST_MTEXT_P (pl)
304 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
305 MERROR (MERROR_IM, -1);
309 else if (MPLIST_INTEGER_P (plist))
311 int c = MPLIST_INTEGER (plist);
313 if (c < 0 || c > MCHAR_MAX)
314 MERROR (MERROR_IM, -1);
316 else if (MPLIST_PLIST_P (plist)
317 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
319 MPlist *pl = MPLIST_PLIST (plist);
320 MSymbol action_name = MPLIST_SYMBOL (pl);
322 pl = MPLIST_NEXT (pl);
324 if (action_name == Minsert)
326 if (MPLIST_MTEXT_P (pl))
328 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
329 MERROR (MERROR_IM, -1);
331 else if (MPLIST_PLIST_P (pl))
335 if (MPLIST_PLIST_P (pl))
339 MPLIST_DO (elt, MPLIST_PLIST (pl))
340 if (! MPLIST_MTEXT_P (elt)
341 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
342 MERROR (MERROR_IM, -1);
346 if (! MPLIST_MTEXT_P (pl)
347 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
348 MERROR (MERROR_IM, -1);
352 else if (! MPLIST_SYMBOL_P (pl))
353 MERROR (MERROR_IM, -1);
355 else if (action_name == Mselect
356 || action_name == Mdelete
357 || action_name == Mmove)
359 if (! MPLIST_SYMBOL_P (pl)
360 && ! MPLIST_INTEGER_P (pl))
361 MERROR (MERROR_IM, -1);
363 else if (action_name == Mmark
364 || action_name == Mcall
365 || action_name == Mshift)
367 if (! MPLIST_SYMBOL_P (pl))
368 MERROR (MERROR_IM, -1);
370 else if (action_name == Mshow || action_name == Mhide
371 || action_name == Mundo)
373 if (! MPLIST_TAIL_P (pl))
374 MERROR (MERROR_IM, -1);
376 else if (action_name == Mpushback)
378 if (! MPLIST_INTEGER_P (pl))
379 MERROR (MERROR_IM, -1);
381 else if (action_name == Mset || action_name == Madd
382 || action_name == Msub || action_name == Mmul
383 || action_name == Mdiv)
385 if (! (MPLIST_SYMBOL_P (pl)
386 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
387 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
388 MERROR (MERROR_IM, -1);
390 else if (action_name == Mequal || action_name == Mless
391 || action_name == Mgreater)
393 if (! ((MPLIST_INTEGER_P (pl) || MPLIST_SYMBOL_P (pl))
394 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
395 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
396 MERROR (MERROR_IM, -1);
397 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
398 if (! MPLIST_PLIST_P (pl))
399 MERROR (MERROR_IM, -1);
400 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
401 MERROR (MERROR_IM, -1);
402 pl = MPLIST_NEXT (pl);
403 if (MPLIST_PLIST_P (pl)
404 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
405 MERROR (MERROR_IM, -1);
407 else if (! macros || ! mplist_get (macros, action_name))
408 MERROR (MERROR_IM, -1);
411 MERROR (MERROR_IM, -1);
418 /* Load a translation into MAP from PLIST.
420 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
423 load_translation (MIMMap *map, MPlist *plist, MPlist *branch_actions,
429 if (MPLIST_MTEXT_P (plist))
431 MText *mt = MPLIST_MTEXT (plist);
433 len = mtext_nchars (mt);
434 if (len == 0 || len != mtext_nbytes (mt))
435 MERROR (MERROR_IM, -1);
436 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
437 for (i = 0; i < len; i++)
438 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
440 else if (MPLIST_PLIST_P (plist))
442 MPlist *elt = MPLIST_PLIST (plist);
444 len = MPLIST_LENGTH (elt);
446 MERROR (MERROR_IM, -1);
447 keyseq = (MSymbol *) alloca (sizeof (int) * len);
448 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
450 if (MPLIST_INTEGER_P (elt))
452 int c = MPLIST_INTEGER (elt);
454 if (c < 0 || c >= 0x100)
455 MERROR (MERROR_IM, -1);
456 keyseq[i] = one_char_symbol[c];
458 else if (MPLIST_SYMBOL_P (elt))
459 keyseq[i] = MPLIST_SYMBOL (elt);
461 MERROR (MERROR_IM, -1);
465 MERROR (MERROR_IM, -1);
467 for (i = 0; i < len; i++)
469 MIMMap *deeper = NULL;
472 deeper = mplist_get (map->submaps, keyseq[i]);
474 map->submaps = mplist ();
477 /* Fixme: It is better to make all deeper maps at once. */
478 MSTRUCT_CALLOC (deeper, MERROR_IM);
479 mplist_put (map->submaps, keyseq[i], deeper);
484 /* We reach a terminal map. */
486 || map->branch_actions)
487 /* This map is already defined. We avoid overriding it. */
490 plist = MPLIST_NEXT (plist);
491 if (! MPLIST_TAIL_P (plist))
493 if (parse_action_list (plist, macros) < 0)
494 MERROR (MERROR_IM, -1);
495 map->map_actions = plist;
496 M17N_OBJECT_REF (plist);
500 map->branch_actions = branch_actions;
501 M17N_OBJECT_REF (branch_actions);
507 /* Load a branch from PLIST into MAP. PLIST has this form:
508 PLIST ::= ( MAP-NAME BRANCH-ACTION * )
509 MAPS is a plist of raw maps.
510 STATE is the current state. */
513 load_branch (MPlist *plist, MPlist *maps, MIMMap *map, MPlist *macros)
516 MPlist *branch_actions;
518 if (! MPLIST_SYMBOL_P (plist))
519 MERROR (MERROR_IM, -1);
520 map_name = MPLIST_SYMBOL (plist);
521 plist = MPLIST_NEXT (plist);
522 if (MPLIST_TAIL_P (plist))
523 branch_actions = NULL;
524 else if (parse_action_list (plist, macros) < 0)
525 MERROR (MERROR_IM, -1);
527 branch_actions = plist;
528 if (map_name == Mnil)
530 map->branch_actions = branch_actions;
532 M17N_OBJECT_REF (branch_actions);
534 else if (map_name == Mt)
536 map->map_actions = branch_actions;
538 M17N_OBJECT_REF (branch_actions);
542 plist = (MPlist *) mplist_get (maps, map_name);
543 if (! plist || ! MPLIST_PLIST_P (plist))
544 MERROR (MERROR_IM, -1);
545 MPLIST_DO (plist, plist)
546 if (! MPLIST_PLIST_P (plist)
547 || (load_translation (map, MPLIST_PLIST (plist), branch_actions,
550 MERROR (MERROR_IM, -1);
556 /* Load a macro from PLIST into MACROS.
558 PLIST ::= ( MACRO-NAME ACTION * )
559 MACROS is a plist of macro names vs action list. */
561 load_macros (MPlist *plist, MPlist *macros)
565 if (! MPLIST_SYMBOL_P (plist))
566 MERROR (MERROR_IM, -1);
567 name = MPLIST_SYMBOL (plist);
568 plist = MPLIST_NEXT (plist);
569 if (MPLIST_TAIL_P (plist)
570 || parse_action_list (plist, macros) < 0)
571 MERROR (MERROR_IM, -1);
572 mplist_put (macros, name, plist);
573 M17N_OBJECT_REF (plist);
577 /* Load an external module from PLIST into EXTERNALS.
579 PLIST ::= ( MODULE-NAME FUNCTION * )
580 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
582 #ifndef DLOPEN_SHLIB_EXT
583 #define DLOPEN_SHLIB_EXT ".so"
587 load_external_module (MPlist *plist, MPlist *externals)
592 MIMExternalModule *external;
596 if (MPLIST_MTEXT_P (plist))
597 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
598 else if (MPLIST_SYMBOL_P (plist))
599 module = MPLIST_SYMBOL (plist);
600 module_file = alloca (strlen (MSYMBOL_NAME (module))
601 + strlen (DLOPEN_SHLIB_EXT) + 1);
602 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
604 handle = dlopen (module_file, RTLD_NOW);
607 fprintf (stderr, "%s\n", dlerror ());
608 MERROR (MERROR_IM, -1);
610 func_list = mplist ();
611 MPLIST_DO (plist, MPLIST_NEXT (plist))
613 if (! MPLIST_SYMBOL_P (plist))
614 MERROR_GOTO (MERROR_IM, err_label);
615 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
617 MERROR_GOTO (MERROR_IM, err_label);
618 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
621 MSTRUCT_MALLOC (external, MERROR_IM);
622 external->handle = handle;
623 external->func_list = func_list;
624 mplist_add (externals, module, external);
629 M17N_OBJECT_UNREF (func_list);
634 /** Load a state from PLIST into a newly allocated state object.
636 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
637 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
638 MAPS is a plist of defined maps.
639 Return the state object. */
642 load_state (MPlist *plist, MPlist *maps, MSymbol language, MPlist *macros)
646 MSTRUCT_CALLOC (state, MERROR_IM);
647 if (! MPLIST_SYMBOL_P (plist))
648 MERROR (MERROR_IM, NULL);
649 state->name = MPLIST_SYMBOL (plist);
650 plist = MPLIST_NEXT (plist);
651 if (MPLIST_MTEXT_P (plist))
653 state->title = MPLIST_MTEXT (plist);
654 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
655 Mlanguage, language);
656 M17N_OBJECT_REF (state->title);
657 plist = MPLIST_NEXT (plist);
659 MSTRUCT_CALLOC (state->map, MERROR_IM);
660 MPLIST_DO (plist, plist)
661 if (! MPLIST_PLIST_P (plist)
662 || load_branch (MPLIST_PLIST (plist), maps, state->map, macros) < 0)
663 MERROR (MERROR_IM, NULL);
669 free_map (MIMMap *map)
673 M17N_OBJECT_UNREF (map->map_actions);
676 MPLIST_DO (plist, map->submaps)
677 free_map ((MIMMap *) MPLIST_VAL (plist));
678 M17N_OBJECT_UNREF (map->submaps);
680 M17N_OBJECT_UNREF (map->branch_actions);
684 /* Load an input method from PLIST into IM_INTO, and return it. */
687 load_input_method (MSymbol language, MSymbol name, MPlist *plist,
688 MInputMethodInfo *im_info)
692 MPlist *states = NULL;
693 MPlist *externals = NULL;
694 MPlist *macros = NULL;
697 for (; MPLIST_PLIST_P (plist); plist = MPLIST_NEXT (plist))
699 elt = MPLIST_PLIST (plist);
700 if (! MPLIST_SYMBOL_P (elt))
701 MERROR_GOTO (MERROR_IM, err);
702 if (MPLIST_SYMBOL (elt) == Mtitle)
704 elt = MPLIST_NEXT (elt);
705 if (MPLIST_MTEXT_P (elt))
707 title = MPLIST_MTEXT (elt);
708 M17N_OBJECT_REF (title);
711 MERROR_GOTO (MERROR_IM, err);
713 else if (MPLIST_SYMBOL (elt) == Mmap)
715 maps = mplist__from_alist (MPLIST_NEXT (elt));
717 MERROR_GOTO (MERROR_IM, err);
719 else if (MPLIST_SYMBOL (elt) == Mmacro)
722 MPLIST_DO (elt, MPLIST_NEXT (elt))
724 if (! MPLIST_PLIST_P (elt)
725 || load_macros (MPLIST_PLIST (elt), macros) < 0)
726 MERROR_GOTO (MERROR_IM, err);
729 else if (MPLIST_SYMBOL (elt) == Mmodule)
731 externals = mplist ();
732 MPLIST_DO (elt, MPLIST_NEXT (elt))
734 if (! MPLIST_PLIST_P (elt)
735 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
736 MERROR_GOTO (MERROR_IM, err);
739 else if (MPLIST_SYMBOL (elt) == Mstate)
742 MPLIST_DO (elt, MPLIST_NEXT (elt))
746 if (! MPLIST_PLIST_P (elt))
747 MERROR_GOTO (MERROR_IM, err);
748 state = load_state (MPLIST_PLIST (elt), maps, language, macros);
750 MERROR_GOTO (MERROR_IM, err);
751 mplist_put (states, state->name, state);
758 MPLIST_DO (elt, maps)
759 M17N_OBJECT_UNREF (MPLIST_VAL (elt));
760 M17N_OBJECT_UNREF (maps);
763 title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
764 MTEXT_FORMAT_US_ASCII);
765 im_info->title = title;
766 im_info->externals = externals;
767 im_info->macros = macros;
768 im_info->states = states;
774 MPLIST_DO (elt, maps)
775 M17N_OBJECT_UNREF (MPLIST_VAL (elt));
776 M17N_OBJECT_UNREF (maps);
779 M17N_OBJECT_UNREF (title);
782 MPLIST_DO (plist, states)
784 MIMState *state = (MIMState *) MPLIST_VAL (plist);
787 M17N_OBJECT_UNREF (state->title);
789 free_map (state->map);
792 M17N_OBJECT_UNREF (states);
796 MPLIST_DO (plist, externals)
798 MIMExternalModule *external = MPLIST_VAL (plist);
800 dlclose (external->handle);
801 M17N_OBJECT_UNREF (external->func_list);
803 MPLIST_KEY (plist) = Mt;
805 M17N_OBJECT_UNREF (externals);
812 static int take_action_list (MInputContext *ic, MPlist *action_list);
815 shift_state (MInputContext *ic, MSymbol state_name)
817 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
818 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
821 /* Find a state to shift to. If not found, shift to the initial
823 state = (MIMState *) mplist_get (im_info->states, state_name);
825 state = (MIMState *) MPLIST_VAL (im_info->states);
827 MDEBUG_PRINT1 ("\n[IM] state-shift (%s)", MSYMBOL_NAME (state->name));
829 /* Enter the new state. */
830 ic_info->state = state;
831 ic_info->map = state->map;
832 ic_info->state_key_head = ic_info->key_head;
833 if (state == (MIMState *) MPLIST_VAL (im_info->states))
835 /* We have shifted to the initial state. */
838 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
839 Mcandidate_list, NULL, 0);
840 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
841 Mcandidate_index, NULL, 0);
842 mtext_cat (ic->produced, ic->preedit);
843 if ((mdebug__flag & mdebug_mask)
844 && mtext_nchars (ic->produced) > 0)
848 MDEBUG_PRINT (" (produced");
849 for (i = 0; i < mtext_nchars (ic->produced); i++)
850 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
853 mtext_reset (ic->preedit);
854 ic->candidate_list = NULL;
855 ic->candidate_show = 0;
856 ic->preedit_changed = ic->candidates_changed = 1;
857 MPLIST_DO (p, ic_info->markers)
859 MPLIST_DO (p, ic_info->vars)
862 memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
863 sizeof (int) * (ic_info->used - ic_info->state_key_head));
864 ic_info->used -= ic_info->state_key_head;
865 ic_info->state_key_head = ic_info->key_head = 0;
867 mtext_cpy (ic_info->preedit_saved, ic->preedit);
868 ic_info->state_pos = ic->cursor_pos;
869 ic->status = state->title;
871 ic->status = im_info->title;
872 ic->status_changed = 1;
873 if (ic_info->key_head == ic_info->used
874 && ic_info->map == ic_info->state->map
875 && ic_info->map->map_actions)
877 MDEBUG_PRINT (" init-actions:");
878 take_action_list (ic, ic_info->map->map_actions);
882 /* Find a candidate group that contains a candidate number INDEX from
883 PLIST. Set START_INDEX to the first candidate number of the group,
884 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
885 candidate group number if they are non-NULL. If INDEX is -1, find
886 the last candidate group. */
889 find_candidates_group (MPlist *plist, int index,
890 int *start_index, int *end_index, int *group_index)
892 int i = 0, gidx = 0, len;
894 MPLIST_DO (plist, plist)
896 if (MPLIST_MTEXT_P (plist))
897 len = mtext_nchars (MPLIST_MTEXT (plist));
899 len = mplist_length (MPLIST_PLIST (plist));
900 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
906 *end_index = i + len;
918 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
920 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
922 int nchars = mt ? mtext_nchars (mt) : 1;
925 mtext_ins (ic->preedit, pos, mt);
927 mtext_ins_char (ic->preedit, pos, c, 1);
928 MPLIST_DO (markers, ic_info->markers)
929 if (MPLIST_INTEGER (markers) > pos)
930 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
931 if (ic->cursor_pos >= pos)
932 ic->cursor_pos += nchars;
933 ic->preedit_changed = 1;
938 preedit_delete (MInputContext *ic, int from, int to)
940 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
943 mtext_del (ic->preedit, from, to);
944 MPLIST_DO (markers, ic_info->markers)
946 if (MPLIST_INTEGER (markers) > to)
948 = (void *) (MPLIST_INTEGER (markers) - (to - from));
949 else if (MPLIST_INTEGER (markers) > from);
950 MPLIST_VAL (markers) = (void *) from;
952 if (ic->cursor_pos >= to)
953 ic->cursor_pos -= to - from;
954 else if (ic->cursor_pos > from)
955 ic->cursor_pos = from;
956 ic->preedit_changed = 1;
961 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
963 int code = marker_code (sym);
965 if (mt && (code == '[' || code == ']'))
969 if (code == '[' && current > 0)
971 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
975 else if (code == ']' && current < mtext_nchars (mt))
977 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
983 return (code == '<' ? 0
984 : code == '>' ? limit
985 : code == '-' ? current - 1
986 : code == '+' ? current + 1
987 : code == '=' ? current
988 : code - '0' > limit ? limit
992 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
996 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
998 int from = mtext_property_start (prop);
999 int to = mtext_property_end (prop);
1001 MPlist *candidate_list = mtext_property_value (prop);
1002 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1004 int ingroup_index = idx - start;
1007 preedit_delete (ic, from, to);
1008 if (MPLIST_MTEXT_P (group))
1010 mt = MPLIST_MTEXT (group);
1011 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1019 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1020 i++, plist = MPLIST_NEXT (plist));
1021 mt = MPLIST_MTEXT (plist);
1022 preedit_insert (ic, from, mt, 0);
1023 to = from + mtext_nchars (mt);
1025 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1026 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1027 ic->cursor_pos = to;
1032 take_action_list (MInputContext *ic, MPlist *action_list)
1034 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1035 MPlist *candidate_list = ic->candidate_list;
1036 int candidate_index = ic->candidate_index;
1037 int candidate_show = ic->candidate_show;
1038 MTextProperty *prop;
1040 MPLIST_DO (action_list, action_list)
1046 if (MPLIST_MTEXT_P (action_list)
1047 || MPLIST_INTEGER_P (action_list))
1048 name = Minsert, args = action_list;
1049 else if (MPLIST_PLIST_P (action_list)
1050 && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list))
1051 || MPLIST_PLIST_P (MPLIST_PLIST (action_list))))
1052 name = Minsert, args = action_list;
1055 action = MPLIST_PLIST (action_list);
1056 name = MPLIST_SYMBOL (action);
1057 args = MPLIST_NEXT (action);
1060 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1061 if (name == Minsert)
1063 if (MPLIST_MTEXT_P (args))
1064 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1065 else if (MPLIST_INTEGER_P (args))
1066 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1067 else if (MPLIST_SYMBOL_P (args))
1069 int c = integer_value (ic, args);
1071 if (c >= 0 && c <= MCHAR_MAX)
1072 preedit_insert (ic, ic->cursor_pos, NULL, c);
1079 args = MPLIST_PLIST (args);
1080 if (MPLIST_MTEXT_P (args))
1082 preedit_insert (ic, ic->cursor_pos, NULL,
1083 mtext_ref_char (MPLIST_MTEXT (args), 0));
1088 mt = MPLIST_MTEXT (MPLIST_PLIST (args));
1089 preedit_insert (ic, ic->cursor_pos, mt, 0);
1090 len = mtext_nchars (mt);
1092 mtext_put_prop (ic->preedit,
1093 ic->cursor_pos - len, ic->cursor_pos,
1094 Mcandidate_list, args);
1095 mtext_put_prop (ic->preedit,
1096 ic->cursor_pos - len, ic->cursor_pos,
1097 Mcandidate_index, (void *) 0);
1100 else if (name == Mselect)
1103 int code, idx, gindex;
1104 int pos = ic->cursor_pos;
1108 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1111 if (MPLIST_SYMBOL_P (args))
1113 code = marker_code (MPLIST_SYMBOL (args));
1119 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1120 group = find_candidates_group (mtext_property_value (prop), idx,
1121 &start, &end, &gindex);
1123 if (code != '[' && code != ']')
1127 ? new_index (NULL, ic->candidate_index - start,
1128 end - start - 1, MPLIST_SYMBOL (args),
1130 : MPLIST_INTEGER (args)));
1133 find_candidates_group (mtext_property_value (prop), -1,
1138 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1143 int ingroup_index = idx - start;
1146 group = mtext_property_value (prop);
1147 len = mplist_length (group);
1160 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1161 idx += (MPLIST_MTEXT_P (group)
1162 ? mtext_nchars (MPLIST_MTEXT (group))
1163 : mplist_length (MPLIST_PLIST (group)));
1164 len = (MPLIST_MTEXT_P (group)
1165 ? mtext_nchars (MPLIST_MTEXT (group))
1166 : mplist_length (MPLIST_PLIST (group)));
1167 if (ingroup_index >= len)
1168 ingroup_index = len - 1;
1169 idx += ingroup_index;
1171 update_candidate (ic, prop, idx);
1173 else if (name == Mshow)
1174 ic->candidate_show = 1;
1175 else if (name == Mhide)
1176 ic->candidate_show = 0;
1177 else if (name == Mdelete)
1179 int len = mtext_nchars (ic->preedit);
1180 int to = (MPLIST_SYMBOL_P (args)
1181 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1183 : MPLIST_INTEGER (args));
1189 if (to < ic->cursor_pos)
1190 preedit_delete (ic, to, ic->cursor_pos);
1191 else if (to > ic->cursor_pos)
1192 preedit_delete (ic, ic->cursor_pos, to);
1194 else if (name == Mmove)
1196 int len = mtext_nchars (ic->preedit);
1198 = (MPLIST_SYMBOL_P (args)
1199 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1201 : MPLIST_INTEGER (args));
1207 if (pos != ic->cursor_pos)
1209 ic->cursor_pos = pos;
1210 ic->preedit_changed = 1;
1213 else if (name == Mmark)
1215 int code = marker_code (MPLIST_SYMBOL (args));
1218 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1219 (void *) ic->cursor_pos);
1221 else if (name == Mpushback)
1223 int num = MPLIST_INTEGER (args);
1226 ic_info->key_head -= num;
1228 ic_info->key_head = num;
1229 if (ic_info->key_head > ic_info->used)
1230 ic_info->key_head = ic_info->used;
1232 else if (name == Mcall)
1234 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1235 MIMExternalFunc func = NULL;
1236 MSymbol module, func_name;
1237 MPlist *func_args, *val;
1240 module = MPLIST_SYMBOL (args);
1241 args = MPLIST_NEXT (args);
1242 func_name = MPLIST_SYMBOL (args);
1244 if (im_info->externals)
1246 MIMExternalModule *external
1247 = (MIMExternalModule *) mplist_get (im_info->externals,
1250 func = (MIMExternalFunc) mplist_get (external->func_list,
1255 func_args = mplist ();
1256 mplist_add (func_args, Mt, ic);
1257 MPLIST_DO (args, MPLIST_NEXT (args))
1261 if (MPLIST_KEY (args) == Msymbol
1262 && MPLIST_KEY (args) != Mnil
1263 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1265 code = new_index (ic, ic->cursor_pos,
1266 mtext_nchars (ic->preedit),
1267 MPLIST_SYMBOL (args), ic->preedit);
1268 mplist_add (func_args, Minteger, (void *) code);
1271 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1273 val = (func) (func_args);
1274 M17N_OBJECT_UNREF (func_args);
1275 if (val && ! MPLIST_TAIL_P (val))
1276 ret = take_action_list (ic, val);
1277 M17N_OBJECT_UNREF (val);
1281 else if (name == Mshift)
1283 shift_state (ic, MPLIST_SYMBOL (args));
1285 else if (name == Mundo)
1287 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1290 mtext_reset (ic->preedit);
1291 mtext_reset (ic_info->preedit_saved);
1292 ic->cursor_pos = ic_info->state_pos = 0;
1293 ic_info->state_key_head = ic_info->key_head = 0;
1295 if (ic_info->used < 0)
1300 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1305 else if (name == Mset || name == Madd || name == Msub
1306 || name == Mmul || name == Mdiv)
1308 MSymbol sym = MPLIST_SYMBOL (args);
1309 int val1 = (int) mplist_get (ic_info->vars, sym), val2;
1311 args = MPLIST_NEXT (args);
1312 val2 = integer_value (ic, args);
1315 else if (name == Madd)
1317 else if (name == Msub)
1319 else if (name == Mmul)
1323 mplist_put (ic_info->vars, sym, (void *) val1);
1324 MDEBUG_PRINT2 ("(%s=%d)", MSYMBOL_NAME (sym), val1);
1326 else if (name == Mequal || name == Mless || name == Mgreater)
1329 MPlist *actions1, *actions2;
1332 val1 = integer_value (ic, args);
1333 args = MPLIST_NEXT (args);
1334 val2 = integer_value (ic, args);
1335 args = MPLIST_NEXT (args);
1336 actions1 = MPLIST_PLIST (args);
1337 args = MPLIST_NEXT (args);
1338 if (MPLIST_TAIL_P (args))
1341 actions2 = MPLIST_PLIST (args);
1342 if (name == Mequal ? val1 == val2
1343 : name == Mless ? val1 < val2
1345 ret = take_action_list (ic, actions1);
1347 ret = take_action_list (ic, actions2);
1353 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1357 && (actions = mplist_get (im_info->macros, name)))
1359 if (take_action_list (ic, actions) < 0)
1366 ic->candidate_list = NULL;
1367 if (ic->cursor_pos > 0
1368 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
1371 ic->candidate_list = mtext_property_value (prop);
1373 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
1375 ic->candidate_from = mtext_property_start (prop);
1376 ic->candidate_to = mtext_property_end (prop);
1379 ic->candidates_changed |= (candidate_list != ic->candidate_list
1380 || candidate_index != ic->candidate_index
1381 || candidate_show != ic->candidate_show);
1386 /* Handle the input key KEY in the current state and map specified in
1387 the input context IC. If KEY is handled correctly, return 0.
1388 Otherwise, return -1. */
1391 handle_key (MInputContext *ic)
1393 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1394 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1395 MIMMap *map = ic_info->map;
1396 MIMMap *submap = NULL;
1397 MSymbol key = ic_info->keys[ic_info->key_head];
1400 MDEBUG_PRINT2 ("[IM] handle `%s' in state %s",
1401 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
1405 submap = mplist_get (map->submaps, key);
1406 if (! submap && (key = msymbol_get (key, M_key_alias)) != Mnil)
1407 submap = mplist_get (map->submaps, key);
1412 MDEBUG_PRINT (" submap-found");
1413 mtext_cpy (ic->preedit, ic_info->preedit_saved);
1414 ic->cursor_pos = ic_info->state_pos;
1415 ic_info->key_head++;
1416 ic_info->map = map = submap;
1417 if (map->map_actions)
1419 MDEBUG_PRINT (" map-actions:");
1420 if (take_action_list (ic, map->map_actions) < 0)
1423 else if (map->submaps)
1425 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
1427 MSymbol key = ic_info->keys[i];
1428 char *name = msymbol_name (key);
1430 if (! name[0] || ! name[1])
1431 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
1433 ic->preedit_changed = 1;
1436 /* If this is the terminal map or we have shifted to another
1437 state, perform branch actions (if any). */
1438 if (! map->submaps || map != ic_info->map)
1440 if (map->branch_actions)
1442 MDEBUG_PRINT (" branch-actions:");
1443 if (take_action_list (ic, map->branch_actions) < 0)
1446 /* If MAP is still not the root map, shift to the current
1448 if (ic_info->map != ic_info->state->map)
1449 shift_state (ic, ic_info->state->name);
1451 MDEBUG_PRINT ("\n");
1455 /* MAP can not handle KEY. */
1457 /* If MAP is the root map of the initial state, it means that
1458 the current input method can not handle KEY. */
1459 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
1461 MDEBUG_PRINT (" unhandled\n");
1465 if (map != ic_info->state->map)
1467 /* If MAP is not the root map... */
1468 /* If MAP has branch actions, perform them. */
1469 if (map->branch_actions)
1471 MDEBUG_PRINT (" branch-actions:");
1472 take_action_list (ic, map->branch_actions);
1474 /* If MAP is still not the root map, shift to the current
1476 if (ic_info->map != ic_info->state->map)
1478 shift_state (ic, ic_info->state->name);
1479 /* If MAP has branch_actions, perform them. */
1480 if (ic_info->map->branch_actions)
1482 MDEBUG_PRINT (" init-actions:");
1483 take_action_list (ic, ic_info->map->branch_actions);
1489 /* MAP is the root map, perform branch actions (if any) or
1490 shift to the initial state. */
1491 if (map->branch_actions)
1493 MDEBUG_PRINT (" branch-actions:");
1494 take_action_list (ic, map->branch_actions);
1498 ((MIMState *) MPLIST_VAL (im_info->states))->name);
1500 MDEBUG_PRINT ("\n");
1506 reset_ic (MInputContext *ic, MSymbol ignore)
1508 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1509 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1511 if (im_info->states)
1512 /* Shift to the initial state. */
1513 shift_state (ic, Mnil);
1515 ic_info->state = NULL;
1516 MLIST_RESET (ic_info);
1517 ic_info->map = ic_info->state ? ic_info->state->map : NULL;
1518 ic_info->state_key_head = ic_info->key_head = 0;
1519 ic_info->key_unhandled = 0;
1520 ic->cursor_pos = ic_info->state_pos = 0;
1521 ic->status = ic_info->state ? ic_info->state->title : NULL;
1523 ic->status = im_info->title;
1524 ic->candidate_list = NULL;
1525 ic->candidate_show = 0;
1526 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1;
1527 if (ic_info->map && ic_info->map->map_actions)
1528 take_action_list (ic, ic_info->map->map_actions);
1532 open_im (MInputMethod *im)
1535 MInputMethodInfo *im_info;
1539 mdb = mdatabase_find (Minput_method, im->language, im->name, Mnil);
1542 plist = mdatabase_load (mdb);
1544 MERROR (MERROR_IM, -1);
1545 MSTRUCT_CALLOC (im_info, MERROR_IM);
1547 result = load_input_method (im->language, im->name, plist, im_info);
1548 M17N_OBJECT_UNREF (plist);
1550 MERROR (MERROR_IM, -1);
1555 close_im (MInputMethod *im)
1557 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1561 M17N_OBJECT_UNREF (im_info->title);
1562 if (im_info->states)
1564 MPLIST_DO (plist, im_info->states)
1566 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1569 M17N_OBJECT_UNREF (state->title);
1571 free_map (state->map);
1574 M17N_OBJECT_UNREF (im_info->states);
1577 if (im_info->macros)
1579 MPLIST_DO (plist, im_info->macros)
1580 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1581 M17N_OBJECT_UNREF (im_info->macros);
1584 if (im_info->externals)
1586 MPLIST_DO (plist, im_info->externals)
1588 MIMExternalModule *external = MPLIST_VAL (plist);
1590 dlclose (external->handle);
1591 M17N_OBJECT_UNREF (external->func_list);
1593 MPLIST_KEY (plist) = Mt;
1595 M17N_OBJECT_UNREF (im_info->externals);
1603 create_ic (MInputContext *ic)
1605 MInputMethod *im = ic->im;
1606 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1607 MInputContextInfo *ic_info;
1610 ic_info = (MInputContextInfo *) ic->info;
1613 MSTRUCT_CALLOC (ic_info, MERROR_IM);
1616 MLIST_INIT1 (ic_info, keys, 8);
1617 ic_info->markers = mplist ();
1618 ic_info->vars = mplist ();
1619 ic_info->preedit_saved = mtext ();
1620 if (im_info->externals)
1622 MPlist *func_args = mplist (), *plist;
1624 mplist_add (func_args, Mt, ic);
1625 MPLIST_DO (plist, im_info->externals)
1627 MIMExternalModule *external = MPLIST_VAL (plist);
1628 MIMExternalFunc func
1629 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
1634 M17N_OBJECT_UNREF (func_args);
1636 reset_ic (ic, Mnil);
1641 destroy_ic (MInputContext *ic)
1643 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1644 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1646 if (im_info->externals)
1648 MPlist *func_args = mplist (), *plist;
1650 mplist_add (func_args, Mt, ic);
1651 MPLIST_DO (plist, im_info->externals)
1653 MIMExternalModule *external = MPLIST_VAL (plist);
1654 MIMExternalFunc func
1655 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
1660 M17N_OBJECT_UNREF (func_args);
1662 MLIST_FREE1 (ic_info, keys);
1663 M17N_OBJECT_UNREF (ic_info->preedit_saved);
1664 M17N_OBJECT_UNREF (ic_info->markers);
1665 M17N_OBJECT_UNREF (ic_info->vars);
1670 /** Handle the input key KEY in the current state and map of IC->info.
1671 If KEY is handled but no text is produced, return 0, otherwise
1677 filter (MInputContext *ic, MSymbol key, void *arg)
1679 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1680 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1683 if (! ic_info->state)
1685 ic_info->key_unhandled = 1;
1688 mtext_reset (ic->produced);
1689 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
1690 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1691 ic_info->key_unhandled = 0;
1693 if (handle_key (ic) < 0)
1695 /* KEY was not handled. Reset the status and break the
1697 reset_ic (ic, Mnil);
1698 /* This forces returning 1. */
1699 ic_info->key_unhandled = 1;
1705 reset_ic (ic, Mnil);
1706 ic_info->key_unhandled = 1;
1709 /* Break the loop if all keys were handled. */
1710 } while (ic_info->key_head < ic_info->used);
1712 /* If the current map is the root of the initial state, we should
1713 produce any preedit text in ic->produced. */
1714 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
1715 && mtext_nchars (ic->preedit) > 0)
1716 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1718 if (mtext_nchars (ic->produced) > 0)
1720 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
1723 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1724 Mlanguage, ic->im->language);
1727 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
1731 /** Return 1 if the last event or key was not handled, otherwise
1734 There is no need of looking up because ic->produced should already
1735 contain the produced text (if any).
1740 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1742 mtext_cat (mt, ic->produced);
1743 mtext_reset (ic->produced);
1744 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
1747 static MPlist *load_im_info_keys;
1750 load_im_info (MSymbol language, MSymbol name, MSymbol key)
1755 if (language == Mnil || name == Mnil)
1756 MERROR (MERROR_IM, NULL);
1758 mdb = mdatabase_find (Minput_method, language, name, Mnil);
1760 MERROR (MERROR_IM, NULL);
1761 mplist_push (load_im_info_keys, key, Mt);
1762 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
1763 mplist_pop (load_im_info_keys);
1768 /* Input method command handler. */
1770 /* List of all (global and local) commands.
1771 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
1772 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
1773 Global commands are storead as (t (t COMMAND ...)) */
1774 static MPlist *command_list;
1776 /* Check if PLIST is a valid command key sequence.
1777 PLIST must be NULL or:
1778 [ symbol:KEY | integer:KEY ] ... */
1781 check_command_keyseq (MPlist *plist)
1785 MPLIST_DO (plist, plist)
1787 if (MPLIST_SYMBOL_P (plist))
1789 else if (MPLIST_INTEGER_P (plist))
1791 int n = MPLIST_INTEGER (plist);
1795 MPLIST_KEY (plist) = Msymbol;
1796 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
1805 get_description_advance (MPlist *plist)
1810 if (! MPLIST_MTEXT_P (plist))
1812 mt = mplist_pop (plist);
1813 pos = mtext_chr (mt, '\n');
1816 MText *detail = mtext_copy (mtext (), 0, mt, pos + 1, mtext_nchars (mt));
1817 mtext_del (mt, pos, mtext_nchars (mt));
1818 mtext_put_prop (mt, 0, pos, Mdetail_text, detail);
1819 M17N_OBJECT_UNREF (detail);
1825 parse_command_list (MPlist *plist, MPlist *global_list)
1827 MPlist *val = mplist ();
1829 /* PLIST ::= (sym:CMD mtext:DESCRIPTION ? (sym:KEY ...) ...) ... */
1830 MPLIST_DO (plist, plist)
1834 MPlist *this_val, *pl, *p;
1836 if (! MPLIST_PLIST_P (plist))
1838 pl = MPLIST_PLIST (plist);
1839 if (! MPLIST_SYMBOL_P (pl))
1841 cmd = MPLIST_SYMBOL (pl);
1842 pl = MPLIST_NEXT (pl);
1843 mt = get_description_advance (pl);
1844 this_val = mplist ();
1846 if (! mt && global_list)
1848 /* Get the description from global_list. */
1849 p = mplist_get (global_list, cmd);
1850 if (p && MPLIST_MTEXT (p))
1852 mt = MPLIST_MTEXT (p);
1853 M17N_OBJECT_REF (mt);
1858 mplist_add (this_val, Mtext, mt);
1859 M17N_OBJECT_UNREF (mt);
1861 /* PL ::= (sym:KEY ...) ... */
1864 if (MPLIST_PLIST_P (pl)
1865 && check_command_keyseq (MPLIST_PLIST (pl)) >= 0)
1866 /* All the elements are valid keys. */
1867 mplist_add (this_val, Mplist, MPLIST_PLIST (pl));
1870 mplist_put (val, cmd, this_val);
1876 get_command_list (MSymbol language, MSymbol name)
1882 language = name = Mt;
1886 MDatabase *mdb = mdatabase_find (msymbol ("input"), M_command,
1889 if (mdb && (plist = mdatabase_load (mdb)))
1891 pl = parse_command_list (plist, NULL);
1892 M17N_OBJECT_UNREF (plist);
1897 mplist_add (plist, Mt, pl);
1898 command_list = mplist ();
1899 mplist_add (command_list, Mt, plist);
1902 per_lang = mplist_get (command_list, language);
1905 plist = mplist_find_by_key (per_lang, name);
1907 return (MPLIST_VAL (plist));
1911 per_lang = mplist ();
1912 mplist_add (command_list, language, per_lang);
1915 /* Now we are sure that we are loading per-im info. */
1916 /* Get the global command list. */
1917 plist = load_im_info (language, name, M_command);
1918 if (! plist || mplist_key (plist) == Mnil)
1922 mplist_add (per_lang, name, plist);
1925 pl = parse_command_list (mplist_value (plist),
1926 mplist_get ((MPlist *) mplist_get (command_list, Mt),
1928 M17N_OBJECT_UNREF (plist);
1929 mplist_put (per_lang, name, pl);
1934 /* Input method variable handler. */
1936 /* List of all variables.
1937 (LANG:(IM-NAME:(VAR ...) ...) ...) ...
1938 VAR is VAR-NAME:(mtext:DESCRIPTION TYPE:VALUE ...)) */
1940 static MPlist *variable_list;
1943 parse_variable_list (MPlist *plist)
1945 MPlist *val = mplist (), *pl, *p;
1947 /* PLIST ::= (sym:VAR mtext:DESCRIPTION TYPE:INIT-VAL ...) ... */
1948 MPLIST_DO (plist, plist)
1954 if (! MPLIST_PLIST_P (plist))
1956 pl = MPLIST_PLIST (plist);
1957 if (! MPLIST_SYMBOL_P (pl))
1959 var = MPLIST_SYMBOL (pl);
1960 pl = MPLIST_NEXT (pl);
1961 mt = get_description_advance (pl);
1962 if (! mt || MPLIST_TAIL_P (pl))
1964 this_val = mplist ();
1965 mplist_add (this_val, Mtext, mt);
1966 M17N_OBJECT_UNREF (mt);
1967 type = MPLIST_KEY (pl);
1968 mplist_add (this_val, type, MPLIST_VAL (pl));
1969 MPLIST_DO (pl, MPLIST_NEXT (pl))
1971 if (type != MPLIST_KEY (pl)
1972 && (type != Minteger || ! MPLIST_PLIST_P (pl)))
1974 if (MPLIST_PLIST_P (pl))
1976 MPLIST_DO (p, MPLIST_PLIST (pl))
1977 if (! MPLIST_INTEGER_P (p))
1979 if (! MPLIST_TAIL_P (p))
1982 mplist_add (this_val, MPLIST_KEY (pl), MPLIST_VAL (pl));
1985 mplist_put (val, var, this_val);
1992 get_variable_list (MSymbol language, MSymbol name)
1997 if (language == Mnil || name == Mnil)
1998 MERROR (MERROR_IM, NULL);
1999 if (! variable_list)
2000 variable_list = mplist ();
2001 per_lang = mplist_get (variable_list, language);
2004 plist = mplist_find_by_key (per_lang, name);
2006 return (MPLIST_VAL (plist));
2010 per_lang = mplist ();
2011 mplist_add (variable_list, language, per_lang);
2013 plist = load_im_info (language, name, M_variable);
2014 if (! plist || mplist_key (plist) == Mnil)
2018 mplist_add (per_lang, name, plist);
2021 pl = parse_variable_list (mplist_value (plist));
2022 M17N_OBJECT_UNREF (plist);
2023 mplist_put (per_lang, name, pl);
2028 input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
2030 MPlist *plist, *pl, *p;
2031 char path[PATH_MAX];
2033 /* Cancel the hook. */
2034 msymbol_put (tag0, M_database_hook, NULL);
2037 mplist_push (load_im_info_keys, M_description, Mt);
2038 MPLIST_DO (plist, mdatabase__dir_list)
2040 char *dirname = (char *) MPLIST_VAL (plist);
2042 DIR *dir = opendir (dirname);
2047 dirlen = strlen (dirname);
2048 strcpy (path, dirname);
2049 while ((dp = readdir (dir)) != NULL)
2051 /* We can't trust dp->d_nameln. */
2052 int len = strlen (dp->d_name);
2055 if (len > 4 && memcmp (dp->d_name + len - 4, ".mim", 4) == 0)
2057 strcpy (path + dirlen, dp->d_name);
2058 fp = fopen (path, "r");
2061 pl = mplist__from_file (fp, load_im_info_keys);
2065 if (MPLIST_PLIST_P (pl))
2067 p = MPLIST_PLIST (pl);
2068 p = MPLIST_NEXT (p);
2069 if (MPLIST_SYMBOL_P (p))
2071 tag1 = MPLIST_VAL (p);
2072 p = MPLIST_NEXT (p);
2073 if (MPLIST_SYMBOL_P (p))
2075 tag2 = MPLIST_VAL (p);
2076 mdatabase_define (tag0, tag1, tag2, tag3,
2081 M17N_OBJECT_UNREF (pl);
2087 mplist_pop (load_im_info_keys);
2091 /* Support functions for mdebug_dump_im. */
2094 dump_im_map (MPlist *map_list, int indent)
2097 MSymbol key = MPLIST_KEY (map_list);
2098 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2100 prefix = (char *) alloca (indent + 1);
2101 memset (prefix, 32, indent);
2102 prefix[indent] = '\0';
2104 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2105 if (map->map_actions)
2106 mdebug_dump_plist (map->map_actions, indent + 2);
2109 MPLIST_DO (map_list, map->submaps)
2111 fprintf (stderr, "\n%s ", prefix);
2112 dump_im_map (map_list, indent + 2);
2115 if (map->branch_actions)
2117 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2118 mdebug_dump_plist (map->branch_actions, indent + 4);
2119 fprintf (stderr, ")");
2121 fprintf (stderr, ")");
2126 dump_im_state (MIMState *state, int indent)
2131 prefix = (char *) alloca (indent + 1);
2132 memset (prefix, 32, indent);
2133 prefix[indent] = '\0';
2135 fprintf (stderr, "(%s", msymbol_name (state->name));
2136 if (state->map->submaps)
2138 MPLIST_DO (map_list, state->map->submaps)
2140 fprintf (stderr, "\n%s ", prefix);
2141 dump_im_map (map_list, indent + 2);
2144 fprintf (stderr, ")");
2153 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2154 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2155 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2156 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2157 char buf[6], buf2[256];
2161 Minput_method = msymbol ("input-method");
2162 msymbol_put (Minput_method, M_database_hook, (void *) input_method_hook);
2163 Minput_driver = msymbol ("input-driver");
2164 Mtitle = msymbol ("title");
2165 Mmacro = msymbol ("macro");
2166 Mmodule = msymbol ("module");
2167 Mmap = msymbol ("map");
2168 Mstate = msymbol ("state");
2169 Minsert = msymbol ("insert");
2170 Mdelete = msymbol ("delete");
2171 Mmove = msymbol ("move");
2172 Mmark = msymbol ("mark");
2173 Mpushback = msymbol ("pushback");
2174 Mundo = msymbol ("undo");
2175 Mcall = msymbol ("call");
2176 Mshift = msymbol ("shift");
2177 Mselect = msymbol ("select");
2178 Mshow = msymbol ("show");
2179 Mhide = msymbol ("hide");
2180 Mset = msymbol ("set");
2181 Madd = msymbol ("add");
2182 Msub = msymbol ("sub");
2183 Mmul = msymbol ("mul");
2184 Mdiv = msymbol ("div");
2185 Mequal = msymbol ("=");
2186 Mless = msymbol ("<");
2187 Mgreater = msymbol (">");
2189 Minput_preedit_start = msymbol ("input-preedit-start");
2190 Minput_preedit_done = msymbol ("input-preedit-done");
2191 Minput_preedit_draw = msymbol ("input-preedit-draw");
2192 Minput_status_start = msymbol ("input-status-start");
2193 Minput_status_done = msymbol ("input-status-done");
2194 Minput_status_draw = msymbol ("input-status-draw");
2195 Minput_candidates_start = msymbol ("input-candidates-start");
2196 Minput_candidates_done = msymbol ("input-candidates-done");
2197 Minput_candidates_draw = msymbol ("input-candidates-draw");
2198 Minput_set_spot = msymbol ("input-set-spot");
2199 Minput_toggle = msymbol ("input-toggle");
2200 Minput_reset = msymbol ("input-reset");
2202 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2203 Mcandidate_index = msymbol (" candidate-index");
2205 Minit = msymbol ("init");
2206 Mfini = msymbol ("fini");
2208 M_key_alias = msymbol (" key-alias");
2209 M_description = msymbol ("description");
2210 M_command = msymbol ("command");
2211 M_variable = msymbol ("variable");
2213 Mdetail_text = msymbol_as_managing_key (" detail-text");
2215 load_im_info_keys = mplist ();
2216 plist = mplist_add (load_im_info_keys, Mmap, Mnil);
2217 plist = mplist_add (plist, Mstate, Mnil);
2218 plist = mplist_add (plist, Mmacro, Mnil);
2219 plist = mplist_add (plist, Mmodule, Mnil);
2224 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2226 one_char_symbol[i] = msymbol (buf);
2228 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (key_names[i]));
2230 for (buf[2] = i; i < 127; i++, buf[2]++)
2231 one_char_symbol[i] = msymbol (buf + 2);
2232 one_char_symbol[i++] = msymbol ("Delete");
2238 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2240 one_char_symbol[i] = msymbol (buf);
2241 if (key_names[i - 128])
2243 strcpy (buf2 + 2, key_names[i - 128]);
2244 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2247 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2248 one_char_symbol[i] = msymbol (buf + 2);
2249 one_char_symbol[i] = msymbol ("M-Delete");
2251 command_list = variable_list = NULL;
2253 minput_default_driver.open_im = open_im;
2254 minput_default_driver.close_im = close_im;
2255 minput_default_driver.create_ic = create_ic;
2256 minput_default_driver.destroy_ic = destroy_ic;
2257 minput_default_driver.filter = filter;
2258 minput_default_driver.lookup = lookup;
2259 minput_default_driver.callback_list = mplist ();
2260 mplist_put (minput_default_driver.callback_list, Minput_reset,
2262 minput_driver = &minput_default_driver;
2269 MPlist *par_lang, *par_im, *p;
2273 MPLIST_DO (par_lang, command_list)
2275 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2277 MPLIST_DO (p, MPLIST_VAL (par_im))
2278 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2279 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2281 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2283 M17N_OBJECT_UNREF (command_list);
2284 command_list = NULL;
2288 MPLIST_DO (par_lang, variable_list)
2290 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2292 MPLIST_DO (p, MPLIST_VAL (par_im))
2293 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2294 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2296 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2298 M17N_OBJECT_UNREF (variable_list);
2299 variable_list = NULL;
2302 if (minput_default_driver.callback_list)
2304 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2305 minput_default_driver.callback_list = NULL;
2307 if (minput_driver->callback_list)
2309 M17N_OBJECT_UNREF (minput_driver->callback_list);
2310 minput_driver->callback_list = NULL;
2313 M17N_OBJECT_UNREF (load_im_info_keys);
2317 minput__callback (MInputContext *ic, MSymbol command)
2319 if (ic->im->driver.callback_list)
2321 MInputCallbackFunc func
2322 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2326 (func) (ic, command);
2331 minput__char_to_key (int c)
2333 if (c < 0 || c >= 0x100)
2336 return one_char_symbol[c];
2340 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2345 /*** @addtogroup m17nInputMethod */
2350 @name Variables: Predefined symbols for callback commands.
2352 These are the predefined symbols that are used as the @c COMMAND
2353 argument of callback functions of an input method driver (see
2354 #MInputDriver::callback_list ). */
2356 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2358 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2359 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2364 MSymbol Minput_preedit_start;
2365 MSymbol Minput_preedit_done;
2366 MSymbol Minput_preedit_draw;
2367 MSymbol Minput_status_start;
2368 MSymbol Minput_status_done;
2369 MSymbol Minput_status_draw;
2370 MSymbol Minput_candidates_start;
2371 MSymbol Minput_candidates_done;
2372 MSymbol Minput_candidates_draw;
2373 MSymbol Minput_set_spot;
2374 MSymbol Minput_toggle;
2375 MSymbol Minput_reset;
2380 @brief The default driver for internal input methods.
2382 The variable #minput_default_driver is the default driver for
2383 internal input methods.
2385 The member MInputDriver::open_im () searches the m17n database for
2386 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2387 $NAME\> and loads it.
2389 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2390 programmers responsibility to set it to a plist of proper callback
2391 functions. Otherwise, no feedback information (e.g. preedit text)
2392 can be shown to users.
2394 The macro M17N_INIT () sets the variable #minput_driver to the
2395 pointer to this driver so that all internal input methods use it.
2397 Therefore, unless @c minput_driver is set differently, the driver
2398 dependent arguments $ARG of the functions whose name begin with
2399 "minput_" are all ignored. */
2402 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2404 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2406 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2407 \< #Minput_method, $LANGUAGE, $NAME\>
2408 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2410 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2411 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2412 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2413 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2415 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2416 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2418 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2419 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2421 MInputDriver minput_default_driver;
2425 @brief The driver for internal input methods.
2427 The variable #minput_driver is a pointer to the input method
2428 driver that is used by internal input methods. The macro
2429 M17N_INIT () initializes it to a pointer to #minput_default_driver
2430 (if <m17n<EM></EM>.h> is included) or to #minput_gui_driver (if
2431 <m17n-gui<EM></EM>.h> is included). */
2433 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
2436 ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
2437 ¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó¥¿¤ò
2438 #minput_default_driver (<m17n<EM></EM>.h> ¤¬ include
2439 ¤µ¤ì¤Æ¤¤¤ë»þ) ¤Þ¤¿¤Ï #minput_gui_driver ( <m17n-gui<EM></EM>.h> ¤¬
2440 include ¤µ¤ì¤Æ¤¤¤ë»þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
2442 MInputDriver *minput_driver;
2444 MSymbol Minput_driver;
2449 @brief Open an input method.
2451 The minput_open_im () function opens an input method that matches
2452 language $LANGUAGE and name $NAME, and returns a pointer to the
2453 input method object newly allocated.
2455 This function at first decides an driver for the input method as
2458 If $LANGUAGE is not #Mnil, the driver pointed by the variable
2459 #minput_driver is used.
2461 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
2462 driver pointed to by the property value is used to open the input
2463 method. If $NAME has no such property, @c NULL is returned.
2465 Then, the member MInputDriver::open_im () of the driver is
2468 $ARG is set in the member @c arg of the structure MInputMethod so
2469 that the driver can refer to it. */
2472 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
2474 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
2475 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2477 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
2479 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
2480 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
2482 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
2483 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
2484 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2486 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
2488 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
2490 @latexonly \IPAlabel{minput_open} @endlatexonly
2495 minput_open_im (MSymbol language, MSymbol name, void *arg)
2498 MInputDriver *driver;
2501 driver = minput_driver;
2504 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
2506 MERROR (MERROR_IM, NULL);
2509 MSTRUCT_CALLOC (im, MERROR_IM);
2510 im->language = language;
2513 im->driver = *driver;
2514 if ((*im->driver.open_im) (im) < 0)
2525 @brief Close an input method.
2527 The minput_close_im () function closes the input method $IM, which
2528 must have been created by minput_open_im (). */
2531 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
2533 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
2534 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
2537 minput_close_im (MInputMethod *im)
2539 (*im->driver.close_im) (im);
2546 @brief Create an input context.
2548 The minput_create_ic () function creates an input context object
2549 associated with input method $IM, and calls callback functions
2550 corresponding to #Minput_preedit_start, #Minput_status_start, and
2551 #Minput_status_draw in this order.
2555 If an input context is successfully created, minput_create_ic ()
2556 returns a pointer to it. Otherwise it returns @c NULL. */
2559 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
2561 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
2562 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
2563 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
2564 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2568 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
2569 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2573 minput_create_ic (MInputMethod *im, void *arg)
2577 MSTRUCT_CALLOC (ic, MERROR_IM);
2580 ic->preedit = mtext ();
2581 ic->candidate_list = NULL;
2582 ic->produced = mtext ();
2583 ic->spot.x = ic->spot.y = 0;
2585 ic->plist = mplist ();
2586 if ((*im->driver.create_ic) (ic) < 0)
2588 M17N_OBJECT_UNREF (ic->preedit);
2589 M17N_OBJECT_UNREF (ic->produced);
2590 M17N_OBJECT_UNREF (ic->plist);
2595 if (im->driver.callback_list)
2597 minput__callback (ic, Minput_preedit_start);
2598 minput__callback (ic, Minput_status_start);
2599 minput__callback (ic, Minput_status_draw);
2608 @brief Destroy an input context.
2610 The minput_destroy_ic () function destroys the input context $IC,
2611 which must have been created by minput_create_ic (). It calls
2612 callback functions corresponding to #Minput_preedit_done,
2613 #Minput_status_done, and #Minput_candidates_done in this order. */
2616 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
2618 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
2619 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
2620 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
2621 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
2622 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2626 minput_destroy_ic (MInputContext *ic)
2628 if (ic->im->driver.callback_list)
2630 minput__callback (ic, Minput_preedit_done);
2631 minput__callback (ic, Minput_status_done);
2632 minput__callback (ic, Minput_candidates_done);
2634 (*ic->im->driver.destroy_ic) (ic);
2635 M17N_OBJECT_UNREF (ic->preedit);
2636 M17N_OBJECT_UNREF (ic->produced);
2637 M17N_OBJECT_UNREF (ic->plist);
2644 @brief Filter an input key.
2646 The minput_filter () function filters input key $KEY according to
2647 input context $IC, and calls callback functions corresponding to
2648 #Minput_preedit_draw, #Minput_status_draw, and
2649 #Minput_candidates_draw if the preedit text, the status, and the
2650 current candidate are changed respectively.
2653 If $KEY is filtered out, this function returns 1. In that case,
2654 the caller should discard the key. Otherwise, it returns 0, and
2655 the caller should handle the key, for instance, by calling the
2656 function minput_lookup () with the same key. */
2659 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
2661 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2662 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
2663 #Minput_preedit_draw, #Minput_status_draw,
2664 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
2667 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
2668 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
2669 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
2670 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
2672 @latexonly \IPAlabel{minput_filter} @endlatexonly
2676 minput_filter (MInputContext *ic, MSymbol key, void *arg)
2683 ret = (*ic->im->driver.filter) (ic, key, arg);
2685 if (ic->im->driver.callback_list)
2687 if (ic->preedit_changed)
2688 minput__callback (ic, Minput_preedit_draw);
2689 if (ic->status_changed)
2690 minput__callback (ic, Minput_status_draw);
2691 if (ic->candidates_changed)
2692 minput__callback (ic, Minput_candidates_draw);
2701 @brief Look up a text produced in the input context.
2703 The minput_lookup () function looks up a text in the input context
2704 $IC. $KEY must be the same one provided to the previous call of
2707 If a text was produced by the input method, it is concatenated
2710 This function calls #MInputDriver::lookup .
2713 If $KEY was correctly handled by the input method, this function
2714 returns 0. Otherwise, returns -1, even in that case, some text
2715 may be produced in $MT. */
2718 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
2720 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
2721 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2723 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
2726 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
2729 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
2730 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
2731 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
2733 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
2736 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2738 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
2743 @brief Set the spot of the input context.
2745 The minput_set_spot () function set the spot of input context $IC
2746 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
2747 The semantics of these values depend on the input method driver.
2749 For instance, a driver designed to work in a CUI environment may
2750 use $X and $Y as column and row numbers, and ignore $ASCENT and
2751 $DESCENT . A driver designed to work in a window system may
2752 interpret $X and $Y as pixel offsets relative to the origin of the
2753 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
2754 descent pixels of the line at ($X . $Y ).
2756 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
2758 $MT and $POS is the M-text and the character position at the spot.
2759 $MT may be @c NULL, in which case, the input method cannot get
2760 information about the text around the spot. */
2763 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
2765 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
2766 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
2767 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
2769 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
2770 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
2771 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
2772 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
2773 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
2774 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
2776 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
2778 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
2779 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
2783 minput_set_spot (MInputContext *ic, int x, int y,
2784 int ascent, int descent, int fontsize,
2789 ic->spot.ascent = ascent;
2790 ic->spot.descent = descent;
2791 ic->spot.fontsize = fontsize;
2794 if (ic->im->driver.callback_list)
2795 minput__callback (ic, Minput_set_spot);
2800 @brief Toggle input method.
2802 The minput_toggle () function toggles the input method associated
2803 with input context $IC. */
2805 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
2807 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2808 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
2812 minput_toggle (MInputContext *ic)
2814 if (ic->im->driver.callback_list)
2815 minput__callback (ic, Minput_toggle);
2816 ic->active = ! ic->active;
2820 @brief Reset an input context.
2822 The minput_reset_ic () function resets input context $IC by
2823 calling a callback function corresponding to #Minput_reset. It
2824 actually shifts the state to the initial one, and thus the current
2825 preediting text (if any) is committed. If necessary, a program
2826 can extract that committed text by calling minput_lookup () just
2827 after the call of minput_reset_ic (). In that case, the arguments
2828 @c KEY and @c ARG of minput_lookup () are ignored. */
2830 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
2832 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
2833 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2834 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
2835 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
2836 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
2837 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
2840 minput_reset_ic (MInputContext *ic)
2842 if (ic->im->driver.callback_list)
2843 minput__callback (ic, Minput_reset);
2848 @brief Key of a text property for detailed description.
2850 The symbol #Mdetail_text is a managing key usually used for a
2851 text property whose value is an M-text that contains detailed
2854 @brief ¾ÜºÙÀâÌÀÍѥƥ¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼.
2856 ¥·¥ó¥Ü¥ë #Mdetail_text ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ê¡¢Ä̾ï¾ÜºÙ¤ÊÀâÌÀ¤ò´Þ¤à
2857 M-text ¤òÃͤȤ·¤Æ»ý¤Ä¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ËÍѤ¤¤é¤ì¤ë¡£
2859 MSymbol Mdetail_text;
2862 @brief Get description text of an input method.
2864 The minput_get_description () function returns an M-text that
2865 briefly describes the input method specified by $LANGUAGE and
2866 $NAME. The returned M-text may have a text property, from its
2867 beginning to end, #Mdetail_text whose value is an M-text
2868 describing the input method in more detail.
2871 If the specified input method has a description text, a pointer to
2872 #MText is returned. A caller have to free it by m17n_object_unref ().
2873 If the input method does not have a description text, @c NULL is
2876 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
2878 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME
2879 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£ÊÖ¤µ¤ì¤ë M-text
2880 ¤Ë¤Ï¡¢¤½¤ÎÁ´ÂΤËÂФ·¤Æ #Mdetail_text
2881 ¤È¤¤¤¦¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬Éղ䵤ì¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ê¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¤µ¤é¤Ë¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
2885 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
2886 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
2887 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
2890 minput_get_description (MSymbol language, MSymbol name)
2892 MPlist *plist = load_im_info (language, name, M_description);
2898 if (! MPLIST_PLIST_P (plist))
2900 M17N_OBJECT_UNREF (plist);
2903 pl = MPLIST_PLIST (plist);
2904 while (! MPLIST_TAIL_P (pl) && ! MPLIST_MTEXT_P (pl))
2905 pl = MPLIST_NEXT (pl);
2906 if (MPLIST_MTEXT_P (pl))
2907 mt = get_description_advance (pl);
2908 M17N_OBJECT_UNREF (plist);
2913 @brief Get information about input method commands.
2915 The minput_get_commands () function returns information about
2916 input method commands of the input method specified by $LANGUAGE
2917 and $NAME. An input method command is a pseudo key event to which
2918 one or more actual input key sequences are assigned.
2920 There are two kinds of commands, global and local. Global
2921 commands are used by multiple input methods for the same purpose,
2922 and have global key assignments. Local commands are used only in
2923 a specific input method, and have only local key assignments.
2925 Each input method may locally change key assignments for global
2926 commands. A global key assignment for a global command are
2927 effective only when the current input method does not have local
2928 key assignments for that command.
2930 If $NAME is #Mnil, information about global commands is returned.
2931 In this case $LANGUAGE is ignored.
2933 If $NAME is not #Mnil, information about those commands that have
2934 local key assignments in the input method specified by $LANGUAGE
2935 and $NAME is returned.
2938 If no input method commands are found, this function returns @c NULL.
2940 Otherwise, a pointer to a plist is returned. The key of each
2941 element in the plist is a symbol representing a command, and the
2942 value is a plist of the form COMMAND-INFO described below.
2944 The first element of COMMAND-INFO has the key #Mtext, and the
2945 value is an M-text describing the command briefly. This M-text
2946 may have a text property whose key is #Mdetail_text and whose
2947 value is an M-text describing the command in more detail.
2949 If there are no more elements, that means no key sequences are
2950 assigned to the command. Otherwise, each of the remaining
2951 elements has the key #Mplist, and the value is a plist whose keys are
2952 #Msymbol and values are symbols representing input keys, which are
2953 currently assigned to the command.
2955 As the returned plist is kept in the library, the caller must not
2956 modify nor free it. */
2958 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
2960 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME
2961 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2962 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
2964 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£
2965 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ÇÍѤ¤¤é¤ì¤ë¡£
2966 ¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
2968 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
2969 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ß͸ú¤Ç¤¢¤ë¡£
2971 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2972 ¤³¤Î¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
2974 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME
2975 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2978 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
2980 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2981 ¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î
2982 COMMAND-INFO ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
2984 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext
2985 ¤ò¡¢ÃͤȤ·¤Æ¤½¤Î¥³¥Þ¥ó¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤ò»ý¤Ä¡£¤³¤Î M-text
2987 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤Î¥³¥Þ¥ó¥É¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
2990 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
2991 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ#Mplist
2992 ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£
2993 ¤³¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol
2994 ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2996 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
2999 minput_get_commands (MSymbol language, MSymbol name)
3001 MPlist *plist = get_command_list (language, name);
3003 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3007 @brief Assign a key sequence to an input method command.
3009 The minput_assign_command_keys () function assigns input key
3010 sequence $KEYSEQ to input method command $COMMAND for the input
3011 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3012 key sequence is assigned globally no matter what $LANGUAGE is.
3013 Otherwise the key sequence is assigned locally.
3015 Each element of $KEYSEQ must have the key $Msymbol and the value
3016 must be a symbol representing an input key.
3018 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3019 globally or locally.
3021 This assignment gets effective in a newly opened input method.
3024 If the operation was successful, 0 is returned. Otherwise -1 is
3025 returned, and #merror_code is set to #MERROR_IM. */
3027 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3029 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3030 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND
3031 ¤ËÂФ·¤Æ¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil
3032 ¤Ê¤é¤Ð¡¢$LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
3033 ¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3035 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol
3036 ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3038 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£
3039 ¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3041 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤Ë¤Ê¤ë¡£
3044 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3045 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3048 minput_assign_command_keys (MSymbol language, MSymbol name,
3049 MSymbol command, MPlist *keyseq)
3051 MPlist *plist, *pl, *p;
3053 if (check_command_keyseq (keyseq) < 0
3054 || ! (plist = get_command_list (language, name)))
3055 MERROR (MERROR_IM, -1);
3056 pl = mplist_get (plist, command);
3059 pl = MPLIST_NEXT (pl);
3061 while ((p = mplist_pop (pl)))
3062 M17N_OBJECT_UNREF (p);
3065 keyseq = mplist_copy (keyseq);
3066 mplist_push (pl, Mplist, keyseq);
3067 M17N_OBJECT_UNREF (keyseq);
3073 MERROR (MERROR_IM, -1);
3076 pl = get_command_list (Mnil, Mnil); /* Get global commands. */
3077 pl = mplist_get (pl, command);
3079 MERROR (MERROR_IM, -1);
3081 mplist_add (p, Mtext, mplist_value (pl));
3082 keyseq = mplist_copy (keyseq);
3083 mplist_add (p, Mplist, keyseq);
3084 M17N_OBJECT_UNREF (keyseq);
3085 mplist_push (plist, command, p);
3091 @brief Get a list of variables of an input method.
3093 The minput_get_variables () function returns a plist (#MPlist) of
3094 variables used to control the behavior of the input method
3095 specified by $LANGUAGE and $NAME. The key of an element of the
3096 plist is a symbol representing a variable, and the value is a
3097 plist of the form VAR-INFO (described below) that carries the
3098 information about the variable.
3100 The first element of VAR-INFO has the key #Mtext, and the value is
3101 an M-text describing the variable briefly. This M-text may have a
3102 text property #Mdetail_text whose value is an M-text describing
3103 the variable in more detail.
3105 The second element of VAR-INFO is for the value of the variable.
3106 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3107 integer, a symbol, or an M-text, respectively. The variable is
3108 set to this value when an input context is created for the input
3111 If there are no more elements, the variable can take any value
3112 that matches with the above type. Otherwise, the remaining
3113 elements of VAR-INFO are to specify valid values of the variable.
3115 If the type of the variable is integer, the following elements
3116 have the key #Minteger or #Mplist. If it is #Minteger, the value
3117 is a valid integer value. If it is #Mplist, the value is a plist
3118 of two of elements. Both of them have the key #Minteger, and
3119 values are the minimum and maximum bounds of the valid value
3122 If the type of the variable is symbol or M-text, the following
3123 elements of the plist have the key #Msymbol or #Mtext,
3124 respectively, and the value must be a valid one.
3126 For instance, suppose an input method has the variables:
3128 @li name:intvar, description: "value is an integer",
3129 initial value:0, value-range:0..3,10,20
3131 @li name:symvar, description: "value is a symbol",
3132 initial value:nil, value-range:a, b, c, nil
3134 @li name:txtvar, description: "value is an M-text",
3135 initial value:empty text, no value-range (i.e. any text)
3137 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3138 a value, and '(...)' means a plist):
3141 plist:(intvar:(mtext:'value is an integer'
3143 plist:(integer:0 integer:3)
3146 symvar:(mtext:"value is a symbol"
3152 txtvar:(mtext:"value is an M-text"
3157 If the input method uses any variables, a pointer to #MPlist is
3158 returned. As the plist is kept in the library, a caller must not
3159 modify nor free it. If the input method does not use any
3160 variable, @c NULL is returned. */
3162 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3164 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3165 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3166 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3167 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3168 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3170 VAR-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext ¤ò¡¢ÃͤȤ·¤Æ¤½¤ÎÊÑ¿ô¤ò´Êñ¤ËÀâÌÀ¤¹¤ë
3171 M-text ¤ò»ý¤Ä¡£¤³¤Î M-text ¤Ï¡¢#Mdetail_text
3172 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤ÎÊÑ¿ô¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3175 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3176 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3177 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3179 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3180 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3182 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3183 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3184 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3185 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3187 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3188 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3190 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3192 @li name:intvar, ÀâÌÀ:"value is an integer",
3193 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3195 @li name:symvar, ÀâÌÀ:"value is a symbol",
3196 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3198 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3199 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3201 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3202 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3205 plist:(intvar:(mtext:"value is an integer"
3207 plist:(integer:0 integer:3)
3210 symvar:(mtext:"value is a symbol"
3216 txtvar:(mtext:"value is an M-text"
3221 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3222 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3223 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3226 minput_get_variables (MSymbol language, MSymbol name)
3228 MPlist *plist = get_variable_list (language, name);
3230 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3234 @brief Set the initial value of an input method variable.
3236 The minput_set_variable () function sets the initial value of
3237 input method variable $VARIABLE to $VALUE for the input method
3238 specified by $LANGUAGE and $NAME.
3240 By default, the initial value is 0.
3242 This setting gets effective in a newly opened input method.
3245 If the operation was successful, 0 is returned. Otherwise -1 is
3246 returned, and #merror_code is set to #MERROR_IM. */
3248 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3250 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3251 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3252 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3254 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3256 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3259 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3260 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3263 minput_set_variable (MSymbol language, MSymbol name,
3264 MSymbol variable, void *value)
3266 MPlist *plist, *val_element, *range_element;
3269 if (language == Mnil || name == Mnil)
3270 MERROR (MERROR_IM, -1);
3271 plist = get_variable_list (language, name);
3273 MERROR (MERROR_IM, -1);
3274 plist = (MPlist *) mplist_get (plist, variable);
3276 MERROR (MERROR_IM, -1);
3277 val_element = MPLIST_NEXT (plist);
3278 type = MPLIST_KEY (val_element);
3279 range_element = MPLIST_NEXT (val_element);
3281 if (! MPLIST_TAIL_P (range_element))
3283 if (type == Minteger)
3285 int val = (int) value, this_val;
3287 MPLIST_DO (plist, range_element)
3289 this_val = (int) MPLIST_VAL (plist);
3290 if (MPLIST_PLIST_P (plist))
3292 int min_bound, max_bound;
3293 MPlist *pl = MPLIST_PLIST (plist);
3295 min_bound = (int) MPLIST_VAL (pl);
3296 pl = MPLIST_NEXT (pl);
3297 max_bound = (int) MPLIST_VAL (pl);
3298 if (val >= min_bound && val <= max_bound)
3301 else if (val == this_val)
3304 if (MPLIST_TAIL_P (plist))
3305 MERROR (MERROR_IM, -1);
3307 else if (type == Msymbol)
3309 MPLIST_DO (plist, range_element)
3310 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3312 if (MPLIST_TAIL_P (plist))
3313 MERROR (MERROR_IM, -1);
3315 else /* type == Mtext */
3317 MPLIST_DO (plist, range_element)
3318 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3320 if (MPLIST_TAIL_P (plist))
3321 MERROR (MERROR_IM, -1);
3322 M17N_OBJECT_REF (value);
3326 mplist_set (val_element, type, value);
3332 /*** @addtogroup m17nDebug */
3338 @brief Dump an input method.
3340 The mdebug_dump_im () function prints the input method $IM in a
3341 human readable way to the stderr. $INDENT specifies how many
3342 columns to indent the lines but the first one.
3345 This function returns $IM. */
3347 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3349 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3350 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3353 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3356 mdebug_dump_im (MInputMethod *im, int indent)
3358 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3361 prefix = (char *) alloca (indent + 1);
3362 memset (prefix, 32, indent);
3363 prefix[indent] = '\0';
3365 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3366 msymbol_name (im->name));
3367 mdebug_dump_mtext (im_info->title, 0, 0);
3368 if (im->name != Mnil)
3372 MPLIST_DO (state, im_info->states)
3374 fprintf (stderr, "\n%s ", prefix);
3375 dump_im_state (MPLIST_VAL (state), indent + 2);
3378 fprintf (stderr, ")");