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 *). */
583 load_external_module (MPlist *plist, MPlist *externals)
588 MIMExternalModule *external;
592 if (MPLIST_MTEXT_P (plist))
593 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
594 else if (MPLIST_SYMBOL_P (plist))
595 module = MPLIST_SYMBOL (plist);
596 module_file = alloca (strlen (MSYMBOL_NAME (module))
597 + strlen (DLOPEN_SHLIB_EXT) + 1);
598 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
600 handle = dlopen (module_file, RTLD_NOW);
603 fprintf (stderr, "%s\n", dlerror ());
604 MERROR (MERROR_IM, -1);
606 func_list = mplist ();
607 MPLIST_DO (plist, MPLIST_NEXT (plist))
609 if (! MPLIST_SYMBOL_P (plist))
610 MERROR_GOTO (MERROR_IM, err_label);
611 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
613 MERROR_GOTO (MERROR_IM, err_label);
614 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
617 MSTRUCT_MALLOC (external, MERROR_IM);
618 external->handle = handle;
619 external->func_list = func_list;
620 mplist_add (externals, module, external);
625 M17N_OBJECT_UNREF (func_list);
630 /** Load a state from PLIST into a newly allocated state object.
632 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
633 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
634 MAPS is a plist of defined maps.
635 Return the state object. */
638 load_state (MPlist *plist, MPlist *maps, MSymbol language, MPlist *macros)
642 MSTRUCT_CALLOC (state, MERROR_IM);
643 if (! MPLIST_SYMBOL_P (plist))
644 MERROR (MERROR_IM, NULL);
645 state->name = MPLIST_SYMBOL (plist);
646 plist = MPLIST_NEXT (plist);
647 if (MPLIST_MTEXT_P (plist))
649 state->title = MPLIST_MTEXT (plist);
650 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
651 Mlanguage, language);
652 M17N_OBJECT_REF (state->title);
653 plist = MPLIST_NEXT (plist);
655 MSTRUCT_CALLOC (state->map, MERROR_IM);
656 MPLIST_DO (plist, plist)
657 if (! MPLIST_PLIST_P (plist)
658 || load_branch (MPLIST_PLIST (plist), maps, state->map, macros) < 0)
659 MERROR (MERROR_IM, NULL);
665 free_map (MIMMap *map)
669 M17N_OBJECT_UNREF (map->map_actions);
672 MPLIST_DO (plist, map->submaps)
673 free_map ((MIMMap *) MPLIST_VAL (plist));
674 M17N_OBJECT_UNREF (map->submaps);
676 M17N_OBJECT_UNREF (map->branch_actions);
680 /* Load an input method from PLIST into IM_INTO, and return it. */
683 load_input_method (MSymbol language, MSymbol name, MPlist *plist,
684 MInputMethodInfo *im_info)
688 MPlist *states = NULL;
689 MPlist *externals = NULL;
690 MPlist *macros = NULL;
693 for (; MPLIST_PLIST_P (plist); plist = MPLIST_NEXT (plist))
695 elt = MPLIST_PLIST (plist);
696 if (! MPLIST_SYMBOL_P (elt))
697 MERROR_GOTO (MERROR_IM, err);
698 if (MPLIST_SYMBOL (elt) == Mtitle)
700 elt = MPLIST_NEXT (elt);
701 if (MPLIST_MTEXT_P (elt))
703 title = MPLIST_MTEXT (elt);
704 M17N_OBJECT_REF (title);
707 MERROR_GOTO (MERROR_IM, err);
709 else if (MPLIST_SYMBOL (elt) == Mmap)
711 maps = mplist__from_alist (MPLIST_NEXT (elt));
713 MERROR_GOTO (MERROR_IM, err);
715 else if (MPLIST_SYMBOL (elt) == Mmacro)
718 MPLIST_DO (elt, MPLIST_NEXT (elt))
720 if (! MPLIST_PLIST_P (elt)
721 || load_macros (MPLIST_PLIST (elt), macros) < 0)
722 MERROR_GOTO (MERROR_IM, err);
725 else if (MPLIST_SYMBOL (elt) == Mmodule)
727 externals = mplist ();
728 MPLIST_DO (elt, MPLIST_NEXT (elt))
730 if (! MPLIST_PLIST_P (elt)
731 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
732 MERROR_GOTO (MERROR_IM, err);
735 else if (MPLIST_SYMBOL (elt) == Mstate)
738 MPLIST_DO (elt, MPLIST_NEXT (elt))
742 if (! MPLIST_PLIST_P (elt))
743 MERROR_GOTO (MERROR_IM, err);
744 state = load_state (MPLIST_PLIST (elt), maps, language, macros);
746 MERROR_GOTO (MERROR_IM, err);
747 mplist_put (states, state->name, state);
754 MPLIST_DO (elt, maps)
755 M17N_OBJECT_UNREF (MPLIST_VAL (elt));
756 M17N_OBJECT_UNREF (maps);
759 title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
760 MTEXT_FORMAT_US_ASCII);
761 im_info->title = title;
762 im_info->externals = externals;
763 im_info->macros = macros;
764 im_info->states = states;
770 MPLIST_DO (elt, maps)
771 M17N_OBJECT_UNREF (MPLIST_VAL (elt));
772 M17N_OBJECT_UNREF (maps);
775 M17N_OBJECT_UNREF (title);
778 MPLIST_DO (plist, states)
780 MIMState *state = (MIMState *) MPLIST_VAL (plist);
783 M17N_OBJECT_UNREF (state->title);
785 free_map (state->map);
788 M17N_OBJECT_UNREF (states);
792 MPLIST_DO (plist, externals)
794 MIMExternalModule *external = MPLIST_VAL (plist);
796 dlclose (external->handle);
797 M17N_OBJECT_UNREF (external->func_list);
799 MPLIST_KEY (plist) = Mt;
801 M17N_OBJECT_UNREF (externals);
808 static int take_action_list (MInputContext *ic, MPlist *action_list);
811 shift_state (MInputContext *ic, MSymbol state_name)
813 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
814 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
817 /* Find a state to shift to. If not found, shift to the initial
819 state = (MIMState *) mplist_get (im_info->states, state_name);
821 state = (MIMState *) MPLIST_VAL (im_info->states);
823 MDEBUG_PRINT1 ("\n[IM] state-shift (%s)", MSYMBOL_NAME (state->name));
825 /* Enter the new state. */
826 ic_info->state = state;
827 ic_info->map = state->map;
828 ic_info->state_key_head = ic_info->key_head;
829 if (state == (MIMState *) MPLIST_VAL (im_info->states))
831 /* We have shifted to the initial state. */
834 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
835 Mcandidate_list, NULL, 0);
836 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
837 Mcandidate_index, NULL, 0);
838 mtext_cat (ic->produced, ic->preedit);
839 if ((mdebug__flag & mdebug_mask)
840 && mtext_nchars (ic->produced) > 0)
844 MDEBUG_PRINT (" (produced");
845 for (i = 0; i < mtext_nchars (ic->produced); i++)
846 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
849 mtext_reset (ic->preedit);
850 ic->candidate_list = NULL;
851 ic->candidate_show = 0;
852 ic->preedit_changed = ic->candidates_changed = 1;
853 MPLIST_DO (p, ic_info->markers)
855 MPLIST_DO (p, ic_info->vars)
858 memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
859 sizeof (int) * (ic_info->used - ic_info->state_key_head));
860 ic_info->used -= ic_info->state_key_head;
861 ic_info->state_key_head = ic_info->key_head = 0;
863 mtext_cpy (ic_info->preedit_saved, ic->preedit);
864 ic_info->state_pos = ic->cursor_pos;
865 ic->status = state->title;
867 ic->status = im_info->title;
868 ic->status_changed = 1;
869 if (ic_info->key_head == ic_info->used
870 && ic_info->map == ic_info->state->map
871 && ic_info->map->map_actions)
873 MDEBUG_PRINT (" init-actions:");
874 take_action_list (ic, ic_info->map->map_actions);
878 /* Find a candidate group that contains a candidate number INDEX from
879 PLIST. Set START_INDEX to the first candidate number of the group,
880 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
881 candidate group number if they are non-NULL. If INDEX is -1, find
882 the last candidate group. */
885 find_candidates_group (MPlist *plist, int index,
886 int *start_index, int *end_index, int *group_index)
888 int i = 0, gidx = 0, len;
890 MPLIST_DO (plist, plist)
892 if (MPLIST_MTEXT_P (plist))
893 len = mtext_nchars (MPLIST_MTEXT (plist));
895 len = mplist_length (MPLIST_PLIST (plist));
896 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
902 *end_index = i + len;
914 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
916 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
918 int nchars = mt ? mtext_nchars (mt) : 1;
921 mtext_ins (ic->preedit, pos, mt);
923 mtext_ins_char (ic->preedit, pos, c, 1);
924 MPLIST_DO (markers, ic_info->markers)
925 if (MPLIST_INTEGER (markers) > pos)
926 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
927 if (ic->cursor_pos >= pos)
928 ic->cursor_pos += nchars;
929 ic->preedit_changed = 1;
934 preedit_delete (MInputContext *ic, int from, int to)
936 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
939 mtext_del (ic->preedit, from, to);
940 MPLIST_DO (markers, ic_info->markers)
942 if (MPLIST_INTEGER (markers) > to)
944 = (void *) (MPLIST_INTEGER (markers) - (to - from));
945 else if (MPLIST_INTEGER (markers) > from);
946 MPLIST_VAL (markers) = (void *) from;
948 if (ic->cursor_pos >= to)
949 ic->cursor_pos -= to - from;
950 else if (ic->cursor_pos > from)
951 ic->cursor_pos = from;
952 ic->preedit_changed = 1;
957 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
959 int code = marker_code (sym);
961 if (mt && (code == '[' || code == ']'))
965 if (code == '[' && current > 0)
967 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
971 else if (code == ']' && current < mtext_nchars (mt))
973 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
979 return (code == '<' ? 0
980 : code == '>' ? limit
981 : code == '-' ? current - 1
982 : code == '+' ? current + 1
983 : code == '=' ? current
984 : code - '0' > limit ? limit
988 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
992 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
994 int from = mtext_property_start (prop);
995 int to = mtext_property_end (prop);
997 MPlist *candidate_list = mtext_property_value (prop);
998 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1000 int ingroup_index = idx - start;
1003 preedit_delete (ic, from, to);
1004 if (MPLIST_MTEXT_P (group))
1006 mt = MPLIST_MTEXT (group);
1007 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1015 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1016 i++, plist = MPLIST_NEXT (plist));
1017 mt = MPLIST_MTEXT (plist);
1018 preedit_insert (ic, from, mt, 0);
1019 to = from + mtext_nchars (mt);
1021 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1022 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1023 ic->cursor_pos = to;
1028 take_action_list (MInputContext *ic, MPlist *action_list)
1030 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1031 MPlist *candidate_list = ic->candidate_list;
1032 int candidate_index = ic->candidate_index;
1033 int candidate_show = ic->candidate_show;
1034 MTextProperty *prop;
1036 MPLIST_DO (action_list, action_list)
1042 if (MPLIST_MTEXT_P (action_list)
1043 || MPLIST_INTEGER_P (action_list))
1044 name = Minsert, args = action_list;
1045 else if (MPLIST_PLIST_P (action_list)
1046 && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list))
1047 || MPLIST_PLIST_P (MPLIST_PLIST (action_list))))
1048 name = Minsert, args = action_list;
1051 action = MPLIST_PLIST (action_list);
1052 name = MPLIST_SYMBOL (action);
1053 args = MPLIST_NEXT (action);
1056 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1057 if (name == Minsert)
1059 if (MPLIST_MTEXT_P (args))
1060 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1061 else if (MPLIST_INTEGER_P (args))
1062 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1063 else if (MPLIST_SYMBOL_P (args))
1065 int c = integer_value (ic, args);
1067 if (c >= 0 && c <= MCHAR_MAX)
1068 preedit_insert (ic, ic->cursor_pos, NULL, c);
1075 args = MPLIST_PLIST (args);
1076 if (MPLIST_MTEXT_P (args))
1078 preedit_insert (ic, ic->cursor_pos, NULL,
1079 mtext_ref_char (MPLIST_MTEXT (args), 0));
1084 mt = MPLIST_MTEXT (MPLIST_PLIST (args));
1085 preedit_insert (ic, ic->cursor_pos, mt, 0);
1086 len = mtext_nchars (mt);
1088 mtext_put_prop (ic->preedit,
1089 ic->cursor_pos - len, ic->cursor_pos,
1090 Mcandidate_list, args);
1091 mtext_put_prop (ic->preedit,
1092 ic->cursor_pos - len, ic->cursor_pos,
1093 Mcandidate_index, (void *) 0);
1096 else if (name == Mselect)
1099 int code, idx, gindex;
1100 int pos = ic->cursor_pos;
1104 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1107 if (MPLIST_SYMBOL_P (args))
1109 code = marker_code (MPLIST_SYMBOL (args));
1115 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1116 group = find_candidates_group (mtext_property_value (prop), idx,
1117 &start, &end, &gindex);
1119 if (code != '[' && code != ']')
1123 ? new_index (NULL, ic->candidate_index - start,
1124 end - start - 1, MPLIST_SYMBOL (args),
1126 : MPLIST_INTEGER (args)));
1129 find_candidates_group (mtext_property_value (prop), -1,
1134 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1139 int ingroup_index = idx - start;
1142 group = mtext_property_value (prop);
1143 len = mplist_length (group);
1156 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1157 idx += (MPLIST_MTEXT_P (group)
1158 ? mtext_nchars (MPLIST_MTEXT (group))
1159 : mplist_length (MPLIST_PLIST (group)));
1160 len = (MPLIST_MTEXT_P (group)
1161 ? mtext_nchars (MPLIST_MTEXT (group))
1162 : mplist_length (MPLIST_PLIST (group)));
1163 if (ingroup_index >= len)
1164 ingroup_index = len - 1;
1165 idx += ingroup_index;
1167 update_candidate (ic, prop, idx);
1169 else if (name == Mshow)
1170 ic->candidate_show = 1;
1171 else if (name == Mhide)
1172 ic->candidate_show = 0;
1173 else if (name == Mdelete)
1175 int len = mtext_nchars (ic->preedit);
1176 int to = (MPLIST_SYMBOL_P (args)
1177 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1179 : MPLIST_INTEGER (args));
1185 if (to < ic->cursor_pos)
1186 preedit_delete (ic, to, ic->cursor_pos);
1187 else if (to > ic->cursor_pos)
1188 preedit_delete (ic, ic->cursor_pos, to);
1190 else if (name == Mmove)
1192 int len = mtext_nchars (ic->preedit);
1194 = (MPLIST_SYMBOL_P (args)
1195 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1197 : MPLIST_INTEGER (args));
1203 if (pos != ic->cursor_pos)
1205 ic->cursor_pos = pos;
1206 ic->preedit_changed = 1;
1209 else if (name == Mmark)
1211 int code = marker_code (MPLIST_SYMBOL (args));
1214 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1215 (void *) ic->cursor_pos);
1217 else if (name == Mpushback)
1219 int num = MPLIST_INTEGER (args);
1222 ic_info->key_head -= num;
1224 ic_info->key_head = num;
1225 if (ic_info->key_head > ic_info->used)
1226 ic_info->key_head = ic_info->used;
1228 else if (name == Mcall)
1230 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1231 MIMExternalFunc func = NULL;
1232 MSymbol module, func_name;
1233 MPlist *func_args, *val;
1236 module = MPLIST_SYMBOL (args);
1237 args = MPLIST_NEXT (args);
1238 func_name = MPLIST_SYMBOL (args);
1240 if (im_info->externals)
1242 MIMExternalModule *external
1243 = (MIMExternalModule *) mplist_get (im_info->externals,
1246 func = (MIMExternalFunc) mplist_get (external->func_list,
1251 func_args = mplist ();
1252 mplist_add (func_args, Mt, ic);
1253 MPLIST_DO (args, MPLIST_NEXT (args))
1257 if (MPLIST_KEY (args) == Msymbol
1258 && MPLIST_KEY (args) != Mnil
1259 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1261 code = new_index (ic, ic->cursor_pos,
1262 mtext_nchars (ic->preedit),
1263 MPLIST_SYMBOL (args), ic->preedit);
1264 mplist_add (func_args, Minteger, (void *) code);
1267 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1269 val = (func) (func_args);
1270 M17N_OBJECT_UNREF (func_args);
1271 if (val && ! MPLIST_TAIL_P (val))
1272 ret = take_action_list (ic, val);
1273 M17N_OBJECT_UNREF (val);
1277 else if (name == Mshift)
1279 shift_state (ic, MPLIST_SYMBOL (args));
1281 else if (name == Mundo)
1283 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1286 mtext_reset (ic->preedit);
1287 mtext_reset (ic_info->preedit_saved);
1288 ic->cursor_pos = ic_info->state_pos = 0;
1289 ic_info->state_key_head = ic_info->key_head = 0;
1291 if (ic_info->used < 0)
1296 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1301 else if (name == Mset || name == Madd || name == Msub
1302 || name == Mmul || name == Mdiv)
1304 MSymbol sym = MPLIST_SYMBOL (args);
1305 int val1 = (int) mplist_get (ic_info->vars, sym), val2;
1307 args = MPLIST_NEXT (args);
1308 val2 = integer_value (ic, args);
1311 else if (name == Madd)
1313 else if (name == Msub)
1315 else if (name == Mmul)
1319 mplist_put (ic_info->vars, sym, (void *) val1);
1320 MDEBUG_PRINT2 ("(%s=%d)", MSYMBOL_NAME (sym), val1);
1322 else if (name == Mequal || name == Mless || name == Mgreater)
1325 MPlist *actions1, *actions2;
1328 val1 = integer_value (ic, args);
1329 args = MPLIST_NEXT (args);
1330 val2 = integer_value (ic, args);
1331 args = MPLIST_NEXT (args);
1332 actions1 = MPLIST_PLIST (args);
1333 args = MPLIST_NEXT (args);
1334 if (MPLIST_TAIL_P (args))
1337 actions2 = MPLIST_PLIST (args);
1338 if (name == Mequal ? val1 == val2
1339 : name == Mless ? val1 < val2
1341 ret = take_action_list (ic, actions1);
1343 ret = take_action_list (ic, actions2);
1349 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1353 && (actions = mplist_get (im_info->macros, name)))
1355 if (take_action_list (ic, actions) < 0)
1362 ic->candidate_list = NULL;
1363 if (ic->cursor_pos > 0
1364 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
1367 ic->candidate_list = mtext_property_value (prop);
1369 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
1371 ic->candidate_from = mtext_property_start (prop);
1372 ic->candidate_to = mtext_property_end (prop);
1375 ic->candidates_changed |= (candidate_list != ic->candidate_list
1376 || candidate_index != ic->candidate_index
1377 || candidate_show != ic->candidate_show);
1382 /* Handle the input key KEY in the current state and map specified in
1383 the input context IC. If KEY is handled correctly, return 0.
1384 Otherwise, return -1. */
1387 handle_key (MInputContext *ic)
1389 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1390 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1391 MIMMap *map = ic_info->map;
1392 MIMMap *submap = NULL;
1393 MSymbol key = ic_info->keys[ic_info->key_head];
1396 MDEBUG_PRINT2 ("[IM] handle `%s' in state %s",
1397 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
1401 submap = mplist_get (map->submaps, key);
1402 if (! submap && (key = msymbol_get (key, M_key_alias)) != Mnil)
1403 submap = mplist_get (map->submaps, key);
1408 MDEBUG_PRINT (" submap-found");
1409 mtext_cpy (ic->preedit, ic_info->preedit_saved);
1410 ic->cursor_pos = ic_info->state_pos;
1411 ic_info->key_head++;
1412 ic_info->map = map = submap;
1413 if (map->map_actions)
1415 MDEBUG_PRINT (" map-actions:");
1416 if (take_action_list (ic, map->map_actions) < 0)
1419 else if (map->submaps)
1421 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
1423 MSymbol key = ic_info->keys[i];
1424 char *name = msymbol_name (key);
1426 if (! name[0] || ! name[1])
1427 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
1429 ic->preedit_changed = 1;
1432 /* If this is the terminal map or we have shifted to another
1433 state, perform branch actions (if any). */
1434 if (! map->submaps || map != ic_info->map)
1436 if (map->branch_actions)
1438 MDEBUG_PRINT (" branch-actions:");
1439 if (take_action_list (ic, map->branch_actions) < 0)
1442 /* If MAP is still not the root map, shift to the current
1444 if (ic_info->map != ic_info->state->map)
1445 shift_state (ic, ic_info->state->name);
1447 MDEBUG_PRINT ("\n");
1451 /* MAP can not handle KEY. */
1453 /* If MAP is the root map of the initial state, it means that
1454 the current input method can not handle KEY. */
1455 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
1457 MDEBUG_PRINT (" unhandled\n");
1461 if (map != ic_info->state->map)
1463 /* If MAP is not the root map... */
1464 /* If MAP has branch actions, perform them. */
1465 if (map->branch_actions)
1467 MDEBUG_PRINT (" branch-actions:");
1468 take_action_list (ic, map->branch_actions);
1470 /* If MAP is still not the root map, shift to the current
1472 if (ic_info->map != ic_info->state->map)
1474 shift_state (ic, ic_info->state->name);
1475 /* If MAP has branch_actions, perform them. */
1476 if (ic_info->map->branch_actions)
1478 MDEBUG_PRINT (" init-actions:");
1479 take_action_list (ic, ic_info->map->branch_actions);
1485 /* MAP is the root map, perform branch actions (if any) or
1486 shift to the initial state. */
1487 if (map->branch_actions)
1489 MDEBUG_PRINT (" branch-actions:");
1490 take_action_list (ic, map->branch_actions);
1494 ((MIMState *) MPLIST_VAL (im_info->states))->name);
1496 MDEBUG_PRINT ("\n");
1502 reset_ic (MInputContext *ic, MSymbol ignore)
1504 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1505 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1507 if (im_info->states)
1508 /* Shift to the initial state. */
1509 shift_state (ic, Mnil);
1511 ic_info->state = NULL;
1512 MLIST_RESET (ic_info);
1513 ic_info->map = ic_info->state ? ic_info->state->map : NULL;
1514 ic_info->state_key_head = ic_info->key_head = 0;
1515 ic_info->key_unhandled = 0;
1516 ic->cursor_pos = ic_info->state_pos = 0;
1517 ic->status = ic_info->state ? ic_info->state->title : NULL;
1519 ic->status = im_info->title;
1520 ic->candidate_list = NULL;
1521 ic->candidate_show = 0;
1522 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1;
1523 if (ic_info->map && ic_info->map->map_actions)
1524 take_action_list (ic, ic_info->map->map_actions);
1528 open_im (MInputMethod *im)
1531 MInputMethodInfo *im_info;
1535 mdb = mdatabase_find (Minput_method, im->language, im->name, Mnil);
1538 plist = mdatabase_load (mdb);
1540 MERROR (MERROR_IM, -1);
1541 MSTRUCT_CALLOC (im_info, MERROR_IM);
1543 result = load_input_method (im->language, im->name, plist, im_info);
1544 M17N_OBJECT_UNREF (plist);
1546 MERROR (MERROR_IM, -1);
1551 close_im (MInputMethod *im)
1553 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1557 M17N_OBJECT_UNREF (im_info->title);
1558 if (im_info->states)
1560 MPLIST_DO (plist, im_info->states)
1562 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1565 M17N_OBJECT_UNREF (state->title);
1567 free_map (state->map);
1570 M17N_OBJECT_UNREF (im_info->states);
1573 if (im_info->macros)
1575 MPLIST_DO (plist, im_info->macros)
1576 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1577 M17N_OBJECT_UNREF (im_info->macros);
1580 if (im_info->externals)
1582 MPLIST_DO (plist, im_info->externals)
1584 MIMExternalModule *external = MPLIST_VAL (plist);
1586 dlclose (external->handle);
1587 M17N_OBJECT_UNREF (external->func_list);
1589 MPLIST_KEY (plist) = Mt;
1591 M17N_OBJECT_UNREF (im_info->externals);
1599 create_ic (MInputContext *ic)
1601 MInputMethod *im = ic->im;
1602 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1603 MInputContextInfo *ic_info;
1606 ic_info = (MInputContextInfo *) ic->info;
1609 MSTRUCT_CALLOC (ic_info, MERROR_IM);
1612 MLIST_INIT1 (ic_info, keys, 8);
1613 ic_info->markers = mplist ();
1614 ic_info->vars = mplist ();
1615 ic_info->preedit_saved = mtext ();
1616 if (im_info->externals)
1618 MPlist *func_args = mplist (), *plist;
1620 mplist_add (func_args, Mt, ic);
1621 MPLIST_DO (plist, im_info->externals)
1623 MIMExternalModule *external = MPLIST_VAL (plist);
1624 MIMExternalFunc func
1625 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
1630 M17N_OBJECT_UNREF (func_args);
1632 reset_ic (ic, Mnil);
1637 destroy_ic (MInputContext *ic)
1639 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1640 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1642 if (im_info->externals)
1644 MPlist *func_args = mplist (), *plist;
1646 mplist_add (func_args, Mt, ic);
1647 MPLIST_DO (plist, im_info->externals)
1649 MIMExternalModule *external = MPLIST_VAL (plist);
1650 MIMExternalFunc func
1651 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
1656 M17N_OBJECT_UNREF (func_args);
1658 MLIST_FREE1 (ic_info, keys);
1659 M17N_OBJECT_UNREF (ic_info->preedit_saved);
1660 M17N_OBJECT_UNREF (ic_info->markers);
1661 M17N_OBJECT_UNREF (ic_info->vars);
1666 /** Handle the input key KEY in the current state and map of IC->info.
1667 If KEY is handled but no text is produced, return 0, otherwise
1673 filter (MInputContext *ic, MSymbol key, void *arg)
1675 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1676 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1679 if (! ic_info->state)
1681 ic_info->key_unhandled = 1;
1684 mtext_reset (ic->produced);
1685 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
1686 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1687 ic_info->key_unhandled = 0;
1689 if (handle_key (ic) < 0)
1691 /* KEY was not handled. Reset the status and break the
1693 reset_ic (ic, Mnil);
1694 /* This forces returning 1. */
1695 ic_info->key_unhandled = 1;
1701 reset_ic (ic, Mnil);
1702 ic_info->key_unhandled = 1;
1705 /* Break the loop if all keys were handled. */
1706 } while (ic_info->key_head < ic_info->used);
1708 /* If the current map is the root of the initial state, we should
1709 produce any preedit text in ic->produced. */
1710 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
1711 && mtext_nchars (ic->preedit) > 0)
1712 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1714 if (mtext_nchars (ic->produced) > 0)
1716 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
1719 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1720 Mlanguage, ic->im->language);
1723 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
1727 /** Return 1 if the last event or key was not handled, otherwise
1730 There is no need of looking up because ic->produced should already
1731 contain the produced text (if any).
1736 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1738 mtext_cat (mt, ic->produced);
1739 mtext_reset (ic->produced);
1740 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
1743 static MPlist *load_im_info_keys;
1746 load_im_info (MSymbol language, MSymbol name, MSymbol key)
1751 if (language == Mnil || name == Mnil)
1752 MERROR (MERROR_IM, NULL);
1754 mdb = mdatabase_find (Minput_method, language, name, Mnil);
1756 MERROR (MERROR_IM, NULL);
1757 mplist_push (load_im_info_keys, key, Mt);
1758 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
1759 mplist_pop (load_im_info_keys);
1764 /* Input method command handler. */
1766 /* List of all (global and local) commands.
1767 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
1768 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
1769 Global commands are storead as (t (t COMMAND ...)) */
1770 static MPlist *command_list;
1772 /* Check if PLIST is a valid command key sequence.
1773 PLIST must be NULL or:
1774 [ symbol:KEY | integer:KEY ] ... */
1777 check_command_keyseq (MPlist *plist)
1781 MPLIST_DO (plist, plist)
1783 if (MPLIST_SYMBOL_P (plist))
1785 else if (MPLIST_INTEGER_P (plist))
1787 int n = MPLIST_INTEGER (plist);
1791 MPLIST_KEY (plist) = Msymbol;
1792 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
1801 get_description_advance (MPlist *plist)
1806 if (! MPLIST_MTEXT_P (plist))
1808 mt = mplist_pop (plist);
1809 pos = mtext_chr (mt, '\n');
1812 MText *detail = mtext_copy (mtext (), 0, mt, pos + 1, mtext_nchars (mt));
1813 mtext_del (mt, pos, mtext_nchars (mt));
1814 mtext_put_prop (mt, 0, pos, Mdetail_text, detail);
1815 M17N_OBJECT_UNREF (detail);
1821 parse_command_list (MPlist *plist, MPlist *global_list)
1823 MPlist *val = mplist ();
1825 /* PLIST ::= (sym:CMD mtext:DESCRIPTION ? (sym:KEY ...) ...) ... */
1826 MPLIST_DO (plist, plist)
1830 MPlist *this_val, *pl, *p;
1832 if (! MPLIST_PLIST_P (plist))
1834 pl = MPLIST_PLIST (plist);
1835 if (! MPLIST_SYMBOL_P (pl))
1837 cmd = MPLIST_SYMBOL (pl);
1838 pl = MPLIST_NEXT (pl);
1839 mt = get_description_advance (pl);
1840 this_val = mplist ();
1842 if (! mt && global_list)
1844 /* Get the description from global_list. */
1845 p = mplist_get (global_list, cmd);
1846 if (p && MPLIST_MTEXT (p))
1848 mt = MPLIST_MTEXT (p);
1849 M17N_OBJECT_REF (mt);
1854 mplist_add (this_val, Mtext, mt);
1855 M17N_OBJECT_UNREF (mt);
1857 /* PL ::= (sym:KEY ...) ... */
1860 if (MPLIST_PLIST_P (pl)
1861 && check_command_keyseq (MPLIST_PLIST (pl)) >= 0)
1862 /* All the elements are valid keys. */
1863 mplist_add (this_val, Mplist, MPLIST_PLIST (pl));
1866 mplist_put (val, cmd, this_val);
1872 get_command_list (MSymbol language, MSymbol name)
1878 language = name = Mt;
1882 MDatabase *mdb = mdatabase_find (msymbol ("input"), M_command,
1885 if (mdb && (plist = mdatabase_load (mdb)))
1887 pl = parse_command_list (plist, NULL);
1888 M17N_OBJECT_UNREF (plist);
1893 mplist_add (plist, Mt, pl);
1894 command_list = mplist ();
1895 mplist_add (command_list, Mt, plist);
1898 per_lang = mplist_get (command_list, language);
1901 plist = mplist_find_by_key (per_lang, name);
1903 return (MPLIST_VAL (plist));
1907 per_lang = mplist ();
1908 mplist_add (command_list, language, per_lang);
1911 /* Now we are sure that we are loading per-im info. */
1912 /* Get the global command list. */
1913 plist = load_im_info (language, name, M_command);
1914 if (! plist || mplist_key (plist) == Mnil)
1918 mplist_add (per_lang, name, plist);
1921 pl = parse_command_list (mplist_value (plist),
1922 mplist_get ((MPlist *) mplist_get (command_list, Mt),
1924 M17N_OBJECT_UNREF (plist);
1925 mplist_put (per_lang, name, pl);
1930 /* Input method variable handler. */
1932 /* List of all variables.
1933 (LANG:(IM-NAME:(VAR ...) ...) ...) ...
1934 VAR is VAR-NAME:(mtext:DESCRIPTION TYPE:VALUE ...)) */
1936 static MPlist *variable_list;
1939 parse_variable_list (MPlist *plist)
1941 MPlist *val = mplist (), *pl, *p;
1943 /* PLIST ::= (sym:VAR mtext:DESCRIPTION TYPE:INIT-VAL ...) ... */
1944 MPLIST_DO (plist, plist)
1950 if (! MPLIST_PLIST_P (plist))
1952 pl = MPLIST_PLIST (plist);
1953 if (! MPLIST_SYMBOL_P (pl))
1955 var = MPLIST_SYMBOL (pl);
1956 pl = MPLIST_NEXT (pl);
1957 mt = get_description_advance (pl);
1958 if (! mt || MPLIST_TAIL_P (pl))
1960 this_val = mplist ();
1961 mplist_add (this_val, Mtext, mt);
1962 M17N_OBJECT_UNREF (mt);
1963 type = MPLIST_KEY (pl);
1964 mplist_add (this_val, type, MPLIST_VAL (pl));
1965 MPLIST_DO (pl, MPLIST_NEXT (pl))
1967 if (type != MPLIST_KEY (pl)
1968 && (type != Minteger || ! MPLIST_PLIST_P (pl)))
1970 if (MPLIST_PLIST_P (pl))
1972 MPLIST_DO (p, MPLIST_PLIST (pl))
1973 if (! MPLIST_INTEGER_P (p))
1975 if (! MPLIST_TAIL_P (p))
1978 mplist_add (this_val, MPLIST_KEY (pl), MPLIST_VAL (pl));
1981 mplist_put (val, var, this_val);
1988 get_variable_list (MSymbol language, MSymbol name)
1993 if (language == Mnil || name == Mnil)
1994 MERROR (MERROR_IM, NULL);
1995 if (! variable_list)
1996 variable_list = mplist ();
1997 per_lang = mplist_get (variable_list, language);
2000 plist = mplist_find_by_key (per_lang, name);
2002 return (MPLIST_VAL (plist));
2006 per_lang = mplist ();
2007 mplist_add (variable_list, language, per_lang);
2009 plist = load_im_info (language, name, M_variable);
2010 if (! plist || mplist_key (plist) == Mnil)
2014 mplist_add (per_lang, name, plist);
2017 pl = parse_variable_list (mplist_value (plist));
2018 M17N_OBJECT_UNREF (plist);
2019 mplist_put (per_lang, name, pl);
2024 input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
2026 MPlist *plist, *pl, *p;
2027 char path[PATH_MAX];
2029 /* Cancel the hook. */
2030 msymbol_put (tag0, M_database_hook, NULL);
2033 mplist_push (load_im_info_keys, M_description, Mt);
2034 MPLIST_DO (plist, mdatabase__dir_list)
2036 char *dirname = (char *) MPLIST_VAL (plist);
2038 DIR *dir = opendir (dirname);
2043 dirlen = strlen (dirname);
2044 strcpy (path, dirname);
2045 while ((dp = readdir (dir)) != NULL)
2047 /* We can't trust dp->d_nameln. */
2048 int len = strlen (dp->d_name);
2051 if (len > 4 && memcmp (dp->d_name + len - 4, ".mim", 4) == 0)
2053 strcpy (path + dirlen, dp->d_name);
2054 fp = fopen (path, "r");
2057 pl = mplist__from_file (fp, load_im_info_keys);
2061 if (MPLIST_PLIST_P (pl))
2063 p = MPLIST_PLIST (pl);
2064 p = MPLIST_NEXT (p);
2065 if (MPLIST_SYMBOL_P (p))
2067 tag1 = MPLIST_VAL (p);
2068 p = MPLIST_NEXT (p);
2069 if (MPLIST_SYMBOL_P (p))
2071 tag2 = MPLIST_VAL (p);
2072 mdatabase_define (tag0, tag1, tag2, tag3,
2077 M17N_OBJECT_UNREF (pl);
2083 mplist_pop (load_im_info_keys);
2087 /* Support functions for mdebug_dump_im. */
2090 dump_im_map (MPlist *map_list, int indent)
2093 MSymbol key = MPLIST_KEY (map_list);
2094 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2096 prefix = (char *) alloca (indent + 1);
2097 memset (prefix, 32, indent);
2098 prefix[indent] = '\0';
2100 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2101 if (map->map_actions)
2102 mdebug_dump_plist (map->map_actions, indent + 2);
2105 MPLIST_DO (map_list, map->submaps)
2107 fprintf (stderr, "\n%s ", prefix);
2108 dump_im_map (map_list, indent + 2);
2111 if (map->branch_actions)
2113 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2114 mdebug_dump_plist (map->branch_actions, indent + 4);
2115 fprintf (stderr, ")");
2117 fprintf (stderr, ")");
2122 dump_im_state (MIMState *state, int indent)
2127 prefix = (char *) alloca (indent + 1);
2128 memset (prefix, 32, indent);
2129 prefix[indent] = '\0';
2131 fprintf (stderr, "(%s", msymbol_name (state->name));
2132 if (state->map->submaps)
2134 MPLIST_DO (map_list, state->map->submaps)
2136 fprintf (stderr, "\n%s ", prefix);
2137 dump_im_map (map_list, indent + 2);
2140 fprintf (stderr, ")");
2149 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2150 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2151 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2152 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2153 char buf[6], buf2[256];
2157 Minput_method = msymbol ("input-method");
2158 msymbol_put (Minput_method, M_database_hook, (void *) input_method_hook);
2159 Minput_driver = msymbol ("input-driver");
2160 Mtitle = msymbol ("title");
2161 Mmacro = msymbol ("macro");
2162 Mmodule = msymbol ("module");
2163 Mmap = msymbol ("map");
2164 Mstate = msymbol ("state");
2165 Minsert = msymbol ("insert");
2166 Mdelete = msymbol ("delete");
2167 Mmove = msymbol ("move");
2168 Mmark = msymbol ("mark");
2169 Mpushback = msymbol ("pushback");
2170 Mundo = msymbol ("undo");
2171 Mcall = msymbol ("call");
2172 Mshift = msymbol ("shift");
2173 Mselect = msymbol ("select");
2174 Mshow = msymbol ("show");
2175 Mhide = msymbol ("hide");
2176 Mset = msymbol ("set");
2177 Madd = msymbol ("add");
2178 Msub = msymbol ("sub");
2179 Mmul = msymbol ("mul");
2180 Mdiv = msymbol ("div");
2181 Mequal = msymbol ("=");
2182 Mless = msymbol ("<");
2183 Mgreater = msymbol (">");
2185 Minput_preedit_start = msymbol ("input-preedit-start");
2186 Minput_preedit_done = msymbol ("input-preedit-done");
2187 Minput_preedit_draw = msymbol ("input-preedit-draw");
2188 Minput_status_start = msymbol ("input-status-start");
2189 Minput_status_done = msymbol ("input-status-done");
2190 Minput_status_draw = msymbol ("input-status-draw");
2191 Minput_candidates_start = msymbol ("input-candidates-start");
2192 Minput_candidates_done = msymbol ("input-candidates-done");
2193 Minput_candidates_draw = msymbol ("input-candidates-draw");
2194 Minput_set_spot = msymbol ("input-set-spot");
2195 Minput_toggle = msymbol ("input-toggle");
2196 Minput_reset = msymbol ("input-reset");
2198 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2199 Mcandidate_index = msymbol (" candidate-index");
2201 Minit = msymbol ("init");
2202 Mfini = msymbol ("fini");
2204 M_key_alias = msymbol (" key-alias");
2205 M_description = msymbol ("description");
2206 M_command = msymbol ("command");
2207 M_variable = msymbol ("variable");
2209 Mdetail_text = msymbol_as_managing_key (" detail-text");
2211 load_im_info_keys = mplist ();
2212 plist = mplist_add (load_im_info_keys, Mmap, Mnil);
2213 plist = mplist_add (plist, Mstate, Mnil);
2214 plist = mplist_add (plist, Mmacro, Mnil);
2215 plist = mplist_add (plist, Mmodule, Mnil);
2220 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2222 one_char_symbol[i] = msymbol (buf);
2224 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (key_names[i]));
2226 for (buf[2] = i; i < 127; i++, buf[2]++)
2227 one_char_symbol[i] = msymbol (buf + 2);
2228 one_char_symbol[i++] = msymbol ("Delete");
2234 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2236 one_char_symbol[i] = msymbol (buf);
2237 if (key_names[i - 128])
2239 strcpy (buf2 + 2, key_names[i - 128]);
2240 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2243 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2244 one_char_symbol[i] = msymbol (buf + 2);
2245 one_char_symbol[i] = msymbol ("M-Delete");
2247 command_list = variable_list = NULL;
2249 minput_default_driver.open_im = open_im;
2250 minput_default_driver.close_im = close_im;
2251 minput_default_driver.create_ic = create_ic;
2252 minput_default_driver.destroy_ic = destroy_ic;
2253 minput_default_driver.filter = filter;
2254 minput_default_driver.lookup = lookup;
2255 minput_default_driver.callback_list = mplist ();
2256 mplist_put (minput_default_driver.callback_list, Minput_reset,
2258 minput_driver = &minput_default_driver;
2265 MPlist *par_lang, *par_im, *p;
2269 MPLIST_DO (par_lang, command_list)
2271 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2273 MPLIST_DO (p, MPLIST_VAL (par_im))
2274 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2275 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2277 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2279 M17N_OBJECT_UNREF (command_list);
2280 command_list = NULL;
2284 MPLIST_DO (par_lang, variable_list)
2286 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2288 MPLIST_DO (p, MPLIST_VAL (par_im))
2289 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2290 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2292 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2294 M17N_OBJECT_UNREF (variable_list);
2295 variable_list = NULL;
2298 if (minput_default_driver.callback_list)
2300 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2301 minput_default_driver.callback_list = NULL;
2303 if (minput_driver->callback_list)
2305 M17N_OBJECT_UNREF (minput_driver->callback_list);
2306 minput_driver->callback_list = NULL;
2309 M17N_OBJECT_UNREF (load_im_info_keys);
2313 minput__callback (MInputContext *ic, MSymbol command)
2315 if (ic->im->driver.callback_list)
2317 MInputCallbackFunc func
2318 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2322 (func) (ic, command);
2327 minput__char_to_key (int c)
2329 if (c < 0 || c >= 0x100)
2332 return one_char_symbol[c];
2336 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2341 /*** @addtogroup m17nInputMethod */
2346 @name Variables: Predefined symbols for callback commands.
2348 These are the predefined symbols that are used as the @c COMMAND
2349 argument of callback functions of an input method driver (see
2350 #MInputDriver::callback_list ). */
2352 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2354 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2355 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2360 MSymbol Minput_preedit_start;
2361 MSymbol Minput_preedit_done;
2362 MSymbol Minput_preedit_draw;
2363 MSymbol Minput_status_start;
2364 MSymbol Minput_status_done;
2365 MSymbol Minput_status_draw;
2366 MSymbol Minput_candidates_start;
2367 MSymbol Minput_candidates_done;
2368 MSymbol Minput_candidates_draw;
2369 MSymbol Minput_set_spot;
2370 MSymbol Minput_toggle;
2371 MSymbol Minput_reset;
2376 @brief The default driver for internal input methods.
2378 The variable #minput_default_driver is the default driver for
2379 internal input methods.
2381 The member MInputDriver::open_im () searches the m17n database for
2382 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2383 $NAME\> and loads it.
2385 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2386 programmers responsibility to set it to a plist of proper callback
2387 functions. Otherwise, no feedback information (e.g. preedit text)
2388 can be shown to users.
2390 The macro M17N_INIT () sets the variable #minput_driver to the
2391 pointer to this driver so that all internal input methods use it.
2393 Therefore, unless @c minput_driver is set differently, the driver
2394 dependent arguments $ARG of the functions whose name begin with
2395 "minput_" are all ignored. */
2398 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2400 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2402 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2403 \< #Minput_method, $LANGUAGE, $NAME\>
2404 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2406 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2407 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2408 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2409 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2411 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2412 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2414 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2415 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2417 MInputDriver minput_default_driver;
2421 @brief The driver for internal input methods.
2423 The variable #minput_driver is a pointer to the input method
2424 driver that is used by internal input methods. The macro
2425 M17N_INIT () initializes it to a pointer to #minput_default_driver
2426 if <m17n<EM></EM>.h> is included. */
2428 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
2430 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
2431 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
2432 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
2433 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
2435 MInputDriver *minput_driver;
2437 MSymbol Minput_driver;
2442 @brief Open an input method.
2444 The minput_open_im () function opens an input method that matches
2445 language $LANGUAGE and name $NAME, and returns a pointer to the
2446 input method object newly allocated.
2448 This function at first decides an driver for the input method as
2451 If $LANGUAGE is not #Mnil, the driver pointed by the variable
2452 #minput_driver is used.
2454 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
2455 driver pointed to by the property value is used to open the input
2456 method. If $NAME has no such property, @c NULL is returned.
2458 Then, the member MInputDriver::open_im () of the driver is
2461 $ARG is set in the member @c arg of the structure MInputMethod so
2462 that the driver can refer to it. */
2465 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
2467 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
2468 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2470 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
2472 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
2473 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
2475 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
2476 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
2477 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2479 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
2481 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
2483 @latexonly \IPAlabel{minput_open} @endlatexonly
2488 minput_open_im (MSymbol language, MSymbol name, void *arg)
2491 MInputDriver *driver;
2494 driver = minput_driver;
2497 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
2499 MERROR (MERROR_IM, NULL);
2502 MSTRUCT_CALLOC (im, MERROR_IM);
2503 im->language = language;
2506 im->driver = *driver;
2507 if ((*im->driver.open_im) (im) < 0)
2518 @brief Close an input method.
2520 The minput_close_im () function closes the input method $IM, which
2521 must have been created by minput_open_im (). */
2524 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
2526 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
2527 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
2530 minput_close_im (MInputMethod *im)
2532 (*im->driver.close_im) (im);
2539 @brief Create an input context.
2541 The minput_create_ic () function creates an input context object
2542 associated with input method $IM, and calls callback functions
2543 corresponding to #Minput_preedit_start, #Minput_status_start, and
2544 #Minput_status_draw in this order.
2548 If an input context is successfully created, minput_create_ic ()
2549 returns a pointer to it. Otherwise it returns @c NULL. */
2552 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
2554 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
2555 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
2556 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
2557 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2561 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
2562 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2566 minput_create_ic (MInputMethod *im, void *arg)
2570 MSTRUCT_CALLOC (ic, MERROR_IM);
2573 ic->preedit = mtext ();
2574 ic->candidate_list = NULL;
2575 ic->produced = mtext ();
2576 ic->spot.x = ic->spot.y = 0;
2578 ic->plist = mplist ();
2579 if ((*im->driver.create_ic) (ic) < 0)
2581 M17N_OBJECT_UNREF (ic->preedit);
2582 M17N_OBJECT_UNREF (ic->produced);
2583 M17N_OBJECT_UNREF (ic->plist);
2588 if (im->driver.callback_list)
2590 minput__callback (ic, Minput_preedit_start);
2591 minput__callback (ic, Minput_status_start);
2592 minput__callback (ic, Minput_status_draw);
2601 @brief Destroy an input context.
2603 The minput_destroy_ic () function destroys the input context $IC,
2604 which must have been created by minput_create_ic (). It calls
2605 callback functions corresponding to #Minput_preedit_done,
2606 #Minput_status_done, and #Minput_candidates_done in this order. */
2609 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
2611 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
2612 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
2613 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
2614 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
2615 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2619 minput_destroy_ic (MInputContext *ic)
2621 if (ic->im->driver.callback_list)
2623 minput__callback (ic, Minput_preedit_done);
2624 minput__callback (ic, Minput_status_done);
2625 minput__callback (ic, Minput_candidates_done);
2627 (*ic->im->driver.destroy_ic) (ic);
2628 M17N_OBJECT_UNREF (ic->preedit);
2629 M17N_OBJECT_UNREF (ic->produced);
2630 M17N_OBJECT_UNREF (ic->plist);
2637 @brief Filter an input key.
2639 The minput_filter () function filters input key $KEY according to
2640 input context $IC, and calls callback functions corresponding to
2641 #Minput_preedit_draw, #Minput_status_draw, and
2642 #Minput_candidates_draw if the preedit text, the status, and the
2643 current candidate are changed respectively.
2646 If $KEY is filtered out, this function returns 1. In that case,
2647 the caller should discard the key. Otherwise, it returns 0, and
2648 the caller should handle the key, for instance, by calling the
2649 function minput_lookup () with the same key. */
2652 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
2654 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2655 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
2656 #Minput_preedit_draw, #Minput_status_draw,
2657 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
2660 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
2661 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
2662 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
2663 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
2665 @latexonly \IPAlabel{minput_filter} @endlatexonly
2669 minput_filter (MInputContext *ic, MSymbol key, void *arg)
2676 ret = (*ic->im->driver.filter) (ic, key, arg);
2678 if (ic->im->driver.callback_list)
2680 if (ic->preedit_changed)
2681 minput__callback (ic, Minput_preedit_draw);
2682 if (ic->status_changed)
2683 minput__callback (ic, Minput_status_draw);
2684 if (ic->candidates_changed)
2685 minput__callback (ic, Minput_candidates_draw);
2694 @brief Look up a text produced in the input context.
2696 The minput_lookup () function looks up a text in the input context
2697 $IC. $KEY must be the same one provided to the previous call of
2700 If a text was produced by the input method, it is concatenated
2703 This function calls #MInputDriver::lookup .
2706 If $KEY was correctly handled by the input method, this function
2707 returns 0. Otherwise, returns -1, even in that case, some text
2708 may be produced in $MT. */
2711 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
2713 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
2714 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2716 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
2719 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
2722 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
2723 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
2724 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
2726 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
2729 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2731 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
2736 @brief Set the spot of the input context.
2738 The minput_set_spot () function set the spot of input context $IC
2739 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
2740 The semantics of these values depend on the input method driver.
2742 For instance, a driver designed to work in a CUI environment may
2743 use $X and $Y as column and row numbers, and ignore $ASCENT and
2744 $DESCENT . A driver designed to work in a window system may
2745 interpret $X and $Y as pixel offsets relative to the origin of the
2746 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
2747 descent pixels of the line at ($X . $Y ).
2749 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
2751 $MT and $POS is the M-text and the character position at the spot.
2752 $MT may be @c NULL, in which case, the input method cannot get
2753 information about the text around the spot. */
2756 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
2758 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
2759 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
2760 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
2762 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
2763 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
2764 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
2765 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
2766 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
2767 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
2769 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
2771 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
2772 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
2776 minput_set_spot (MInputContext *ic, int x, int y,
2777 int ascent, int descent, int fontsize,
2782 ic->spot.ascent = ascent;
2783 ic->spot.descent = descent;
2784 ic->spot.fontsize = fontsize;
2787 if (ic->im->driver.callback_list)
2788 minput__callback (ic, Minput_set_spot);
2793 @brief Toggle input method.
2795 The minput_toggle () function toggles the input method associated
2796 with input context $IC. */
2798 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
2800 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2801 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
2805 minput_toggle (MInputContext *ic)
2807 if (ic->im->driver.callback_list)
2808 minput__callback (ic, Minput_toggle);
2809 ic->active = ! ic->active;
2813 @brief Reset an input context.
2815 The minput_reset_ic () function resets input context $IC by
2816 calling a callback function corresponding to #Minput_reset. It
2817 actually shifts the state to the initial one, and thus the current
2818 preediting text (if any) is committed. If necessary, a program
2819 can extract that committed text by calling minput_lookup () just
2820 after the call of minput_reset_ic (). In that case, the arguments
2821 @c KEY and @c ARG of minput_lookup () are ignored. */
2823 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
2825 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
2826 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2827 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
2828 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
2829 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
2830 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
2833 minput_reset_ic (MInputContext *ic)
2835 if (ic->im->driver.callback_list)
2836 minput__callback (ic, Minput_reset);
2841 @brief Key of a text property for detailed description.
2843 The symbol #Mdetail_text is a managing key usually used for a
2844 text property whose value is an M-text that contains detailed
2847 @brief ¾ÜºÙÀâÌÀÍѥƥ¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼.
2849 ¥·¥ó¥Ü¥ë #Mdetail_text ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ê¡¢Ä̾ï¾ÜºÙ¤ÊÀâÌÀ¤ò´Þ¤à
2850 M-text ¤òÃͤȤ·¤Æ»ý¤Ä¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ËÍѤ¤¤é¤ì¤ë¡£
2852 MSymbol Mdetail_text;
2855 @brief Get description text of an input method.
2857 The minput_get_description () function returns an M-text that
2858 briefly describes the input method specified by $LANGUAGE and
2859 $NAME. The returned M-text may have a text property, from its
2860 beginning to end, #Mdetail_text whose value is an M-text
2861 describing the input method in more detail.
2864 If the specified input method has a description text, a pointer to
2865 #MText is returned. A caller have to free it by m17n_object_unref ().
2866 If the input method does not have a description text, @c NULL is
2869 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
2871 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME
2872 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£ÊÖ¤µ¤ì¤ë M-text
2873 ¤Ë¤Ï¡¢¤½¤ÎÁ´ÂΤËÂФ·¤Æ #Mdetail_text
2874 ¤È¤¤¤¦¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬Éղ䵤ì¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ê¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¤µ¤é¤Ë¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
2878 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
2879 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
2880 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
2883 minput_get_description (MSymbol language, MSymbol name)
2885 MPlist *plist = load_im_info (language, name, M_description);
2891 if (! MPLIST_PLIST_P (plist))
2893 M17N_OBJECT_UNREF (plist);
2896 pl = MPLIST_PLIST (plist);
2897 while (! MPLIST_TAIL_P (pl) && ! MPLIST_MTEXT_P (pl))
2898 pl = MPLIST_NEXT (pl);
2899 if (MPLIST_MTEXT_P (pl))
2900 mt = get_description_advance (pl);
2901 M17N_OBJECT_UNREF (plist);
2906 @brief Get information about input method commands.
2908 The minput_get_commands () function returns information about
2909 input method commands of the input method specified by $LANGUAGE
2910 and $NAME. An input method command is a pseudo key event to which
2911 one or more actual input key sequences are assigned.
2913 There are two kinds of commands, global and local. Global
2914 commands are used by multiple input methods for the same purpose,
2915 and have global key assignments. Local commands are used only in
2916 a specific input method, and have only local key assignments.
2918 Each input method may locally change key assignments for global
2919 commands. A global key assignment for a global command are
2920 effective only when the current input method does not have local
2921 key assignments for that command.
2923 If $NAME is #Mnil, information about global commands is returned.
2924 In this case $LANGUAGE is ignored.
2926 If $NAME is not #Mnil, information about those commands that have
2927 local key assignments in the input method specified by $LANGUAGE
2928 and $NAME is returned.
2931 If no input method commands are found, this function returns @c NULL.
2933 Otherwise, a pointer to a plist is returned. The key of each
2934 element in the plist is a symbol representing a command, and the
2935 value is a plist of the form COMMAND-INFO described below.
2937 The first element of COMMAND-INFO has the key #Mtext, and the
2938 value is an M-text describing the command briefly. This M-text
2939 may have a text property whose key is #Mdetail_text and whose
2940 value is an M-text describing the command in more detail.
2942 If there are no more elements, that means no key sequences are
2943 assigned to the command. Otherwise, each of the remaining
2944 elements has the key #Mplist, and the value is a plist whose keys are
2945 #Msymbol and values are symbols representing input keys, which are
2946 currently assigned to the command.
2948 As the returned plist is kept in the library, the caller must not
2949 modify nor free it. */
2951 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
2953 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME
2954 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2955 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
2957 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£
2958 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ÇÍѤ¤¤é¤ì¤ë¡£
2959 ¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
2961 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
2962 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ß͸ú¤Ç¤¢¤ë¡£
2964 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2965 ¤³¤Î¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
2967 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME
2968 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2971 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
2973 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2974 ¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î
2975 COMMAND-INFO ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
2977 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext
2978 ¤ò¡¢ÃͤȤ·¤Æ¤½¤Î¥³¥Þ¥ó¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤ò»ý¤Ä¡£¤³¤Î M-text
2980 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤Î¥³¥Þ¥ó¥É¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
2983 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
2984 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ#Mplist
2985 ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£
2986 ¤³¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol
2987 ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2989 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
2992 minput_get_commands (MSymbol language, MSymbol name)
2994 MPlist *plist = get_command_list (language, name);
2996 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3000 @brief Assign a key sequence to an input method command.
3002 The minput_assign_command_keys () function assigns input key
3003 sequence $KEYSEQ to input method command $COMMAND for the input
3004 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3005 key sequence is assigned globally no matter what $LANGUAGE is.
3006 Otherwise the key sequence is assigned locally.
3008 Each element of $KEYSEQ must have the key $Msymbol and the value
3009 must be a symbol representing an input key.
3011 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3012 globally or locally.
3014 This assignment gets effective in a newly opened input method.
3017 If the operation was successful, 0 is returned. Otherwise -1 is
3018 returned, and #merror_code is set to #MERROR_IM. */
3020 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3022 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3023 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND
3024 ¤ËÂФ·¤Æ¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil
3025 ¤Ê¤é¤Ð¡¢$LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
3026 ¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3028 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol
3029 ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3031 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£
3032 ¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3034 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤Ë¤Ê¤ë¡£
3037 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3038 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3041 minput_assign_command_keys (MSymbol language, MSymbol name,
3042 MSymbol command, MPlist *keyseq)
3044 MPlist *plist, *pl, *p;
3046 if (check_command_keyseq (keyseq) < 0
3047 || ! (plist = get_command_list (language, name)))
3048 MERROR (MERROR_IM, -1);
3049 pl = mplist_get (plist, command);
3052 pl = MPLIST_NEXT (pl);
3054 while ((p = mplist_pop (pl)))
3055 M17N_OBJECT_UNREF (p);
3058 keyseq = mplist_copy (keyseq);
3059 mplist_push (pl, Mplist, keyseq);
3060 M17N_OBJECT_UNREF (keyseq);
3066 MERROR (MERROR_IM, -1);
3069 pl = get_command_list (Mnil, Mnil); /* Get global commands. */
3070 pl = mplist_get (pl, command);
3072 MERROR (MERROR_IM, -1);
3074 mplist_add (p, Mtext, mplist_value (pl));
3075 keyseq = mplist_copy (keyseq);
3076 mplist_add (p, Mplist, keyseq);
3077 M17N_OBJECT_UNREF (keyseq);
3078 mplist_push (plist, command, p);
3084 @brief Get a list of variables of an input method.
3086 The minput_get_variables () function returns a plist (#MPlist) of
3087 variables used to control the behavior of the input method
3088 specified by $LANGUAGE and $NAME. The key of an element of the
3089 plist is a symbol representing a variable, and the value is a
3090 plist of the form VAR-INFO (described below) that carries the
3091 information about the variable.
3093 The first element of VAR-INFO has the key #Mtext, and the value is
3094 an M-text describing the variable briefly. This M-text may have a
3095 text property #Mdetail_text whose value is an M-text describing
3096 the variable in more detail.
3098 The second element of VAR-INFO is for the value of the variable.
3099 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3100 integer, a symbol, or an M-text, respectively. The variable is
3101 set to this value when an input context is created for the input
3104 If there are no more elements, the variable can take any value
3105 that matches with the above type. Otherwise, the remaining
3106 elements of VAR-INFO are to specify valid values of the variable.
3108 If the type of the variable is integer, the following elements
3109 have the key #Minteger or #Mplist. If it is #Minteger, the value
3110 is a valid integer value. If it is #Mplist, the value is a plist
3111 of two of elements. Both of them have the key #Minteger, and
3112 values are the minimum and maximum bounds of the valid value
3115 If the type of the variable is symbol or M-text, the following
3116 elements of the plist have the key #Msymbol or #Mtext,
3117 respectively, and the value must be a valid one.
3119 For instance, suppose an input method has the variables:
3121 @li name:intvar, description: "value is an integer",
3122 initial value:0, value-range:0..3,10,20
3124 @li name:symvar, description: "value is a symbol",
3125 initial value:nil, value-range:a, b, c, nil
3127 @li name:txtvar, description: "value is an M-text",
3128 initial value:empty text, no value-range (i.e. any text)
3130 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3131 a value, and '(...)' means a plist):
3134 plist:(intvar:(mtext:'value is an integer'
3136 plist:(integer:0 integer:3)
3139 symvar:(mtext:"value is a symbol"
3145 txtvar:(mtext:"value is an M-text"
3150 If the input method uses any variables, a pointer to #MPlist is
3151 returned. As the plist is kept in the library, a caller must not
3152 modify nor free it. If the input method does not use any
3153 variable, @c NULL is returned. */
3155 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3157 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3158 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3159 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3160 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3161 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3163 VAR-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext ¤ò¡¢ÃͤȤ·¤Æ¤½¤ÎÊÑ¿ô¤ò´Êñ¤ËÀâÌÀ¤¹¤ë
3164 M-text ¤ò»ý¤Ä¡£¤³¤Î M-text ¤Ï¡¢#Mdetail_text
3165 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤ÎÊÑ¿ô¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3168 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3169 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3170 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3172 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3173 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3175 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3176 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3177 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3178 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3180 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3181 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3183 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3185 @li name:intvar, ÀâÌÀ:"value is an integer",
3186 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3188 @li name:symvar, ÀâÌÀ:"value is a symbol",
3189 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3191 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3192 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3194 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3195 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3198 plist:(intvar:(mtext:"value is an integer"
3200 plist:(integer:0 integer:3)
3203 symvar:(mtext:"value is a symbol"
3209 txtvar:(mtext:"value is an M-text"
3214 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3215 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3216 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3219 minput_get_variables (MSymbol language, MSymbol name)
3221 MPlist *plist = get_variable_list (language, name);
3223 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3227 @brief Set the initial value of an input method variable.
3229 The minput_set_variable () function sets the initial value of
3230 input method variable $VARIABLE to $VALUE for the input method
3231 specified by $LANGUAGE and $NAME.
3233 By default, the initial value is 0.
3235 This setting gets effective in a newly opened input method.
3238 If the operation was successful, 0 is returned. Otherwise -1 is
3239 returned, and #merror_code is set to #MERROR_IM. */
3241 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3243 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3244 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3245 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3247 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3249 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3252 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3253 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3256 minput_set_variable (MSymbol language, MSymbol name,
3257 MSymbol variable, void *value)
3259 MPlist *plist, *val_element, *range_element;
3262 if (language == Mnil || name == Mnil)
3263 MERROR (MERROR_IM, -1);
3264 plist = get_variable_list (language, name);
3266 MERROR (MERROR_IM, -1);
3267 plist = (MPlist *) mplist_get (plist, variable);
3269 MERROR (MERROR_IM, -1);
3270 val_element = MPLIST_NEXT (plist);
3271 type = MPLIST_KEY (val_element);
3272 range_element = MPLIST_NEXT (val_element);
3274 if (! MPLIST_TAIL_P (range_element))
3276 if (type == Minteger)
3278 int val = (int) value, this_val;
3280 MPLIST_DO (plist, range_element)
3282 this_val = (int) MPLIST_VAL (plist);
3283 if (MPLIST_PLIST_P (plist))
3285 int min_bound, max_bound;
3286 MPlist *pl = MPLIST_PLIST (plist);
3288 min_bound = (int) MPLIST_VAL (pl);
3289 pl = MPLIST_NEXT (pl);
3290 max_bound = (int) MPLIST_VAL (pl);
3291 if (val >= min_bound && val <= max_bound)
3294 else if (val == this_val)
3297 if (MPLIST_TAIL_P (plist))
3298 MERROR (MERROR_IM, -1);
3300 else if (type == Msymbol)
3302 MPLIST_DO (plist, range_element)
3303 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3305 if (MPLIST_TAIL_P (plist))
3306 MERROR (MERROR_IM, -1);
3308 else /* type == Mtext */
3310 MPLIST_DO (plist, range_element)
3311 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3313 if (MPLIST_TAIL_P (plist))
3314 MERROR (MERROR_IM, -1);
3315 M17N_OBJECT_REF (value);
3319 mplist_set (val_element, type, value);
3325 /*** @addtogroup m17nDebug */
3331 @brief Dump an input method.
3333 The mdebug_dump_im () function prints the input method $IM in a
3334 human readable way to the stderr. $INDENT specifies how many
3335 columns to indent the lines but the first one.
3338 This function returns $IM. */
3340 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3342 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3343 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3346 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3349 mdebug_dump_im (MInputMethod *im, int indent)
3351 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3354 prefix = (char *) alloca (indent + 1);
3355 memset (prefix, 32, indent);
3356 prefix[indent] = '\0';
3358 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3359 msymbol_name (im->name));
3360 mdebug_dump_mtext (im_info->title, 0, 0);
3361 if (im->name != Mnil)
3365 MPLIST_DO (state, im_info->states)
3367 fprintf (stderr, "\n%s ", prefix);
3368 dump_im_state (MPLIST_VAL (state), indent + 2);
3371 fprintf (stderr, ")");