1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides a input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and the body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those driver utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provides an input method that is not only for a specific language.
44 The database uses @c Mt as LANGUAGE of such an input method.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer have to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and the body is
56 defined in an external resources (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤÏm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë
95 <Minput_method, LANGUAGE, NAME>
96 ¤È¤¤¤¦¥¿¥°¤òÉÕ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£
97 ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç¤Ï
98 CUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ¤¤¤ë¡£
99 ¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍøÍѤ¹¤ë¡£
100 m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄêµÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢
101 ¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
103 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£
104 @c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢
105 ÆþÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
106 ¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤ÎÀâÌÀ¤ò»²¾È¡£
108 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
110 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£
111 ¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê¤É¡£)
112 ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver
113 ¤ò¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
114 ¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â
115 @c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö¤¬¤Ç¤¤ë¡£
117 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot
118 ¤ÎÆþÎÏ¥¹¥¿¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
119 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý¤·¤Æ¤¤¤ë¡£
120 ¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
126 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
128 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
129 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
130 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
131 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
135 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
136 /*** @addtogroup m17nInternal
141 #include <sys/types.h>
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)
856 memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
857 sizeof (int) * (ic_info->used - ic_info->state_key_head));
858 ic_info->used -= ic_info->state_key_head;
859 ic_info->state_key_head = ic_info->key_head = 0;
861 mtext_cpy (ic_info->preedit_saved, ic->preedit);
862 ic_info->state_pos = ic->cursor_pos;
863 ic->status = state->title;
865 ic->status = im_info->title;
866 ic->status_changed = 1;
867 if (ic_info->key_head == ic_info->used
868 && ic_info->map == ic_info->state->map
869 && ic_info->map->map_actions)
871 MDEBUG_PRINT (" init-actions:");
872 take_action_list (ic, ic_info->map->map_actions);
876 /* Find a candidate group that contains a candidate number INDEX from
877 PLIST. Set START_INDEX to the first candidate number of the group,
878 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
879 candidate group number if they are non-NULL. If INDEX is -1, find
880 the last candidate group. */
883 find_candidates_group (MPlist *plist, int index,
884 int *start_index, int *end_index, int *group_index)
886 int i = 0, gidx = 0, len;
888 MPLIST_DO (plist, plist)
890 if (MPLIST_MTEXT_P (plist))
891 len = mtext_nchars (MPLIST_MTEXT (plist));
893 len = mplist_length (MPLIST_PLIST (plist));
894 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
900 *end_index = i + len;
912 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
914 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
916 int nchars = mt ? mtext_nchars (mt) : 1;
919 mtext_ins (ic->preedit, pos, mt);
921 mtext_ins_char (ic->preedit, pos, c, 1);
922 MPLIST_DO (markers, ic_info->markers)
923 if (MPLIST_INTEGER (markers) > pos)
924 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
925 if (ic->cursor_pos >= pos)
926 ic->cursor_pos += nchars;
927 ic->preedit_changed = 1;
932 preedit_delete (MInputContext *ic, int from, int to)
934 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
937 mtext_del (ic->preedit, from, to);
938 MPLIST_DO (markers, ic_info->markers)
940 if (MPLIST_INTEGER (markers) > to)
942 = (void *) (MPLIST_INTEGER (markers) - (to - from));
943 else if (MPLIST_INTEGER (markers) > from);
944 MPLIST_VAL (markers) = (void *) from;
946 if (ic->cursor_pos >= to)
947 ic->cursor_pos -= to - from;
948 else if (ic->cursor_pos > from)
949 ic->cursor_pos = from;
950 ic->preedit_changed = 1;
955 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
957 int code = marker_code (sym);
959 if (mt && (code == '[' || code == ']'))
963 if (code == '[' && current > 0)
965 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
969 else if (code == ']' && current < mtext_nchars (mt))
971 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
977 return (code == '<' ? 0
978 : code == '>' ? limit
979 : code == '-' ? current - 1
980 : code == '+' ? current + 1
981 : code == '=' ? current
982 : code - '0' > limit ? limit
986 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
990 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
992 int from = mtext_property_start (prop);
993 int to = mtext_property_end (prop);
995 MPlist *candidate_list = mtext_property_value (prop);
996 MPlist *group = find_candidates_group (candidate_list, idx, &start,
998 int ingroup_index = idx - start;
1001 preedit_delete (ic, from, to);
1002 if (MPLIST_MTEXT_P (group))
1004 mt = MPLIST_MTEXT (group);
1005 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1013 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1014 i++, plist = MPLIST_NEXT (plist));
1015 mt = MPLIST_MTEXT (plist);
1016 preedit_insert (ic, from, mt, 0);
1017 to = from + mtext_nchars (mt);
1019 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1020 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1021 ic->cursor_pos = to;
1026 take_action_list (MInputContext *ic, MPlist *action_list)
1028 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1029 MPlist *candidate_list = ic->candidate_list;
1030 int candidate_index = ic->candidate_index;
1031 int candidate_show = ic->candidate_show;
1032 MTextProperty *prop;
1034 MPLIST_DO (action_list, action_list)
1040 if (MPLIST_MTEXT_P (action_list)
1041 || MPLIST_INTEGER_P (action_list))
1042 name = Minsert, args = action_list;
1043 else if (MPLIST_PLIST_P (action_list)
1044 && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list))
1045 || MPLIST_PLIST_P (MPLIST_PLIST (action_list))))
1046 name = Minsert, args = action_list;
1049 action = MPLIST_PLIST (action_list);
1050 name = MPLIST_SYMBOL (action);
1051 args = MPLIST_NEXT (action);
1054 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1055 if (name == Minsert)
1057 if (MPLIST_MTEXT_P (args))
1058 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1059 else if (MPLIST_INTEGER_P (args))
1060 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1061 else if (MPLIST_SYMBOL_P (args))
1063 int c = integer_value (ic, args);
1065 if (c >= 0 && c <= MCHAR_MAX)
1066 preedit_insert (ic, ic->cursor_pos, NULL, c);
1073 args = MPLIST_PLIST (args);
1074 if (MPLIST_MTEXT_P (args))
1076 preedit_insert (ic, ic->cursor_pos, NULL,
1077 mtext_ref_char (MPLIST_MTEXT (args), 0));
1082 mt = MPLIST_MTEXT (MPLIST_PLIST (args));
1083 preedit_insert (ic, ic->cursor_pos, mt, 0);
1084 len = mtext_nchars (mt);
1086 mtext_put_prop (ic->preedit,
1087 ic->cursor_pos - len, ic->cursor_pos,
1088 Mcandidate_list, args);
1089 mtext_put_prop (ic->preedit,
1090 ic->cursor_pos - len, ic->cursor_pos,
1091 Mcandidate_index, (void *) 0);
1094 else if (name == Mselect)
1097 int code, idx, gindex;
1098 int pos = ic->cursor_pos;
1102 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1105 if (MPLIST_SYMBOL_P (args))
1107 code = marker_code (MPLIST_SYMBOL (args));
1113 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1114 group = find_candidates_group (mtext_property_value (prop), idx,
1115 &start, &end, &gindex);
1117 if (code != '[' && code != ']')
1121 ? new_index (NULL, ic->candidate_index - start,
1122 end - start - 1, MPLIST_SYMBOL (args),
1124 : MPLIST_INTEGER (args)));
1127 find_candidates_group (mtext_property_value (prop), -1,
1132 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1137 int ingroup_index = idx - start;
1140 group = mtext_property_value (prop);
1141 len = mplist_length (group);
1154 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1155 idx += (MPLIST_MTEXT_P (group)
1156 ? mtext_nchars (MPLIST_MTEXT (group))
1157 : mplist_length (MPLIST_PLIST (group)));
1158 len = (MPLIST_MTEXT_P (group)
1159 ? mtext_nchars (MPLIST_MTEXT (group))
1160 : mplist_length (MPLIST_PLIST (group)));
1161 if (ingroup_index >= len)
1162 ingroup_index = len - 1;
1163 idx += ingroup_index;
1165 update_candidate (ic, prop, idx);
1167 else if (name == Mshow)
1168 ic->candidate_show = 1;
1169 else if (name == Mhide)
1170 ic->candidate_show = 0;
1171 else if (name == Mdelete)
1173 int len = mtext_nchars (ic->preedit);
1174 int to = (MPLIST_SYMBOL_P (args)
1175 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1177 : MPLIST_INTEGER (args));
1183 if (to < ic->cursor_pos)
1184 preedit_delete (ic, to, ic->cursor_pos);
1185 else if (to > ic->cursor_pos)
1186 preedit_delete (ic, ic->cursor_pos, to);
1188 else if (name == Mmove)
1190 int len = mtext_nchars (ic->preedit);
1192 = (MPLIST_SYMBOL_P (args)
1193 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1195 : MPLIST_INTEGER (args));
1201 if (pos != ic->cursor_pos)
1203 ic->cursor_pos = pos;
1204 ic->preedit_changed = 1;
1207 else if (name == Mmark)
1209 int code = marker_code (MPLIST_SYMBOL (args));
1212 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1213 (void *) ic->cursor_pos);
1215 else if (name == Mpushback)
1217 int num = MPLIST_INTEGER (args);
1220 ic_info->key_head -= num;
1222 ic_info->key_head = num;
1223 if (ic_info->key_head > ic_info->used)
1224 ic_info->key_head = ic_info->used;
1226 else if (name == Mcall)
1228 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1229 MIMExternalFunc func = NULL;
1230 MSymbol module, func_name;
1231 MPlist *func_args, *val;
1234 module = MPLIST_SYMBOL (args);
1235 args = MPLIST_NEXT (args);
1236 func_name = MPLIST_SYMBOL (args);
1238 if (im_info->externals)
1240 MIMExternalModule *external
1241 = (MIMExternalModule *) mplist_get (im_info->externals,
1244 func = (MIMExternalFunc) mplist_get (external->func_list,
1249 func_args = mplist ();
1250 mplist_add (func_args, Mt, ic);
1251 MPLIST_DO (args, MPLIST_NEXT (args))
1255 if (MPLIST_KEY (args) == Msymbol
1256 && MPLIST_KEY (args) != Mnil
1257 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1259 code = new_index (ic, ic->cursor_pos,
1260 mtext_nchars (ic->preedit),
1261 MPLIST_SYMBOL (args), ic->preedit);
1262 mplist_add (func_args, Minteger, (void *) code);
1265 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1267 val = (func) (func_args);
1268 M17N_OBJECT_UNREF (func_args);
1269 if (val && ! MPLIST_TAIL_P (val))
1270 ret = take_action_list (ic, val);
1271 M17N_OBJECT_UNREF (val);
1275 else if (name == Mshift)
1277 shift_state (ic, MPLIST_SYMBOL (args));
1279 else if (name == Mundo)
1281 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1284 mtext_reset (ic->preedit);
1285 mtext_reset (ic_info->preedit_saved);
1286 ic->cursor_pos = ic_info->state_pos = 0;
1287 ic_info->state_key_head = ic_info->key_head = 0;
1289 if (ic_info->used < 0)
1294 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1299 else if (name == Mset || name == Madd || name == Msub
1300 || name == Mmul || name == Mdiv)
1302 MSymbol sym = MPLIST_SYMBOL (args);
1303 int val1 = (int) mplist_get (ic_info->vars, sym), val2;
1305 args = MPLIST_NEXT (args);
1306 val2 = integer_value (ic, args);
1309 else if (name == Madd)
1311 else if (name == Msub)
1313 else if (name == Mmul)
1317 mplist_put (ic_info->vars, sym, (void *) val1);
1318 MDEBUG_PRINT2 ("(%s=%d)", MSYMBOL_NAME (sym), val1);
1320 else if (name == Mequal || name == Mless || name == Mgreater)
1323 MPlist *actions1, *actions2;
1326 val1 = integer_value (ic, args);
1327 args = MPLIST_NEXT (args);
1328 val2 = integer_value (ic, args);
1329 args = MPLIST_NEXT (args);
1330 actions1 = MPLIST_PLIST (args);
1331 args = MPLIST_NEXT (args);
1332 if (MPLIST_TAIL_P (args))
1335 actions2 = MPLIST_PLIST (args);
1336 MDEBUG_PRINT2 ("(%d,%d)", val1, val2);
1337 if (name == Mequal ? val1 == val2
1338 : name == Mless ? val1 < val2
1341 MDEBUG_PRINT ("ok");
1342 ret = take_action_list (ic, actions1);
1346 MDEBUG_PRINT ("no");
1348 ret = take_action_list (ic, actions2);
1355 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1359 && (actions = mplist_get (im_info->macros, name)))
1361 if (take_action_list (ic, actions) < 0)
1368 ic->candidate_list = NULL;
1369 if (ic->cursor_pos > 0
1370 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
1373 ic->candidate_list = mtext_property_value (prop);
1375 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
1377 ic->candidate_from = mtext_property_start (prop);
1378 ic->candidate_to = mtext_property_end (prop);
1381 ic->candidates_changed |= (candidate_list != ic->candidate_list
1382 || candidate_index != ic->candidate_index
1383 || candidate_show != ic->candidate_show);
1388 /* Handle the input key KEY in the current state and map specified in
1389 the input context IC. If KEY is handled correctly, return 0.
1390 Otherwise, return -1. */
1393 handle_key (MInputContext *ic)
1395 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1396 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1397 MIMMap *map = ic_info->map;
1398 MIMMap *submap = NULL;
1399 MSymbol key = ic_info->keys[ic_info->key_head];
1402 MDEBUG_PRINT2 ("[IM] handle `%s' in state %s",
1403 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
1407 submap = mplist_get (map->submaps, key);
1408 if (! submap && (key = msymbol_get (key, M_key_alias)) != Mnil)
1409 submap = mplist_get (map->submaps, key);
1414 MDEBUG_PRINT (" submap-found");
1415 mtext_cpy (ic->preedit, ic_info->preedit_saved);
1416 ic->cursor_pos = ic_info->state_pos;
1417 ic_info->key_head++;
1418 ic_info->map = map = submap;
1419 if (map->map_actions)
1421 MDEBUG_PRINT (" map-actions:");
1422 if (take_action_list (ic, map->map_actions) < 0)
1425 else if (map->submaps)
1427 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
1429 MSymbol key = ic_info->keys[i];
1430 char *name = msymbol_name (key);
1432 if (! name[0] || ! name[1])
1433 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
1435 ic->preedit_changed = 1;
1438 /* If this is the terminal map or we have shifted to another
1439 state, perform branch actions (if any). */
1440 if (! map->submaps || map != ic_info->map)
1442 if (map->branch_actions)
1444 MDEBUG_PRINT (" branch-actions:");
1445 if (take_action_list (ic, map->branch_actions) < 0)
1448 /* If MAP is still not the root map, shift to the current
1450 if (ic_info->map != ic_info->state->map)
1451 shift_state (ic, ic_info->state->name);
1453 MDEBUG_PRINT ("\n");
1457 /* MAP can not handle KEY. */
1459 /* If MAP is the root map of the initial state, it means that
1460 the current input method can not handle KEY. */
1461 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
1463 MDEBUG_PRINT (" unhandled\n");
1467 if (map != ic_info->state->map)
1469 /* If MAP is not the root map... */
1470 /* If MAP has branch actions, perform them. */
1471 if (map->branch_actions)
1473 MDEBUG_PRINT (" branch-actions:");
1474 take_action_list (ic, map->branch_actions);
1476 /* If MAP is still not the root map, shift to the current
1478 if (ic_info->map != ic_info->state->map)
1480 shift_state (ic, ic_info->state->name);
1481 /* If MAP has branch_actions, perform them. */
1482 if (ic_info->map->branch_actions)
1484 MDEBUG_PRINT (" init-actions:");
1485 take_action_list (ic, ic_info->map->branch_actions);
1491 /* MAP is the root map, perform branch actions (if any) or
1492 shift to the initial state. */
1493 if (map->branch_actions)
1495 MDEBUG_PRINT (" branch-actions:");
1496 take_action_list (ic, map->branch_actions);
1500 ((MIMState *) MPLIST_VAL (im_info->states))->name);
1502 MDEBUG_PRINT ("\n");
1508 reset_ic (MInputContext *ic, MSymbol ignore)
1510 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1511 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1513 if (im_info->states)
1514 /* Shift to the initial state. */
1515 shift_state (ic, Mnil);
1517 ic_info->state = NULL;
1518 MLIST_RESET (ic_info);
1519 ic_info->map = ic_info->state ? ic_info->state->map : NULL;
1520 ic_info->state_key_head = ic_info->key_head = 0;
1521 ic_info->key_unhandled = 0;
1522 ic->cursor_pos = ic_info->state_pos = 0;
1523 ic->status = ic_info->state ? ic_info->state->title : NULL;
1525 ic->status = im_info->title;
1526 ic->candidate_list = NULL;
1527 ic->candidate_show = 0;
1528 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1;
1529 if (ic_info->map && ic_info->map->map_actions)
1530 take_action_list (ic, ic_info->map->map_actions);
1534 open_im (MInputMethod *im)
1537 MInputMethodInfo *im_info;
1541 mdb = mdatabase_find (Minput_method, im->language, im->name, Mnil);
1544 plist = mdatabase_load (mdb);
1546 MERROR (MERROR_IM, -1);
1547 MSTRUCT_CALLOC (im_info, MERROR_IM);
1549 result = load_input_method (im->language, im->name, plist, im_info);
1550 M17N_OBJECT_UNREF (plist);
1552 MERROR (MERROR_IM, -1);
1557 close_im (MInputMethod *im)
1559 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1563 M17N_OBJECT_UNREF (im_info->title);
1564 if (im_info->states)
1566 MPLIST_DO (plist, im_info->states)
1568 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1571 M17N_OBJECT_UNREF (state->title);
1573 free_map (state->map);
1576 M17N_OBJECT_UNREF (im_info->states);
1579 if (im_info->macros)
1581 MPLIST_DO (plist, im_info->macros)
1582 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1583 M17N_OBJECT_UNREF (im_info->macros);
1586 if (im_info->externals)
1588 MPLIST_DO (plist, im_info->externals)
1590 MIMExternalModule *external = MPLIST_VAL (plist);
1592 dlclose (external->handle);
1593 M17N_OBJECT_UNREF (external->func_list);
1595 MPLIST_KEY (plist) = Mt;
1597 M17N_OBJECT_UNREF (im_info->externals);
1605 create_ic (MInputContext *ic)
1607 MInputMethod *im = ic->im;
1608 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1609 MInputContextInfo *ic_info;
1612 ic_info = (MInputContextInfo *) ic->info;
1615 MSTRUCT_CALLOC (ic_info, MERROR_IM);
1618 MLIST_INIT1 (ic_info, keys, 8);
1619 ic_info->markers = mplist ();
1620 ic_info->vars = mplist ();
1621 ic_info->preedit_saved = mtext ();
1622 if (im_info->externals)
1624 MPlist *func_args = mplist (), *plist;
1626 mplist_add (func_args, Mt, ic);
1627 MPLIST_DO (plist, im_info->externals)
1629 MIMExternalModule *external = MPLIST_VAL (plist);
1630 MIMExternalFunc func
1631 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
1636 M17N_OBJECT_UNREF (func_args);
1638 reset_ic (ic, Mnil);
1643 destroy_ic (MInputContext *ic)
1645 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1646 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1648 if (im_info->externals)
1650 MPlist *func_args = mplist (), *plist;
1652 mplist_add (func_args, Mt, ic);
1653 MPLIST_DO (plist, im_info->externals)
1655 MIMExternalModule *external = MPLIST_VAL (plist);
1656 MIMExternalFunc func
1657 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
1662 M17N_OBJECT_UNREF (func_args);
1664 MLIST_FREE1 (ic_info, keys);
1665 M17N_OBJECT_UNREF (ic_info->preedit_saved);
1666 M17N_OBJECT_UNREF (ic_info->markers);
1667 M17N_OBJECT_UNREF (ic_info->vars);
1672 /** Handle the input key KEY in the current state and map of IC->info.
1673 If KEY is handled but no text is produced, return 0, otherwise
1679 filter (MInputContext *ic, MSymbol key, void *arg)
1681 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1682 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1685 if (! ic_info->state)
1687 ic_info->key_unhandled = 1;
1690 mtext_reset (ic->produced);
1691 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
1692 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1693 ic_info->key_unhandled = 0;
1695 if (handle_key (ic) < 0)
1697 /* KEY was not handled. Reset the status and break the
1699 reset_ic (ic, Mnil);
1700 /* This forces returning 1. */
1701 ic_info->key_unhandled = 1;
1707 reset_ic (ic, Mnil);
1708 ic_info->key_unhandled = 1;
1711 /* Break the loop if all keys were handled. */
1712 } while (ic_info->key_head < ic_info->used);
1714 /* If the current map is the root of the initial state, we should
1715 produce any preedit text in ic->produced. */
1716 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
1717 && mtext_nchars (ic->preedit) > 0)
1718 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1720 if (mtext_nchars (ic->produced) > 0)
1722 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
1725 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1726 Mlanguage, ic->im->language);
1729 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
1733 /** Return 1 if the last event or key was not handled, otherwise
1736 There is no need of looking up because ic->produced should already
1737 contain the produced text (if any).
1742 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1744 mtext_cat (mt, ic->produced);
1745 mtext_reset (ic->produced);
1746 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
1749 static MPlist *load_im_info_keys;
1752 load_im_info (MSymbol language, MSymbol name, MSymbol key)
1757 if (language == Mnil || name == Mnil)
1758 MERROR (MERROR_IM, NULL);
1760 mdb = mdatabase_find (Minput_method, language, name, Mnil);
1762 MERROR (MERROR_IM, NULL);
1763 mplist_push (load_im_info_keys, key, Mt);
1764 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
1765 mplist_pop (load_im_info_keys);
1770 /* Input method command handler. */
1772 /* List of all (global and local) commands.
1773 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
1774 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
1775 Global commands are storead as (t (t COMMAND ...)) */
1776 static MPlist *command_list;
1778 /* Check if PLIST is a valid command key sequence.
1779 PLIST must be NULL or:
1780 [ symbol:KEY | integer:KEY ] ... */
1783 check_command_keyseq (MPlist *plist)
1787 MPLIST_DO (plist, plist)
1789 if (MPLIST_SYMBOL_P (plist))
1791 else if (MPLIST_INTEGER_P (plist))
1793 int n = MPLIST_INTEGER (plist);
1797 MPLIST_KEY (plist) = Msymbol;
1798 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
1807 get_description_advance (MPlist *plist)
1812 if (! MPLIST_MTEXT_P (plist))
1814 mt = mplist_pop (plist);
1815 pos = mtext_chr (mt, '\n');
1818 MText *detail = mtext_copy (mtext (), 0, mt, pos + 1, mtext_nchars (mt));
1819 mtext_del (mt, pos, mtext_nchars (mt));
1820 mtext_put_prop (mt, 0, pos, Mdetail_text, detail);
1821 M17N_OBJECT_UNREF (detail);
1827 parse_command_list (MPlist *plist, MPlist *global_list)
1829 MPlist *val = mplist ();
1831 /* PLIST ::= (sym:CMD mtext:DESCRIPTION ? (sym:KEY ...) ...) ... */
1832 MPLIST_DO (plist, plist)
1836 MPlist *this_val, *pl, *p;
1838 if (! MPLIST_PLIST_P (plist))
1840 pl = MPLIST_PLIST (plist);
1841 if (! MPLIST_SYMBOL_P (pl))
1843 cmd = MPLIST_SYMBOL (pl);
1844 pl = MPLIST_NEXT (pl);
1845 mt = get_description_advance (pl);
1846 this_val = mplist ();
1848 if (! mt && global_list)
1850 /* Get the description from global_list. */
1851 p = mplist_get (global_list, cmd);
1852 if (p && MPLIST_MTEXT (p))
1854 mt = MPLIST_MTEXT (p);
1855 M17N_OBJECT_REF (mt);
1860 mplist_add (this_val, Mtext, mt);
1861 M17N_OBJECT_UNREF (mt);
1863 /* PL ::= (sym:KEY ...) ... */
1866 if (MPLIST_PLIST_P (pl)
1867 && check_command_keyseq (MPLIST_PLIST (pl)) >= 0)
1868 /* All the elements are valid keys. */
1869 mplist_add (this_val, Mplist, MPLIST_PLIST (pl));
1872 mplist_put (val, cmd, this_val);
1878 get_command_list (MSymbol language, MSymbol name)
1884 language = name = Mt;
1888 MDatabase *mdb = mdatabase_find (msymbol ("input"), M_command,
1891 if (mdb && (plist = mdatabase_load (mdb)))
1893 pl = parse_command_list (plist, NULL);
1894 M17N_OBJECT_UNREF (plist);
1899 mplist_add (plist, Mt, pl);
1900 command_list = mplist ();
1901 mplist_add (command_list, Mt, plist);
1904 per_lang = mplist_get (command_list, language);
1907 plist = mplist_find_by_key (per_lang, name);
1909 return (MPLIST_VAL (plist));
1913 per_lang = mplist ();
1914 mplist_add (command_list, language, per_lang);
1917 /* Now we are sure that we are loading per-im info. */
1918 /* Get the global command list. */
1919 plist = load_im_info (language, name, M_command);
1920 if (! plist || mplist_key (plist) == Mnil)
1924 mplist_add (per_lang, name, plist);
1927 pl = parse_command_list (mplist_value (plist),
1928 mplist_get ((MPlist *) mplist_get (command_list, Mt),
1930 M17N_OBJECT_UNREF (plist);
1931 mplist_put (per_lang, name, pl);
1936 /* Input method variable handler. */
1938 /* List of all variables.
1939 (LANG:(IM-NAME:(VAR ...) ...) ...) ...
1940 VAR is VAR-NAME:(mtext:DESCRIPTION TYPE:VALUE ...)) */
1942 static MPlist *variable_list;
1945 parse_variable_list (MPlist *plist)
1947 MPlist *val = mplist (), *pl, *p;
1949 /* PLIST ::= (sym:VAR mtext:DESCRIPTION TYPE:INIT-VAL ...) ... */
1950 MPLIST_DO (plist, plist)
1956 if (! MPLIST_PLIST_P (plist))
1958 pl = MPLIST_PLIST (plist);
1959 if (! MPLIST_SYMBOL_P (pl))
1961 var = MPLIST_SYMBOL (pl);
1962 pl = MPLIST_NEXT (pl);
1963 mt = get_description_advance (pl);
1964 if (! mt || MPLIST_TAIL_P (pl))
1966 this_val = mplist ();
1967 mplist_add (this_val, Mtext, mt);
1968 M17N_OBJECT_UNREF (mt);
1969 type = MPLIST_KEY (pl);
1970 mplist_add (this_val, type, MPLIST_VAL (pl));
1971 MPLIST_DO (pl, MPLIST_NEXT (pl))
1973 if (type != MPLIST_KEY (pl)
1974 && (type != Minteger || ! MPLIST_PLIST_P (pl)))
1976 if (MPLIST_PLIST_P (pl))
1978 MPLIST_DO (p, MPLIST_PLIST (pl))
1979 if (! MPLIST_INTEGER_P (p))
1981 if (! MPLIST_TAIL_P (p))
1984 mplist_add (this_val, MPLIST_KEY (pl), MPLIST_VAL (pl));
1987 mplist_put (val, var, this_val);
1994 get_variable_list (MSymbol language, MSymbol name)
1999 if (language == Mnil || name == Mnil)
2000 MERROR (MERROR_IM, NULL);
2001 if (! variable_list)
2002 variable_list = mplist ();
2003 per_lang = mplist_get (variable_list, language);
2006 plist = mplist_find_by_key (per_lang, name);
2008 return (MPLIST_VAL (plist));
2012 per_lang = mplist ();
2013 mplist_add (variable_list, language, per_lang);
2015 plist = load_im_info (language, name, M_variable);
2016 if (! plist || mplist_key (plist) == Mnil)
2020 mplist_add (per_lang, name, plist);
2023 pl = parse_variable_list (mplist_value (plist));
2024 M17N_OBJECT_UNREF (plist);
2025 mplist_put (per_lang, name, pl);
2030 input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
2032 MPlist *plist, *pl, *p;
2033 char path[PATH_MAX];
2035 /* Cancel the hook. */
2036 msymbol_put (tag0, M_database_hook, NULL);
2039 mplist_push (load_im_info_keys, M_description, Mt);
2040 MPLIST_DO (plist, mdatabase__dir_list)
2042 char *dirname = (char *) MPLIST_VAL (plist);
2044 DIR *dir = opendir (dirname);
2049 dirlen = strlen (dirname);
2050 strcpy (path, dirname);
2051 while ((dp = readdir (dir)) != NULL)
2053 /* We can't trust dp->d_nameln. */
2054 int len = strlen (dp->d_name);
2057 if (len > 4 && memcmp (dp->d_name + len - 4, ".mim", 4) == 0)
2059 strcpy (path + dirlen, dp->d_name);
2060 fp = fopen (path, "r");
2063 pl = mplist__from_file (fp, load_im_info_keys);
2067 if (MPLIST_PLIST_P (pl))
2069 p = MPLIST_PLIST (pl);
2070 p = MPLIST_NEXT (p);
2071 if (MPLIST_SYMBOL_P (p))
2073 tag1 = MPLIST_VAL (p);
2074 p = MPLIST_NEXT (p);
2075 if (MPLIST_SYMBOL_P (p))
2077 tag2 = MPLIST_VAL (p);
2078 mdatabase_define (tag0, tag1, tag2, tag3,
2083 M17N_OBJECT_UNREF (pl);
2089 mplist_pop (load_im_info_keys);
2093 /* Support functions for mdebug_dump_im. */
2096 dump_im_map (MPlist *map_list, int indent)
2099 MSymbol key = MPLIST_KEY (map_list);
2100 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2102 prefix = (char *) alloca (indent + 1);
2103 memset (prefix, 32, indent);
2104 prefix[indent] = '\0';
2106 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2107 if (map->map_actions)
2108 mdebug_dump_plist (map->map_actions, indent + 2);
2111 MPLIST_DO (map_list, map->submaps)
2113 fprintf (stderr, "\n%s ", prefix);
2114 dump_im_map (map_list, indent + 2);
2117 if (map->branch_actions)
2119 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2120 mdebug_dump_plist (map->branch_actions, indent + 4);
2121 fprintf (stderr, ")");
2123 fprintf (stderr, ")");
2128 dump_im_state (MIMState *state, int indent)
2133 prefix = (char *) alloca (indent + 1);
2134 memset (prefix, 32, indent);
2135 prefix[indent] = '\0';
2137 fprintf (stderr, "(%s", msymbol_name (state->name));
2138 if (state->map->submaps)
2140 MPLIST_DO (map_list, state->map->submaps)
2142 fprintf (stderr, "\n%s ", prefix);
2143 dump_im_map (map_list, indent + 2);
2146 fprintf (stderr, ")");
2155 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2156 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2157 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2158 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2159 char buf[6], buf2[256];
2163 Minput_method = msymbol ("input-method");
2164 msymbol_put (Minput_method, M_database_hook, (void *) input_method_hook);
2165 Minput_driver = msymbol ("input-driver");
2166 Mtitle = msymbol ("title");
2167 Mmacro = msymbol ("macro");
2168 Mmodule = msymbol ("module");
2169 Mmap = msymbol ("map");
2170 Mstate = msymbol ("state");
2171 Minsert = msymbol ("insert");
2172 Mdelete = msymbol ("delete");
2173 Mmove = msymbol ("move");
2174 Mmark = msymbol ("mark");
2175 Mpushback = msymbol ("pushback");
2176 Mundo = msymbol ("undo");
2177 Mcall = msymbol ("call");
2178 Mshift = msymbol ("shift");
2179 Mselect = msymbol ("select");
2180 Mshow = msymbol ("show");
2181 Mhide = msymbol ("hide");
2182 Mset = msymbol ("set");
2183 Madd = msymbol ("add");
2184 Msub = msymbol ("sub");
2185 Mmul = msymbol ("mul");
2186 Mdiv = msymbol ("div");
2187 Mequal = msymbol ("=");
2188 Mless = msymbol ("<");
2189 Mgreater = msymbol (">");
2191 Minput_preedit_start = msymbol ("input-preedit-start");
2192 Minput_preedit_done = msymbol ("input-preedit-done");
2193 Minput_preedit_draw = msymbol ("input-preedit-draw");
2194 Minput_status_start = msymbol ("input-status-start");
2195 Minput_status_done = msymbol ("input-status-done");
2196 Minput_status_draw = msymbol ("input-status-draw");
2197 Minput_candidates_start = msymbol ("input-candidates-start");
2198 Minput_candidates_done = msymbol ("input-candidates-done");
2199 Minput_candidates_draw = msymbol ("input-candidates-draw");
2200 Minput_set_spot = msymbol ("input-set-spot");
2201 Minput_toggle = msymbol ("input-toggle");
2202 Minput_reset = msymbol ("input-reset");
2204 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2205 Mcandidate_index = msymbol (" candidate-index");
2207 Minit = msymbol ("init");
2208 Mfini = msymbol ("fini");
2210 M_key_alias = msymbol (" key-alias");
2211 M_description = msymbol ("description");
2212 M_command = msymbol ("command");
2213 M_variable = msymbol ("variable");
2215 Mdetail_text = msymbol_as_managing_key (" detail-text");
2217 load_im_info_keys = mplist ();
2218 plist = mplist_add (load_im_info_keys, Mmap, Mnil);
2219 plist = mplist_add (plist, Mstate, Mnil);
2220 plist = mplist_add (plist, Mmacro, Mnil);
2221 plist = mplist_add (plist, Mmodule, Mnil);
2226 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2228 one_char_symbol[i] = msymbol (buf);
2230 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (key_names[i]));
2232 for (buf[2] = i; i < 127; i++, buf[2]++)
2233 one_char_symbol[i] = msymbol (buf + 2);
2234 one_char_symbol[i++] = msymbol ("Delete");
2240 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2242 one_char_symbol[i] = msymbol (buf);
2243 if (key_names[i - 128])
2245 strcpy (buf2 + 2, key_names[i - 128]);
2246 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2249 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2250 one_char_symbol[i] = msymbol (buf + 2);
2251 one_char_symbol[i] = msymbol ("M-Delete");
2253 command_list = variable_list = NULL;
2255 minput_default_driver.open_im = open_im;
2256 minput_default_driver.close_im = close_im;
2257 minput_default_driver.create_ic = create_ic;
2258 minput_default_driver.destroy_ic = destroy_ic;
2259 minput_default_driver.filter = filter;
2260 minput_default_driver.lookup = lookup;
2261 minput_default_driver.callback_list = mplist ();
2262 mplist_put (minput_default_driver.callback_list, Minput_reset,
2264 minput_driver = &minput_default_driver;
2271 MPlist *par_lang, *par_im, *p;
2275 MPLIST_DO (par_lang, command_list)
2277 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2279 MPLIST_DO (p, MPLIST_VAL (par_im))
2280 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2281 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2283 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2285 M17N_OBJECT_UNREF (command_list);
2286 command_list = NULL;
2290 MPLIST_DO (par_lang, variable_list)
2292 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2294 MPLIST_DO (p, MPLIST_VAL (par_im))
2295 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2296 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2298 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2300 M17N_OBJECT_UNREF (variable_list);
2301 variable_list = NULL;
2304 if (minput_default_driver.callback_list)
2306 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2307 minput_default_driver.callback_list = NULL;
2309 if (minput_driver->callback_list)
2311 M17N_OBJECT_UNREF (minput_driver->callback_list);
2312 minput_driver->callback_list = NULL;
2315 M17N_OBJECT_UNREF (load_im_info_keys);
2319 minput__callback (MInputContext *ic, MSymbol command)
2321 if (ic->im->driver.callback_list)
2323 MInputCallbackFunc func
2324 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2328 (func) (ic, command);
2333 minput__char_to_key (int c)
2335 if (c < 0 || c >= 0x100)
2338 return one_char_symbol[c];
2342 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2347 /*** @addtogroup m17nInputMethod */
2352 @name Variables: Predefined symbols for callback commands.
2354 These are the predefined symbols that are used as the @c COMMAND
2355 argument of callback functions of an input method driver (see
2356 #MInputDriver::callback_list ). */
2358 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2360 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2361 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2366 MSymbol Minput_preedit_start;
2367 MSymbol Minput_preedit_done;
2368 MSymbol Minput_preedit_draw;
2369 MSymbol Minput_status_start;
2370 MSymbol Minput_status_done;
2371 MSymbol Minput_status_draw;
2372 MSymbol Minput_candidates_start;
2373 MSymbol Minput_candidates_done;
2374 MSymbol Minput_candidates_draw;
2375 MSymbol Minput_set_spot;
2376 MSymbol Minput_toggle;
2377 MSymbol Minput_reset;
2382 @brief The default driver for internal input methods.
2384 The variable #minput_default_driver is the default driver for
2385 internal input methods.
2387 The member MInputDriver::open_im () searches the m17n database for
2388 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2389 $NAME\> and loads it.
2391 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2392 programmers responsibility to set it to a plist of proper callback
2393 functions. Otherwise, no feedback information (e.g. preedit text)
2394 can be shown to users.
2396 The macro M17N_INIT () sets the variable #minput_driver to the
2397 pointer to this driver so that all internal input methods use it.
2399 Therefore, unless @c minput_driver is set differently, the driver
2400 dependent arguments $ARG of the functions whose name begin with
2401 "minput_" are all ignored. */
2404 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2406 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2408 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2409 \< #Minput_method, $LANGUAGE, $NAME\>
2410 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2412 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2413 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2414 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2415 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2417 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2418 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2420 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2421 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2423 MInputDriver minput_default_driver;
2427 @brief The driver for internal input methods.
2429 The variable #minput_driver is a pointer to the input method
2430 driver that is used by internal input methods. The macro
2431 M17N_INIT () initializes it to a pointer to #minput_default_driver
2432 if <m17n<EM></EM>.h> is included. */
2434 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
2436 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
2437 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
2438 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
2439 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
2441 MInputDriver *minput_driver;
2443 MSymbol Minput_driver;
2448 @brief Open an input method.
2450 The minput_open_im () function opens an input method that matches
2451 language $LANGUAGE and name $NAME, and returns a pointer to the
2452 input method object newly allocated.
2454 This function at first decides an driver for the input method as
2457 If $LANGUAGE is not #Mnil, the driver pointed by the variable
2458 #minput_driver is used.
2460 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
2461 driver pointed to by the property value is used to open the input
2462 method. If $NAME has no such property, @c NULL is returned.
2464 Then, the member MInputDriver::open_im () of the driver is
2467 $ARG is set in the member @c arg of the structure MInputMethod so
2468 that the driver can refer to it. */
2471 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
2473 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
2474 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2476 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
2478 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
2479 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
2481 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
2482 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
2483 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2485 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
2487 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
2489 @latexonly \IPAlabel{minput_open} @endlatexonly
2494 minput_open_im (MSymbol language, MSymbol name, void *arg)
2497 MInputDriver *driver;
2500 driver = minput_driver;
2503 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
2505 MERROR (MERROR_IM, NULL);
2508 MSTRUCT_CALLOC (im, MERROR_IM);
2509 im->language = language;
2512 im->driver = *driver;
2513 if ((*im->driver.open_im) (im) < 0)
2524 @brief Close an input method.
2526 The minput_close_im () function closes the input method $IM, which
2527 must have been created by minput_open_im (). */
2530 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
2532 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
2533 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
2536 minput_close_im (MInputMethod *im)
2538 (*im->driver.close_im) (im);
2545 @brief Create an input context.
2547 The minput_create_ic () function creates an input context object
2548 associated with input method $IM, and calls callback functions
2549 corresponding to #Minput_preedit_start, #Minput_status_start, and
2550 #Minput_status_draw in this order.
2554 If an input context is successfully created, minput_create_ic ()
2555 returns a pointer to it. Otherwise it returns @c NULL. */
2558 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
2560 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
2561 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
2562 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
2563 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2567 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
2568 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2572 minput_create_ic (MInputMethod *im, void *arg)
2576 MSTRUCT_CALLOC (ic, MERROR_IM);
2579 ic->preedit = mtext ();
2580 ic->candidate_list = NULL;
2581 ic->produced = mtext ();
2582 ic->spot.x = ic->spot.y = 0;
2584 ic->plist = mplist ();
2585 if ((*im->driver.create_ic) (ic) < 0)
2587 M17N_OBJECT_UNREF (ic->preedit);
2588 M17N_OBJECT_UNREF (ic->produced);
2589 M17N_OBJECT_UNREF (ic->plist);
2594 if (im->driver.callback_list)
2596 minput__callback (ic, Minput_preedit_start);
2597 minput__callback (ic, Minput_status_start);
2598 minput__callback (ic, Minput_status_draw);
2607 @brief Destroy an input context.
2609 The minput_destroy_ic () function destroys the input context $IC,
2610 which must have been created by minput_create_ic (). It calls
2611 callback functions corresponding to #Minput_preedit_done,
2612 #Minput_status_done, and #Minput_candidates_done in this order. */
2615 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
2617 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
2618 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
2619 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
2620 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
2621 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2625 minput_destroy_ic (MInputContext *ic)
2627 if (ic->im->driver.callback_list)
2629 minput__callback (ic, Minput_preedit_done);
2630 minput__callback (ic, Minput_status_done);
2631 minput__callback (ic, Minput_candidates_done);
2633 (*ic->im->driver.destroy_ic) (ic);
2634 M17N_OBJECT_UNREF (ic->preedit);
2635 M17N_OBJECT_UNREF (ic->produced);
2636 M17N_OBJECT_UNREF (ic->plist);
2643 @brief Filter an input key.
2645 The minput_filter () function filters input key $KEY according to
2646 input context $IC, and calls callback functions corresponding to
2647 #Minput_preedit_draw, #Minput_status_draw, and
2648 #Minput_candidates_draw if the preedit text, the status, and the
2649 current candidate are changed respectively.
2652 If $KEY is filtered out, this function returns 1. In that case,
2653 the caller should discard the key. Otherwise, it returns 0, and
2654 the caller should handle the key, for instance, by calling the
2655 function minput_lookup () with the same key. */
2658 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
2660 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2661 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
2662 #Minput_preedit_draw, #Minput_status_draw,
2663 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
2666 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
2667 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
2668 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
2669 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
2671 @latexonly \IPAlabel{minput_filter} @endlatexonly
2675 minput_filter (MInputContext *ic, MSymbol key, void *arg)
2682 ret = (*ic->im->driver.filter) (ic, key, arg);
2684 if (ic->im->driver.callback_list)
2686 if (ic->preedit_changed)
2687 minput__callback (ic, Minput_preedit_draw);
2688 if (ic->status_changed)
2689 minput__callback (ic, Minput_status_draw);
2690 if (ic->candidates_changed)
2691 minput__callback (ic, Minput_candidates_draw);
2700 @brief Look up a text produced in the input context.
2702 The minput_lookup () function looks up a text in the input context
2703 $IC. $KEY must be the same one provided to the previous call of
2706 If a text was produced by the input method, it is concatenated
2709 This function calls #MInputDriver::lookup .
2712 If $KEY was correctly handled by the input method, this function
2713 returns 0. Otherwise, returns -1, even in that case, some text
2714 may be produced in $MT. */
2717 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
2719 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
2720 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2722 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
2725 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
2728 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
2729 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
2730 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
2732 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
2735 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2737 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
2742 @brief Set the spot of the input context.
2744 The minput_set_spot () function set the spot of input context $IC
2745 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
2746 The semantics of these values depend on the input method driver.
2748 For instance, a driver designed to work in a CUI environment may
2749 use $X and $Y as column and row numbers, and ignore $ASCENT and
2750 $DESCENT . A driver designed to work in a window system may
2751 interpret $X and $Y as pixel offsets relative to the origin of the
2752 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
2753 descent pixels of the line at ($X . $Y ).
2755 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
2757 $MT and $POS is the M-text and the character position at the spot.
2758 $MT may be @c NULL, in which case, the input method cannot get
2759 information about the text around the spot. */
2762 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
2764 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
2765 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
2766 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
2768 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
2769 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
2770 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
2771 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
2772 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
2773 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
2775 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
2777 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
2778 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
2782 minput_set_spot (MInputContext *ic, int x, int y,
2783 int ascent, int descent, int fontsize,
2788 ic->spot.ascent = ascent;
2789 ic->spot.descent = descent;
2790 ic->spot.fontsize = fontsize;
2793 if (ic->im->driver.callback_list)
2794 minput__callback (ic, Minput_set_spot);
2799 @brief Toggle input method.
2801 The minput_toggle () function toggles the input method associated
2802 with input context $IC. */
2804 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
2806 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2807 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
2811 minput_toggle (MInputContext *ic)
2813 if (ic->im->driver.callback_list)
2814 minput__callback (ic, Minput_toggle);
2815 ic->active = ! ic->active;
2819 @brief Reset an input context.
2821 The minput_reset_ic () function resets input context $IC by
2822 calling a callback function corresponding to #Minput_reset. It
2823 actually shifts the state to the initial one, and thus the current
2824 preediting text (if any) is committed. If necessary, a program
2825 can extract that committed text by calling minput_lookup () just
2826 after the call of minput_reset_ic (). In that case, the arguments
2827 @c KEY and @c ARG of minput_lookup () are ignored. */
2829 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
2831 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
2832 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2833 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
2834 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
2835 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
2836 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
2839 minput_reset_ic (MInputContext *ic)
2841 if (ic->im->driver.callback_list)
2842 minput__callback (ic, Minput_reset);
2847 @brief Key of a text property for detailed description.
2849 The symbol #Mdetail_text is a managing key usually used for a
2850 text property whose value is an M-text that contains detailed
2853 @brief ¾ÜºÙÀâÌÀÍѥƥ¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼.
2855 ¥·¥ó¥Ü¥ë #Mdetail_text ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ê¡¢Ä̾ï¾ÜºÙ¤ÊÀâÌÀ¤ò´Þ¤à
2856 M-text ¤òÃͤȤ·¤Æ»ý¤Ä¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ËÍѤ¤¤é¤ì¤ë¡£
2858 MSymbol Mdetail_text;
2861 @brief Get description text of an input method.
2863 The minput_get_description () function returns an M-text that
2864 briefly describes the input method specified by $LANGUAGE and
2865 $NAME. The returned M-text may have a text property, from its
2866 beginning to end, #Mdetail_text whose value is an M-text
2867 describing the input method in more detail.
2870 If the specified input method has a description text, a pointer to
2871 #MText is returned. A caller have to free it by m17n_object_unref ().
2872 If the input method does not have a description text, @c NULL is
2875 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
2877 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME
2878 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£ÊÖ¤µ¤ì¤ë M-text
2879 ¤Ë¤Ï¡¢¤½¤ÎÁ´ÂΤËÂФ·¤Æ #Mdetail_text
2880 ¤È¤¤¤¦¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬Éղ䵤ì¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ê¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¤µ¤é¤Ë¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
2884 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
2885 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
2886 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
2889 minput_get_description (MSymbol language, MSymbol name)
2891 MPlist *plist = load_im_info (language, name, M_description);
2897 if (! MPLIST_PLIST_P (plist))
2899 M17N_OBJECT_UNREF (plist);
2902 pl = MPLIST_PLIST (plist);
2903 while (! MPLIST_TAIL_P (pl) && ! MPLIST_MTEXT_P (pl))
2904 pl = MPLIST_NEXT (pl);
2905 if (MPLIST_MTEXT_P (pl))
2906 mt = get_description_advance (pl);
2907 M17N_OBJECT_UNREF (plist);
2912 @brief Get information about input method commands.
2914 The minput_get_commands () function returns information about
2915 input method commands of the input method specified by $LANGUAGE
2916 and $NAME. An input method command is a pseudo key event to which
2917 one or more actual input key sequences are assigned.
2919 There are two kinds of commands, global and local. Global
2920 commands are used by multiple input methods for the same purpose,
2921 and have global key assignments. Local commands are used only in
2922 a specific input method, and have only local key assignments.
2924 Each input method may locally change key assignments for global
2925 commands. A global key assignment for a global command are
2926 effective only when the current input method does not have local
2927 key assignments for that command.
2929 If $NAME is #Mnil, information about global commands is returned.
2930 In this case $LANGUAGE is ignored.
2932 If $NAME is not #Mnil, information about those commands that have
2933 local key assignments in the input method specified by $LANGUAGE
2934 and $NAME is returned.
2937 If no input method commands are found, this function returns @c NULL.
2939 Otherwise, a pointer to a plist is returned. The key of each
2940 element in the plist is a symbol representing a command, and the
2941 value is a plist of the form COMMAND-INFO described below.
2943 The first element of COMMAND-INFO has the key #Mtext, and the
2944 value is an M-text describing the command briefly. This M-text
2945 may have a text property whose key is #Mdetail_text and whose
2946 value is an M-text describing the command in more detail.
2948 If there are no more elements, that means no key sequences are
2949 assigned to the command. Otherwise, each of the remaining
2950 elements has the key #Mplist, and the value is a plist whose keys are
2951 #Msymbol and values are symbols representing input keys, which are
2952 currently assigned to the command.
2954 As the returned plist is kept in the library, the caller must not
2955 modify nor free it. */
2957 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
2959 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME
2960 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2961 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
2963 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£
2964 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ÇÍѤ¤¤é¤ì¤ë¡£
2965 ¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
2967 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
2968 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ß͸ú¤Ç¤¢¤ë¡£
2970 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2971 ¤³¤Î¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
2973 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME
2974 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
2977 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
2979 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2980 ¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î
2981 COMMAND-INFO ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
2983 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext
2984 ¤ò¡¢ÃͤȤ·¤Æ¤½¤Î¥³¥Þ¥ó¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤ò»ý¤Ä¡£¤³¤Î M-text
2986 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤Î¥³¥Þ¥ó¥É¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
2989 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
2990 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ#Mplist
2991 ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£
2992 ¤³¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol
2993 ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2995 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
2998 minput_get_commands (MSymbol language, MSymbol name)
3000 MPlist *plist = get_command_list (language, name);
3002 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3006 @brief Assign a key sequence to an input method command.
3008 The minput_assign_command_keys () function assigns input key
3009 sequence $KEYSEQ to input method command $COMMAND for the input
3010 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3011 key sequence is assigned globally no matter what $LANGUAGE is.
3012 Otherwise the key sequence is assigned locally.
3014 Each element of $KEYSEQ must have the key $Msymbol and the value
3015 must be a symbol representing an input key.
3017 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3018 globally or locally.
3020 This assignment gets effective in a newly opened input method.
3023 If the operation was successful, 0 is returned. Otherwise -1 is
3024 returned, and #merror_code is set to #MERROR_IM. */
3026 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3028 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3029 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND
3030 ¤ËÂФ·¤Æ¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil
3031 ¤Ê¤é¤Ð¡¢$LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
3032 ¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3034 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol
3035 ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3037 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£
3038 ¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3040 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤Ë¤Ê¤ë¡£
3043 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3044 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3047 minput_assign_command_keys (MSymbol language, MSymbol name,
3048 MSymbol command, MPlist *keyseq)
3050 MPlist *plist, *pl, *p;
3052 if (check_command_keyseq (keyseq) < 0
3053 || ! (plist = get_command_list (language, name)))
3054 MERROR (MERROR_IM, -1);
3055 pl = mplist_get (plist, command);
3058 pl = MPLIST_NEXT (pl);
3060 while ((p = mplist_pop (pl)))
3061 M17N_OBJECT_UNREF (p);
3064 keyseq = mplist_copy (keyseq);
3065 mplist_push (pl, Mplist, keyseq);
3066 M17N_OBJECT_UNREF (keyseq);
3072 MERROR (MERROR_IM, -1);
3075 pl = get_command_list (Mnil, Mnil); /* Get global commands. */
3076 pl = mplist_get (pl, command);
3078 MERROR (MERROR_IM, -1);
3080 mplist_add (p, Mtext, mplist_value (pl));
3081 keyseq = mplist_copy (keyseq);
3082 mplist_add (p, Mplist, keyseq);
3083 M17N_OBJECT_UNREF (keyseq);
3084 mplist_push (plist, command, p);
3090 @brief Get a list of variables of an input method.
3092 The minput_get_variables () function returns a plist (#MPlist) of
3093 variables used to control the behavior of the input method
3094 specified by $LANGUAGE and $NAME. The key of an element of the
3095 plist is a symbol representing a variable, and the value is a
3096 plist of the form VAR-INFO (described below) that carries the
3097 information about the variable.
3099 The first element of VAR-INFO has the key #Mtext, and the value is
3100 an M-text describing the variable briefly. This M-text may have a
3101 text property #Mdetail_text whose value is an M-text describing
3102 the variable in more detail.
3104 The second element of VAR-INFO is for the value of the variable.
3105 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3106 integer, a symbol, or an M-text, respectively. The variable is
3107 set to this value when an input context is created for the input
3110 If there are no more elements, the variable can take any value
3111 that matches with the above type. Otherwise, the remaining
3112 elements of VAR-INFO are to specify valid values of the variable.
3114 If the type of the variable is integer, the following elements
3115 have the key #Minteger or #Mplist. If it is #Minteger, the value
3116 is a valid integer value. If it is #Mplist, the value is a plist
3117 of two of elements. Both of them have the key #Minteger, and
3118 values are the minimum and maximum bounds of the valid value
3121 If the type of the variable is symbol or M-text, the following
3122 elements of the plist have the key #Msymbol or #Mtext,
3123 respectively, and the value must be a valid one.
3125 For instance, suppose an input method has the variables:
3127 @li name:intvar, description: "value is an integer",
3128 initial value:0, value-range:0..3,10,20
3130 @li name:symvar, description: "value is a symbol",
3131 initial value:nil, value-range:a, b, c, nil
3133 @li name:txtvar, description: "value is an M-text",
3134 initial value:empty text, no value-range (i.e. any text)
3136 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3137 a value, and '(...)' means a plist):
3140 plist:(intvar:(mtext:'value is an integer'
3142 plist:(integer:0 integer:3)
3145 symvar:(mtext:"value is a symbol"
3151 txtvar:(mtext:"value is an M-text"
3156 If the input method uses any variables, a pointer to #MPlist is
3157 returned. As the plist is kept in the library, a caller must not
3158 modify nor free it. If the input method does not use any
3159 variable, @c NULL is returned. */
3161 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3163 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3164 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3165 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3166 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3167 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3169 VAR-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext ¤ò¡¢ÃͤȤ·¤Æ¤½¤ÎÊÑ¿ô¤ò´Êñ¤ËÀâÌÀ¤¹¤ë
3170 M-text ¤ò»ý¤Ä¡£¤³¤Î M-text ¤Ï¡¢#Mdetail_text
3171 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤ÎÊÑ¿ô¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3174 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3175 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3176 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3178 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3179 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3181 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3182 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3183 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3184 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3186 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3187 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3189 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3191 @li name:intvar, ÀâÌÀ:"value is an integer",
3192 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3194 @li name:symvar, ÀâÌÀ:"value is a symbol",
3195 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3197 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3198 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3200 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3201 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3204 plist:(intvar:(mtext:"value is an integer"
3206 plist:(integer:0 integer:3)
3209 symvar:(mtext:"value is a symbol"
3215 txtvar:(mtext:"value is an M-text"
3220 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3221 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3222 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3225 minput_get_variables (MSymbol language, MSymbol name)
3227 MPlist *plist = get_variable_list (language, name);
3229 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3233 @brief Set the initial value of an input method variable.
3235 The minput_set_variable () function sets the initial value of
3236 input method variable $VARIABLE to $VALUE for the input method
3237 specified by $LANGUAGE and $NAME.
3239 By default, the initial value is 0.
3241 This setting gets effective in a newly opened input method.
3244 If the operation was successful, 0 is returned. Otherwise -1 is
3245 returned, and #merror_code is set to #MERROR_IM. */
3247 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3249 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3250 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3251 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3253 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3255 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3258 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3259 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3262 minput_set_variable (MSymbol language, MSymbol name,
3263 MSymbol variable, void *value)
3265 MPlist *plist, *val_element, *range_element;
3268 if (language == Mnil || name == Mnil)
3269 MERROR (MERROR_IM, -1);
3270 plist = get_variable_list (language, name);
3272 MERROR (MERROR_IM, -1);
3273 plist = (MPlist *) mplist_get (plist, variable);
3275 MERROR (MERROR_IM, -1);
3276 val_element = MPLIST_NEXT (plist);
3277 type = MPLIST_KEY (val_element);
3278 range_element = MPLIST_NEXT (val_element);
3280 if (! MPLIST_TAIL_P (range_element))
3282 if (type == Minteger)
3284 int val = (int) value, this_val;
3286 MPLIST_DO (plist, range_element)
3288 this_val = (int) MPLIST_VAL (plist);
3289 if (MPLIST_PLIST_P (plist))
3291 int min_bound, max_bound;
3292 MPlist *pl = MPLIST_PLIST (plist);
3294 min_bound = (int) MPLIST_VAL (pl);
3295 pl = MPLIST_NEXT (pl);
3296 max_bound = (int) MPLIST_VAL (pl);
3297 if (val >= min_bound && val <= max_bound)
3300 else if (val == this_val)
3303 if (MPLIST_TAIL_P (plist))
3304 MERROR (MERROR_IM, -1);
3306 else if (type == Msymbol)
3308 MPLIST_DO (plist, range_element)
3309 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3311 if (MPLIST_TAIL_P (plist))
3312 MERROR (MERROR_IM, -1);
3314 else /* type == Mtext */
3316 MPLIST_DO (plist, range_element)
3317 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3319 if (MPLIST_TAIL_P (plist))
3320 MERROR (MERROR_IM, -1);
3321 M17N_OBJECT_REF (value);
3325 mplist_set (val_element, type, value);
3331 /*** @addtogroup m17nDebug */
3337 @brief Dump an input method.
3339 The mdebug_dump_im () function prints the input method $IM in a
3340 human readable way to the stderr. $INDENT specifies how many
3341 columns to indent the lines but the first one.
3344 This function returns $IM. */
3346 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3348 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3349 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3352 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3355 mdebug_dump_im (MInputMethod *im, int indent)
3357 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3360 prefix = (char *) alloca (indent + 1);
3361 memset (prefix, 32, indent);
3362 prefix[indent] = '\0';
3364 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3365 msymbol_name (im->name));
3366 mdebug_dump_mtext (im_info->title, 0, 0);
3367 if (im->name != Mnil)
3371 MPLIST_DO (state, im_info->states)
3373 fprintf (stderr, "\n%s ", prefix);
3374 dump_im_state (MPLIST_VAL (state), indent + 2);
3377 fprintf (stderr, ")");