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_MTEXT_P (pl))
380 MText *mt = MPLIST_MTEXT (pl);
382 if (mtext_nchars (mt) != mtext_nbytes (mt))
383 MERROR (MERROR_IM, -1);
385 else if (MPLIST_PLIST_P (pl))
389 MPLIST_DO (p, MPLIST_PLIST (pl))
390 if (! MPLIST_SYMBOL_P (p))
391 MERROR (MERROR_IM, -1);
393 else if (! MPLIST_INTEGER_P (pl))
394 MERROR (MERROR_IM, -1);
396 else if (action_name == Mset || action_name == Madd
397 || action_name == Msub || action_name == Mmul
398 || action_name == Mdiv)
400 if (! (MPLIST_SYMBOL_P (pl)
401 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
402 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
403 MERROR (MERROR_IM, -1);
405 else if (action_name == Mequal || action_name == Mless
406 || action_name == Mgreater)
408 if (! ((MPLIST_INTEGER_P (pl) || MPLIST_SYMBOL_P (pl))
409 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
410 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
411 MERROR (MERROR_IM, -1);
412 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
413 if (! MPLIST_PLIST_P (pl))
414 MERROR (MERROR_IM, -1);
415 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
416 MERROR (MERROR_IM, -1);
417 pl = MPLIST_NEXT (pl);
418 if (MPLIST_PLIST_P (pl)
419 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
420 MERROR (MERROR_IM, -1);
422 else if (! macros || ! mplist_get (macros, action_name))
423 MERROR (MERROR_IM, -1);
426 MERROR (MERROR_IM, -1);
433 /* Load a translation into MAP from PLIST.
435 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
438 load_translation (MIMMap *map, MPlist *plist, MPlist *branch_actions,
444 if (MPLIST_MTEXT_P (plist))
446 MText *mt = MPLIST_MTEXT (plist);
448 len = mtext_nchars (mt);
449 if (len == 0 || len != mtext_nbytes (mt))
450 MERROR (MERROR_IM, -1);
451 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
452 for (i = 0; i < len; i++)
453 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
455 else if (MPLIST_PLIST_P (plist))
457 MPlist *elt = MPLIST_PLIST (plist);
459 len = MPLIST_LENGTH (elt);
461 MERROR (MERROR_IM, -1);
462 keyseq = (MSymbol *) alloca (sizeof (int) * len);
463 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
465 if (MPLIST_INTEGER_P (elt))
467 int c = MPLIST_INTEGER (elt);
469 if (c < 0 || c >= 0x100)
470 MERROR (MERROR_IM, -1);
471 keyseq[i] = one_char_symbol[c];
473 else if (MPLIST_SYMBOL_P (elt))
474 keyseq[i] = MPLIST_SYMBOL (elt);
476 MERROR (MERROR_IM, -1);
480 MERROR (MERROR_IM, -1);
482 for (i = 0; i < len; i++)
484 MIMMap *deeper = NULL;
487 deeper = mplist_get (map->submaps, keyseq[i]);
489 map->submaps = mplist ();
492 /* Fixme: It is better to make all deeper maps at once. */
493 MSTRUCT_CALLOC (deeper, MERROR_IM);
494 mplist_put (map->submaps, keyseq[i], deeper);
499 /* We reach a terminal map. */
501 || map->branch_actions)
502 /* This map is already defined. We avoid overriding it. */
505 plist = MPLIST_NEXT (plist);
506 if (! MPLIST_TAIL_P (plist))
508 if (parse_action_list (plist, macros) < 0)
509 MERROR (MERROR_IM, -1);
510 map->map_actions = plist;
511 M17N_OBJECT_REF (plist);
515 map->branch_actions = branch_actions;
516 M17N_OBJECT_REF (branch_actions);
522 /* Load a branch from PLIST into MAP. PLIST has this form:
523 PLIST ::= ( MAP-NAME BRANCH-ACTION * )
524 MAPS is a plist of raw maps.
525 STATE is the current state. */
528 load_branch (MPlist *plist, MPlist *maps, MIMMap *map, MPlist *macros)
531 MPlist *branch_actions;
533 if (! MPLIST_SYMBOL_P (plist))
534 MERROR (MERROR_IM, -1);
535 map_name = MPLIST_SYMBOL (plist);
536 plist = MPLIST_NEXT (plist);
537 if (MPLIST_TAIL_P (plist))
538 branch_actions = NULL;
539 else if (parse_action_list (plist, macros) < 0)
540 MERROR (MERROR_IM, -1);
542 branch_actions = plist;
543 if (map_name == Mnil)
545 map->branch_actions = branch_actions;
547 M17N_OBJECT_REF (branch_actions);
549 else if (map_name == Mt)
551 map->map_actions = branch_actions;
553 M17N_OBJECT_REF (branch_actions);
557 plist = (MPlist *) mplist_get (maps, map_name);
558 if (! plist || ! MPLIST_PLIST_P (plist))
559 MERROR (MERROR_IM, -1);
560 MPLIST_DO (plist, plist)
561 if (! MPLIST_PLIST_P (plist)
562 || (load_translation (map, MPLIST_PLIST (plist), branch_actions,
565 MERROR (MERROR_IM, -1);
571 /* Load a macro from PLIST into MACROS.
573 PLIST ::= ( MACRO-NAME ACTION * )
574 MACROS is a plist of macro names vs action list. */
576 load_macros (MPlist *plist, MPlist *macros)
580 if (! MPLIST_SYMBOL_P (plist))
581 MERROR (MERROR_IM, -1);
582 name = MPLIST_SYMBOL (plist);
583 plist = MPLIST_NEXT (plist);
584 if (MPLIST_TAIL_P (plist)
585 || parse_action_list (plist, macros) < 0)
586 MERROR (MERROR_IM, -1);
587 mplist_put (macros, name, plist);
588 M17N_OBJECT_REF (plist);
592 /* Load an external module from PLIST into EXTERNALS.
594 PLIST ::= ( MODULE-NAME FUNCTION * )
595 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
598 load_external_module (MPlist *plist, MPlist *externals)
603 MIMExternalModule *external;
607 if (MPLIST_MTEXT_P (plist))
608 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
609 else if (MPLIST_SYMBOL_P (plist))
610 module = MPLIST_SYMBOL (plist);
611 module_file = alloca (strlen (MSYMBOL_NAME (module))
612 + strlen (DLOPEN_SHLIB_EXT) + 1);
613 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
615 handle = dlopen (module_file, RTLD_NOW);
618 fprintf (stderr, "%s\n", dlerror ());
619 MERROR (MERROR_IM, -1);
621 func_list = mplist ();
622 MPLIST_DO (plist, MPLIST_NEXT (plist))
624 if (! MPLIST_SYMBOL_P (plist))
625 MERROR_GOTO (MERROR_IM, err_label);
626 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
628 MERROR_GOTO (MERROR_IM, err_label);
629 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
632 MSTRUCT_MALLOC (external, MERROR_IM);
633 external->handle = handle;
634 external->func_list = func_list;
635 mplist_add (externals, module, external);
640 M17N_OBJECT_UNREF (func_list);
645 /** Load a state from PLIST into a newly allocated state object.
647 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
648 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
649 MAPS is a plist of defined maps.
650 Return the state object. */
653 load_state (MPlist *plist, MPlist *maps, MSymbol language, MPlist *macros)
657 MSTRUCT_CALLOC (state, MERROR_IM);
658 if (! MPLIST_SYMBOL_P (plist))
659 MERROR (MERROR_IM, NULL);
660 state->name = MPLIST_SYMBOL (plist);
661 plist = MPLIST_NEXT (plist);
662 if (MPLIST_MTEXT_P (plist))
664 state->title = MPLIST_MTEXT (plist);
665 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
666 Mlanguage, language);
667 M17N_OBJECT_REF (state->title);
668 plist = MPLIST_NEXT (plist);
670 MSTRUCT_CALLOC (state->map, MERROR_IM);
671 MPLIST_DO (plist, plist)
672 if (! MPLIST_PLIST_P (plist)
673 || load_branch (MPLIST_PLIST (plist), maps, state->map, macros) < 0)
674 MERROR (MERROR_IM, NULL);
680 free_map (MIMMap *map)
684 M17N_OBJECT_UNREF (map->map_actions);
687 MPLIST_DO (plist, map->submaps)
688 free_map ((MIMMap *) MPLIST_VAL (plist));
689 M17N_OBJECT_UNREF (map->submaps);
691 M17N_OBJECT_UNREF (map->branch_actions);
695 /* Load an input method from PLIST into IM_INTO, and return it. */
698 load_input_method (MSymbol language, MSymbol name, MPlist *plist,
699 MInputMethodInfo *im_info)
703 MPlist *states = NULL;
704 MPlist *externals = NULL;
705 MPlist *macros = NULL;
708 for (; MPLIST_PLIST_P (plist); plist = MPLIST_NEXT (plist))
710 elt = MPLIST_PLIST (plist);
711 if (! MPLIST_SYMBOL_P (elt))
712 MERROR_GOTO (MERROR_IM, err);
713 if (MPLIST_SYMBOL (elt) == Mtitle)
715 elt = MPLIST_NEXT (elt);
716 if (MPLIST_MTEXT_P (elt))
718 title = MPLIST_MTEXT (elt);
719 M17N_OBJECT_REF (title);
722 MERROR_GOTO (MERROR_IM, err);
724 else if (MPLIST_SYMBOL (elt) == Mmap)
726 maps = mplist__from_alist (MPLIST_NEXT (elt));
728 MERROR_GOTO (MERROR_IM, err);
730 else if (MPLIST_SYMBOL (elt) == Mmacro)
733 MPLIST_DO (elt, MPLIST_NEXT (elt))
735 if (! MPLIST_PLIST_P (elt)
736 || load_macros (MPLIST_PLIST (elt), macros) < 0)
737 MERROR_GOTO (MERROR_IM, err);
740 else if (MPLIST_SYMBOL (elt) == Mmodule)
742 externals = mplist ();
743 MPLIST_DO (elt, MPLIST_NEXT (elt))
745 if (! MPLIST_PLIST_P (elt)
746 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
747 MERROR_GOTO (MERROR_IM, err);
750 else if (MPLIST_SYMBOL (elt) == Mstate)
753 MPLIST_DO (elt, MPLIST_NEXT (elt))
757 if (! MPLIST_PLIST_P (elt))
758 MERROR_GOTO (MERROR_IM, err);
759 state = load_state (MPLIST_PLIST (elt), maps, language, macros);
761 MERROR_GOTO (MERROR_IM, err);
762 mplist_put (states, state->name, state);
769 MPLIST_DO (elt, maps)
770 M17N_OBJECT_UNREF (MPLIST_VAL (elt));
771 M17N_OBJECT_UNREF (maps);
774 title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
775 MTEXT_FORMAT_US_ASCII);
776 im_info->title = title;
777 im_info->externals = externals;
778 im_info->macros = macros;
779 im_info->states = states;
785 MPLIST_DO (elt, maps)
786 M17N_OBJECT_UNREF (MPLIST_VAL (elt));
787 M17N_OBJECT_UNREF (maps);
790 M17N_OBJECT_UNREF (title);
793 MPLIST_DO (plist, states)
795 MIMState *state = (MIMState *) MPLIST_VAL (plist);
798 M17N_OBJECT_UNREF (state->title);
800 free_map (state->map);
803 M17N_OBJECT_UNREF (states);
807 MPLIST_DO (plist, externals)
809 MIMExternalModule *external = MPLIST_VAL (plist);
811 dlclose (external->handle);
812 M17N_OBJECT_UNREF (external->func_list);
814 MPLIST_KEY (plist) = Mt;
816 M17N_OBJECT_UNREF (externals);
823 static int take_action_list (MInputContext *ic, MPlist *action_list);
826 shift_state (MInputContext *ic, MSymbol state_name)
828 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
829 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
832 /* Find a state to shift to. If not found, shift to the initial
834 state = (MIMState *) mplist_get (im_info->states, state_name);
836 state = (MIMState *) MPLIST_VAL (im_info->states);
838 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
840 /* Enter the new state. */
841 ic_info->state = state;
842 ic_info->map = state->map;
843 ic_info->state_key_head = ic_info->key_head;
844 if (state == (MIMState *) MPLIST_VAL (im_info->states))
846 /* We have shifted to the initial state. */
849 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
850 Mcandidate_list, NULL, 0);
851 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
852 Mcandidate_index, NULL, 0);
853 mtext_cat (ic->produced, ic->preedit);
854 if ((mdebug__flag & mdebug_mask)
855 && mtext_nchars (ic->produced) > 0)
859 MDEBUG_PRINT (" (produced");
860 for (i = 0; i < mtext_nchars (ic->produced); i++)
861 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
864 mtext_reset (ic->preedit);
865 ic->candidate_list = NULL;
866 ic->candidate_show = 0;
867 ic->preedit_changed = ic->candidates_changed = 1;
868 MPLIST_DO (p, ic_info->markers)
871 memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
872 sizeof (int) * (ic_info->used - ic_info->state_key_head));
873 ic_info->used -= ic_info->state_key_head;
874 ic_info->state_key_head = ic_info->key_head = 0;
876 mtext_cpy (ic_info->preedit_saved, ic->preedit);
877 ic_info->state_pos = ic->cursor_pos;
878 ic->status = state->title;
880 ic->status = im_info->title;
881 ic->status_changed = 1;
882 if (ic_info->map == ic_info->state->map
883 && ic_info->map->map_actions)
885 MDEBUG_PRINT (" init-actions:");
886 take_action_list (ic, ic_info->map->map_actions);
890 /* Find a candidate group that contains a candidate number INDEX from
891 PLIST. Set START_INDEX to the first candidate number of the group,
892 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
893 candidate group number if they are non-NULL. If INDEX is -1, find
894 the last candidate group. */
897 find_candidates_group (MPlist *plist, int index,
898 int *start_index, int *end_index, int *group_index)
900 int i = 0, gidx = 0, len;
902 MPLIST_DO (plist, plist)
904 if (MPLIST_MTEXT_P (plist))
905 len = mtext_nchars (MPLIST_MTEXT (plist));
907 len = mplist_length (MPLIST_PLIST (plist));
908 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
914 *end_index = i + len;
926 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
928 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
930 int nchars = mt ? mtext_nchars (mt) : 1;
933 mtext_ins (ic->preedit, pos, mt);
935 mtext_ins_char (ic->preedit, pos, c, 1);
936 MPLIST_DO (markers, ic_info->markers)
937 if (MPLIST_INTEGER (markers) > pos)
938 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
939 if (ic->cursor_pos >= pos)
940 ic->cursor_pos += nchars;
941 ic->preedit_changed = 1;
946 preedit_delete (MInputContext *ic, int from, int to)
948 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
951 mtext_del (ic->preedit, from, to);
952 MPLIST_DO (markers, ic_info->markers)
954 if (MPLIST_INTEGER (markers) > to)
956 = (void *) (MPLIST_INTEGER (markers) - (to - from));
957 else if (MPLIST_INTEGER (markers) > from);
958 MPLIST_VAL (markers) = (void *) from;
960 if (ic->cursor_pos >= to)
961 ic->cursor_pos -= to - from;
962 else if (ic->cursor_pos > from)
963 ic->cursor_pos = from;
964 ic->preedit_changed = 1;
969 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
971 int code = marker_code (sym);
973 if (mt && (code == '[' || code == ']'))
977 if (code == '[' && current > 0)
979 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
983 else if (code == ']' && current < mtext_nchars (mt))
985 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
991 return (code == '<' ? 0
992 : code == '>' ? limit
993 : code == '-' ? current - 1
994 : code == '+' ? current + 1
995 : code == '=' ? current
996 : code - '0' > limit ? limit
1000 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1004 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1006 int from = mtext_property_start (prop);
1007 int to = mtext_property_end (prop);
1009 MPlist *candidate_list = mtext_property_value (prop);
1010 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1012 int ingroup_index = idx - start;
1015 preedit_delete (ic, from, to);
1016 if (MPLIST_MTEXT_P (group))
1018 mt = MPLIST_MTEXT (group);
1019 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1027 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1028 i++, plist = MPLIST_NEXT (plist));
1029 mt = MPLIST_MTEXT (plist);
1030 preedit_insert (ic, from, mt, 0);
1031 to = from + mtext_nchars (mt);
1033 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1034 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1035 ic->cursor_pos = to;
1040 take_action_list (MInputContext *ic, MPlist *action_list)
1042 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1043 MPlist *candidate_list = ic->candidate_list;
1044 int candidate_index = ic->candidate_index;
1045 int candidate_show = ic->candidate_show;
1046 MTextProperty *prop;
1048 MPLIST_DO (action_list, action_list)
1054 if (MPLIST_MTEXT_P (action_list)
1055 || MPLIST_INTEGER_P (action_list))
1056 name = Minsert, args = action_list;
1057 else if (MPLIST_PLIST_P (action_list)
1058 && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list))
1059 || MPLIST_PLIST_P (MPLIST_PLIST (action_list))))
1060 name = Minsert, args = action_list;
1063 action = MPLIST_PLIST (action_list);
1064 name = MPLIST_SYMBOL (action);
1065 args = MPLIST_NEXT (action);
1068 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1069 if (name == Minsert)
1071 if (MPLIST_MTEXT_P (args))
1072 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1073 else if (MPLIST_INTEGER_P (args))
1074 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1075 else if (MPLIST_SYMBOL_P (args))
1077 int c = integer_value (ic, args);
1079 if (c >= 0 && c <= MCHAR_MAX)
1080 preedit_insert (ic, ic->cursor_pos, NULL, c);
1087 args = MPLIST_PLIST (args);
1088 if (MPLIST_MTEXT_P (args))
1090 preedit_insert (ic, ic->cursor_pos, NULL,
1091 mtext_ref_char (MPLIST_MTEXT (args), 0));
1096 mt = MPLIST_MTEXT (MPLIST_PLIST (args));
1097 preedit_insert (ic, ic->cursor_pos, mt, 0);
1098 len = mtext_nchars (mt);
1100 mtext_put_prop (ic->preedit,
1101 ic->cursor_pos - len, ic->cursor_pos,
1102 Mcandidate_list, args);
1103 mtext_put_prop (ic->preedit,
1104 ic->cursor_pos - len, ic->cursor_pos,
1105 Mcandidate_index, (void *) 0);
1108 else if (name == Mselect)
1111 int code, idx, gindex;
1112 int pos = ic->cursor_pos;
1116 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1119 if (MPLIST_SYMBOL_P (args))
1121 code = marker_code (MPLIST_SYMBOL (args));
1127 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1128 group = find_candidates_group (mtext_property_value (prop), idx,
1129 &start, &end, &gindex);
1131 if (code != '[' && code != ']')
1135 ? new_index (NULL, ic->candidate_index - start,
1136 end - start - 1, MPLIST_SYMBOL (args),
1138 : MPLIST_INTEGER (args)));
1141 find_candidates_group (mtext_property_value (prop), -1,
1146 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1151 int ingroup_index = idx - start;
1154 group = mtext_property_value (prop);
1155 len = mplist_length (group);
1168 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1169 idx += (MPLIST_MTEXT_P (group)
1170 ? mtext_nchars (MPLIST_MTEXT (group))
1171 : mplist_length (MPLIST_PLIST (group)));
1172 len = (MPLIST_MTEXT_P (group)
1173 ? mtext_nchars (MPLIST_MTEXT (group))
1174 : mplist_length (MPLIST_PLIST (group)));
1175 if (ingroup_index >= len)
1176 ingroup_index = len - 1;
1177 idx += ingroup_index;
1179 update_candidate (ic, prop, idx);
1181 else if (name == Mshow)
1182 ic->candidate_show = 1;
1183 else if (name == Mhide)
1184 ic->candidate_show = 0;
1185 else if (name == Mdelete)
1187 int len = mtext_nchars (ic->preedit);
1188 int to = (MPLIST_SYMBOL_P (args)
1189 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1191 : MPLIST_INTEGER (args));
1197 if (to < ic->cursor_pos)
1198 preedit_delete (ic, to, ic->cursor_pos);
1199 else if (to > ic->cursor_pos)
1200 preedit_delete (ic, ic->cursor_pos, to);
1202 else if (name == Mmove)
1204 int len = mtext_nchars (ic->preedit);
1206 = (MPLIST_SYMBOL_P (args)
1207 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1209 : MPLIST_INTEGER (args));
1215 if (pos != ic->cursor_pos)
1217 ic->cursor_pos = pos;
1218 ic->preedit_changed = 1;
1221 else if (name == Mmark)
1223 int code = marker_code (MPLIST_SYMBOL (args));
1226 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1227 (void *) ic->cursor_pos);
1229 else if (name == Mpushback)
1231 if (MPLIST_INTEGER_P (args))
1233 int num = MPLIST_INTEGER (args);
1236 ic_info->key_head -= num;
1238 ic_info->key_head = num;
1239 if (ic_info->key_head > ic_info->used)
1240 ic_info->key_head = ic_info->used;
1242 else if (MPLIST_MTEXT_P (args))
1244 MText *mt = MPLIST_MTEXT (args);
1245 int i, len = mtext_nchars (mt);
1248 ic_info->key_head--;
1249 for (i = 0; i < len; i++)
1251 key = one_char_symbol[MTEXT_DATA (mt)[i]];
1252 if (ic_info->key_head + i < ic_info->used)
1253 ic_info->keys[ic_info->key_head + i] = key;
1255 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1260 MPlist *plist = MPLIST_PLIST (args), *pl;
1264 ic_info->key_head--;
1266 MPLIST_DO (pl, plist)
1268 key = MPLIST_SYMBOL (pl);
1269 if (ic_info->key_head < ic_info->used)
1270 ic_info->keys[ic_info->key_head + i] = key;
1272 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1277 else if (name == Mcall)
1279 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1280 MIMExternalFunc func = NULL;
1281 MSymbol module, func_name;
1282 MPlist *func_args, *val;
1285 module = MPLIST_SYMBOL (args);
1286 args = MPLIST_NEXT (args);
1287 func_name = MPLIST_SYMBOL (args);
1289 if (im_info->externals)
1291 MIMExternalModule *external
1292 = (MIMExternalModule *) mplist_get (im_info->externals,
1295 func = (MIMExternalFunc) mplist_get (external->func_list,
1300 func_args = mplist ();
1301 mplist_add (func_args, Mt, ic);
1302 MPLIST_DO (args, MPLIST_NEXT (args))
1306 if (MPLIST_KEY (args) == Msymbol
1307 && MPLIST_KEY (args) != Mnil
1308 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1310 code = new_index (ic, ic->cursor_pos,
1311 mtext_nchars (ic->preedit),
1312 MPLIST_SYMBOL (args), ic->preedit);
1313 mplist_add (func_args, Minteger, (void *) code);
1316 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1318 val = (func) (func_args);
1319 M17N_OBJECT_UNREF (func_args);
1320 if (val && ! MPLIST_TAIL_P (val))
1321 ret = take_action_list (ic, val);
1322 M17N_OBJECT_UNREF (val);
1326 else if (name == Mshift)
1328 shift_state (ic, MPLIST_SYMBOL (args));
1330 else if (name == Mundo)
1332 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1335 mtext_reset (ic->preedit);
1336 mtext_reset (ic_info->preedit_saved);
1337 ic->cursor_pos = ic_info->state_pos = 0;
1338 ic_info->state_key_head = ic_info->key_head = 0;
1340 if (ic_info->used < 0)
1345 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1350 else if (name == Mset || name == Madd || name == Msub
1351 || name == Mmul || name == Mdiv)
1353 MSymbol sym = MPLIST_SYMBOL (args);
1354 int val1 = (int) mplist_get (ic_info->vars, sym), val2;
1356 args = MPLIST_NEXT (args);
1357 val2 = integer_value (ic, args);
1360 else if (name == Madd)
1362 else if (name == Msub)
1364 else if (name == Mmul)
1368 mplist_put (ic_info->vars, sym, (void *) val1);
1369 MDEBUG_PRINT2 ("(%s=%d)", MSYMBOL_NAME (sym), val1);
1371 else if (name == Mequal || name == Mless || name == Mgreater)
1374 MPlist *actions1, *actions2;
1377 val1 = integer_value (ic, args);
1378 args = MPLIST_NEXT (args);
1379 val2 = integer_value (ic, args);
1380 args = MPLIST_NEXT (args);
1381 actions1 = MPLIST_PLIST (args);
1382 args = MPLIST_NEXT (args);
1383 if (MPLIST_TAIL_P (args))
1386 actions2 = MPLIST_PLIST (args);
1387 MDEBUG_PRINT2 ("(%d,%d)", val1, val2);
1388 if (name == Mequal ? val1 == val2
1389 : name == Mless ? val1 < val2
1392 MDEBUG_PRINT ("ok");
1393 ret = take_action_list (ic, actions1);
1397 MDEBUG_PRINT ("no");
1399 ret = take_action_list (ic, actions2);
1406 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1410 && (actions = mplist_get (im_info->macros, name)))
1412 if (take_action_list (ic, actions) < 0)
1419 ic->candidate_list = NULL;
1420 if (ic->cursor_pos > 0
1421 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
1424 ic->candidate_list = mtext_property_value (prop);
1426 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
1428 ic->candidate_from = mtext_property_start (prop);
1429 ic->candidate_to = mtext_property_end (prop);
1432 ic->candidates_changed |= (candidate_list != ic->candidate_list
1433 || candidate_index != ic->candidate_index
1434 || candidate_show != ic->candidate_show);
1439 /* Handle the input key KEY in the current state and map specified in
1440 the input context IC. If KEY is handled correctly, return 0.
1441 Otherwise, return -1. */
1444 handle_key (MInputContext *ic)
1446 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1447 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1448 MIMMap *map = ic_info->map;
1449 MIMMap *submap = NULL;
1450 MSymbol key = ic_info->keys[ic_info->key_head];
1453 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
1454 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
1460 submap = mplist_get (map->submaps, key);
1461 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
1462 submap = mplist_get (map->submaps, alias);
1467 MDEBUG_PRINT (" submap-found");
1468 mtext_cpy (ic->preedit, ic_info->preedit_saved);
1469 ic->cursor_pos = ic_info->state_pos;
1470 ic_info->key_head++;
1471 ic_info->map = map = submap;
1472 if (map->map_actions)
1474 MDEBUG_PRINT (" map-actions:");
1475 if (take_action_list (ic, map->map_actions) < 0)
1477 MDEBUG_PRINT ("\n");
1481 else if (map->submaps)
1483 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
1485 MSymbol key = ic_info->keys[i];
1486 char *name = msymbol_name (key);
1488 if (! name[0] || ! name[1])
1489 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
1491 ic->preedit_changed = 1;
1494 /* If this is the terminal map or we have shifted to another
1495 state, perform branch actions (if any). */
1496 if (! map->submaps || map != ic_info->map)
1498 if (map->branch_actions)
1500 MDEBUG_PRINT (" branch-actions:");
1501 if (take_action_list (ic, map->branch_actions) < 0)
1503 MDEBUG_PRINT ("\n");
1507 /* If MAP is still not the root map, shift to the current
1509 if (ic_info->map != ic_info->state->map)
1510 shift_state (ic, ic_info->state->name);
1515 /* MAP can not handle KEY. */
1517 /* If MAP is the root map of the initial state, it means that
1518 the current input method can not handle KEY. */
1519 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
1521 MDEBUG_PRINT (" unhandled\n");
1525 if (map != ic_info->state->map)
1527 /* If MAP is not the root map... */
1528 /* If MAP has branch actions, perform them. */
1529 if (map->branch_actions)
1531 MDEBUG_PRINT (" branch-actions:");
1532 take_action_list (ic, map->branch_actions);
1534 /* If MAP is still not the root map, shift to the current
1536 if (ic_info->map != ic_info->state->map)
1538 shift_state (ic, ic_info->state->name);
1539 /* If MAP has branch_actions, perform them. */
1540 if (ic_info->map->branch_actions)
1542 MDEBUG_PRINT (" init-actions:");
1543 take_action_list (ic, ic_info->map->branch_actions);
1549 /* MAP is the root map, perform branch actions (if any) or
1550 shift to the initial state. */
1551 if (map->branch_actions)
1553 MDEBUG_PRINT (" branch-actions:");
1554 take_action_list (ic, map->branch_actions);
1558 ((MIMState *) MPLIST_VAL (im_info->states))->name);
1561 MDEBUG_PRINT ("\n");
1566 reset_ic (MInputContext *ic, MSymbol ignore)
1568 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1569 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1571 if (im_info->states)
1572 /* Shift to the initial state. */
1573 shift_state (ic, Mnil);
1575 ic_info->state = NULL;
1576 MLIST_RESET (ic_info);
1577 ic_info->map = ic_info->state ? ic_info->state->map : NULL;
1578 ic_info->state_key_head = ic_info->key_head = 0;
1579 ic_info->key_unhandled = 0;
1580 ic->cursor_pos = ic_info->state_pos = 0;
1581 ic->status = ic_info->state ? ic_info->state->title : NULL;
1583 ic->status = im_info->title;
1584 ic->candidate_list = NULL;
1585 ic->candidate_show = 0;
1586 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1;
1590 open_im (MInputMethod *im)
1593 MInputMethodInfo *im_info;
1597 mdb = mdatabase_find (Minput_method, im->language, im->name, Mnil);
1600 plist = mdatabase_load (mdb);
1602 MERROR (MERROR_IM, -1);
1603 MSTRUCT_CALLOC (im_info, MERROR_IM);
1605 result = load_input_method (im->language, im->name, plist, im_info);
1606 M17N_OBJECT_UNREF (plist);
1608 MERROR (MERROR_IM, -1);
1613 close_im (MInputMethod *im)
1615 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1619 M17N_OBJECT_UNREF (im_info->title);
1620 if (im_info->states)
1622 MPLIST_DO (plist, im_info->states)
1624 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1627 M17N_OBJECT_UNREF (state->title);
1629 free_map (state->map);
1632 M17N_OBJECT_UNREF (im_info->states);
1635 if (im_info->macros)
1637 MPLIST_DO (plist, im_info->macros)
1638 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1639 M17N_OBJECT_UNREF (im_info->macros);
1642 if (im_info->externals)
1644 MPLIST_DO (plist, im_info->externals)
1646 MIMExternalModule *external = MPLIST_VAL (plist);
1648 dlclose (external->handle);
1649 M17N_OBJECT_UNREF (external->func_list);
1651 MPLIST_KEY (plist) = Mt;
1653 M17N_OBJECT_UNREF (im_info->externals);
1661 create_ic (MInputContext *ic)
1663 MInputMethod *im = ic->im;
1664 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1665 MInputContextInfo *ic_info;
1668 ic_info = (MInputContextInfo *) ic->info;
1671 MSTRUCT_CALLOC (ic_info, MERROR_IM);
1674 MLIST_INIT1 (ic_info, keys, 8);
1675 ic_info->markers = mplist ();
1676 ic_info->vars = mplist ();
1677 ic_info->preedit_saved = mtext ();
1678 if (im_info->externals)
1680 MPlist *func_args = mplist (), *plist;
1682 mplist_add (func_args, Mt, ic);
1683 MPLIST_DO (plist, im_info->externals)
1685 MIMExternalModule *external = MPLIST_VAL (plist);
1686 MIMExternalFunc func
1687 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
1692 M17N_OBJECT_UNREF (func_args);
1694 reset_ic (ic, Mnil);
1699 destroy_ic (MInputContext *ic)
1701 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1702 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1704 if (im_info->externals)
1706 MPlist *func_args = mplist (), *plist;
1708 mplist_add (func_args, Mt, ic);
1709 MPLIST_DO (plist, im_info->externals)
1711 MIMExternalModule *external = MPLIST_VAL (plist);
1712 MIMExternalFunc func
1713 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
1718 M17N_OBJECT_UNREF (func_args);
1720 MLIST_FREE1 (ic_info, keys);
1721 M17N_OBJECT_UNREF (ic_info->preedit_saved);
1722 M17N_OBJECT_UNREF (ic_info->markers);
1723 M17N_OBJECT_UNREF (ic_info->vars);
1728 /** Handle the input key KEY in the current state and map of IC->info.
1729 If KEY is handled but no text is produced, return 0, otherwise
1735 filter (MInputContext *ic, MSymbol key, void *arg)
1737 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1738 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1741 if (! ic_info->state)
1743 ic_info->key_unhandled = 1;
1746 mtext_reset (ic->produced);
1747 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
1748 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1749 ic_info->key_unhandled = 0;
1751 if (handle_key (ic) < 0)
1753 /* KEY was not handled. Reset the status and break the
1755 reset_ic (ic, Mnil);
1756 /* This forces returning 1. */
1757 ic_info->key_unhandled = 1;
1763 reset_ic (ic, Mnil);
1764 ic_info->key_unhandled = 1;
1767 /* Break the loop if all keys were handled. */
1768 } while (ic_info->key_head < ic_info->used);
1770 /* If the current map is the root of the initial state, we should
1771 produce any preedit text in ic->produced. */
1772 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
1773 && mtext_nchars (ic->preedit) > 0)
1774 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1776 if (mtext_nchars (ic->produced) > 0)
1778 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
1781 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1782 Mlanguage, ic->im->language);
1785 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
1789 /** Return 1 if the last event or key was not handled, otherwise
1792 There is no need of looking up because ic->produced should already
1793 contain the produced text (if any).
1798 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1800 mtext_cat (mt, ic->produced);
1801 mtext_reset (ic->produced);
1802 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
1805 static MPlist *load_im_info_keys;
1808 load_im_info (MSymbol language, MSymbol name, MSymbol key)
1813 if (language == Mnil || name == Mnil)
1814 MERROR (MERROR_IM, NULL);
1816 mdb = mdatabase_find (Minput_method, language, name, Mnil);
1818 MERROR (MERROR_IM, NULL);
1819 mplist_push (load_im_info_keys, key, Mt);
1820 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
1821 mplist_pop (load_im_info_keys);
1826 /* Input method command handler. */
1828 /* List of all (global and local) commands.
1829 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
1830 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
1831 Global commands are storead as (t (t COMMAND ...)) */
1832 static MPlist *command_list;
1834 /* Check if PLIST is a valid command key sequence.
1835 PLIST must be NULL or:
1836 [ symbol:KEY | integer:KEY ] ... */
1839 check_command_keyseq (MPlist *plist)
1843 MPLIST_DO (plist, plist)
1845 if (MPLIST_SYMBOL_P (plist))
1847 else if (MPLIST_INTEGER_P (plist))
1849 int n = MPLIST_INTEGER (plist);
1853 MPLIST_KEY (plist) = Msymbol;
1854 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
1863 get_description_advance (MPlist *plist)
1868 if (! MPLIST_MTEXT_P (plist))
1870 mt = mplist_pop (plist);
1871 pos = mtext_chr (mt, '\n');
1874 MText *detail = mtext_copy (mtext (), 0, mt, pos + 1, mtext_nchars (mt));
1875 mtext_del (mt, pos, mtext_nchars (mt));
1876 mtext_put_prop (mt, 0, pos, Mdetail_text, detail);
1877 M17N_OBJECT_UNREF (detail);
1883 parse_command_list (MPlist *plist, MPlist *global_list)
1885 MPlist *val = mplist ();
1887 /* PLIST ::= (sym:CMD mtext:DESCRIPTION ? (sym:KEY ...) ...) ... */
1888 MPLIST_DO (plist, plist)
1892 MPlist *this_val, *pl, *p;
1894 if (! MPLIST_PLIST_P (plist))
1896 pl = MPLIST_PLIST (plist);
1897 if (! MPLIST_SYMBOL_P (pl))
1899 cmd = MPLIST_SYMBOL (pl);
1900 pl = MPLIST_NEXT (pl);
1901 mt = get_description_advance (pl);
1902 this_val = mplist ();
1904 if (! mt && global_list)
1906 /* Get the description from global_list. */
1907 p = mplist_get (global_list, cmd);
1908 if (p && MPLIST_MTEXT (p))
1910 mt = MPLIST_MTEXT (p);
1911 M17N_OBJECT_REF (mt);
1916 mplist_add (this_val, Mtext, mt);
1917 M17N_OBJECT_UNREF (mt);
1919 /* PL ::= (sym:KEY ...) ... */
1922 if (MPLIST_PLIST_P (pl)
1923 && check_command_keyseq (MPLIST_PLIST (pl)) >= 0)
1924 /* All the elements are valid keys. */
1925 mplist_add (this_val, Mplist, MPLIST_PLIST (pl));
1928 mplist_put (val, cmd, this_val);
1934 get_command_list (MSymbol language, MSymbol name)
1940 language = name = Mt;
1944 MDatabase *mdb = mdatabase_find (msymbol ("input"), M_command,
1947 if (mdb && (plist = mdatabase_load (mdb)))
1949 pl = parse_command_list (plist, NULL);
1950 M17N_OBJECT_UNREF (plist);
1955 mplist_add (plist, Mt, pl);
1956 command_list = mplist ();
1957 mplist_add (command_list, Mt, plist);
1960 per_lang = mplist_get (command_list, language);
1963 plist = mplist_find_by_key (per_lang, name);
1965 return (MPLIST_VAL (plist));
1969 per_lang = mplist ();
1970 mplist_add (command_list, language, per_lang);
1973 /* Now we are sure that we are loading per-im info. */
1974 /* Get the global command list. */
1975 plist = load_im_info (language, name, M_command);
1976 if (! plist || mplist_key (plist) == Mnil)
1980 mplist_add (per_lang, name, plist);
1983 pl = parse_command_list (mplist_value (plist),
1984 mplist_get ((MPlist *) mplist_get (command_list, Mt),
1986 M17N_OBJECT_UNREF (plist);
1987 mplist_put (per_lang, name, pl);
1992 /* Input method variable handler. */
1994 /* List of all variables.
1995 (LANG:(IM-NAME:(VAR ...) ...) ...) ...
1996 VAR is VAR-NAME:(mtext:DESCRIPTION TYPE:VALUE ...)) */
1998 static MPlist *variable_list;
2001 parse_variable_list (MPlist *plist)
2003 MPlist *val = mplist (), *pl, *p;
2005 /* PLIST ::= (sym:VAR mtext:DESCRIPTION TYPE:INIT-VAL ...) ... */
2006 MPLIST_DO (plist, plist)
2012 if (! MPLIST_PLIST_P (plist))
2014 pl = MPLIST_PLIST (plist);
2015 if (! MPLIST_SYMBOL_P (pl))
2017 var = MPLIST_SYMBOL (pl);
2018 pl = MPLIST_NEXT (pl);
2019 mt = get_description_advance (pl);
2020 if (! mt || MPLIST_TAIL_P (pl))
2022 this_val = mplist ();
2023 mplist_add (this_val, Mtext, mt);
2024 M17N_OBJECT_UNREF (mt);
2025 type = MPLIST_KEY (pl);
2026 mplist_add (this_val, type, MPLIST_VAL (pl));
2027 MPLIST_DO (pl, MPLIST_NEXT (pl))
2029 if (type != MPLIST_KEY (pl)
2030 && (type != Minteger || ! MPLIST_PLIST_P (pl)))
2032 if (MPLIST_PLIST_P (pl))
2034 MPLIST_DO (p, MPLIST_PLIST (pl))
2035 if (! MPLIST_INTEGER_P (p))
2037 if (! MPLIST_TAIL_P (p))
2040 mplist_add (this_val, MPLIST_KEY (pl), MPLIST_VAL (pl));
2043 mplist_put (val, var, this_val);
2050 get_variable_list (MSymbol language, MSymbol name)
2055 if (language == Mnil || name == Mnil)
2056 MERROR (MERROR_IM, NULL);
2057 if (! variable_list)
2058 variable_list = mplist ();
2059 per_lang = mplist_get (variable_list, language);
2062 plist = mplist_find_by_key (per_lang, name);
2064 return (MPLIST_VAL (plist));
2068 per_lang = mplist ();
2069 mplist_add (variable_list, language, per_lang);
2071 plist = load_im_info (language, name, M_variable);
2072 if (! plist || mplist_key (plist) == Mnil)
2076 mplist_add (per_lang, name, plist);
2079 pl = parse_variable_list (mplist_value (plist));
2080 M17N_OBJECT_UNREF (plist);
2081 mplist_put (per_lang, name, pl);
2086 input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
2088 MPlist *plist, *pl, *p;
2089 char path[PATH_MAX];
2091 /* Cancel the hook. */
2092 msymbol_put (tag0, M_database_hook, NULL);
2095 mplist_push (load_im_info_keys, M_description, Mt);
2096 MPLIST_DO (plist, mdatabase__dir_list)
2098 char *dirname = (char *) MPLIST_VAL (plist);
2100 DIR *dir = opendir (dirname);
2105 dirlen = strlen (dirname);
2106 strcpy (path, dirname);
2107 while ((dp = readdir (dir)) != NULL)
2109 /* We can't trust dp->d_nameln. */
2110 int len = strlen (dp->d_name);
2113 if (len > 4 && memcmp (dp->d_name + len - 4, ".mim", 4) == 0)
2115 strcpy (path + dirlen, dp->d_name);
2116 fp = fopen (path, "r");
2119 pl = mplist__from_file (fp, load_im_info_keys);
2123 if (MPLIST_PLIST_P (pl))
2125 p = MPLIST_PLIST (pl);
2126 p = MPLIST_NEXT (p);
2127 if (MPLIST_SYMBOL_P (p))
2129 tag1 = MPLIST_VAL (p);
2130 p = MPLIST_NEXT (p);
2131 if (MPLIST_SYMBOL_P (p))
2133 tag2 = MPLIST_VAL (p);
2134 mdatabase_define (tag0, tag1, tag2, tag3,
2139 M17N_OBJECT_UNREF (pl);
2145 mplist_pop (load_im_info_keys);
2149 /* Support functions for mdebug_dump_im. */
2152 dump_im_map (MPlist *map_list, int indent)
2155 MSymbol key = MPLIST_KEY (map_list);
2156 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2158 prefix = (char *) alloca (indent + 1);
2159 memset (prefix, 32, indent);
2160 prefix[indent] = '\0';
2162 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2163 if (map->map_actions)
2164 mdebug_dump_plist (map->map_actions, indent + 2);
2167 MPLIST_DO (map_list, map->submaps)
2169 fprintf (stderr, "\n%s ", prefix);
2170 dump_im_map (map_list, indent + 2);
2173 if (map->branch_actions)
2175 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2176 mdebug_dump_plist (map->branch_actions, indent + 4);
2177 fprintf (stderr, ")");
2179 fprintf (stderr, ")");
2184 dump_im_state (MIMState *state, int indent)
2189 prefix = (char *) alloca (indent + 1);
2190 memset (prefix, 32, indent);
2191 prefix[indent] = '\0';
2193 fprintf (stderr, "(%s", msymbol_name (state->name));
2194 if (state->map->submaps)
2196 MPLIST_DO (map_list, state->map->submaps)
2198 fprintf (stderr, "\n%s ", prefix);
2199 dump_im_map (map_list, indent + 2);
2202 fprintf (stderr, ")");
2211 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2212 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2213 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2214 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2215 char buf[6], buf2[256];
2219 Minput_method = msymbol ("input-method");
2220 msymbol_put (Minput_method, M_database_hook, (void *) input_method_hook);
2221 Minput_driver = msymbol ("input-driver");
2222 Mtitle = msymbol ("title");
2223 Mmacro = msymbol ("macro");
2224 Mmodule = msymbol ("module");
2225 Mmap = msymbol ("map");
2226 Mstate = msymbol ("state");
2227 Minsert = msymbol ("insert");
2228 Mdelete = msymbol ("delete");
2229 Mmove = msymbol ("move");
2230 Mmark = msymbol ("mark");
2231 Mpushback = msymbol ("pushback");
2232 Mundo = msymbol ("undo");
2233 Mcall = msymbol ("call");
2234 Mshift = msymbol ("shift");
2235 Mselect = msymbol ("select");
2236 Mshow = msymbol ("show");
2237 Mhide = msymbol ("hide");
2238 Mset = msymbol ("set");
2239 Madd = msymbol ("add");
2240 Msub = msymbol ("sub");
2241 Mmul = msymbol ("mul");
2242 Mdiv = msymbol ("div");
2243 Mequal = msymbol ("=");
2244 Mless = msymbol ("<");
2245 Mgreater = msymbol (">");
2247 Minput_preedit_start = msymbol ("input-preedit-start");
2248 Minput_preedit_done = msymbol ("input-preedit-done");
2249 Minput_preedit_draw = msymbol ("input-preedit-draw");
2250 Minput_status_start = msymbol ("input-status-start");
2251 Minput_status_done = msymbol ("input-status-done");
2252 Minput_status_draw = msymbol ("input-status-draw");
2253 Minput_candidates_start = msymbol ("input-candidates-start");
2254 Minput_candidates_done = msymbol ("input-candidates-done");
2255 Minput_candidates_draw = msymbol ("input-candidates-draw");
2256 Minput_set_spot = msymbol ("input-set-spot");
2257 Minput_focus_move = msymbol ("input-focus-move");
2258 Minput_focus_in = msymbol ("input-focus-in");
2259 Minput_focus_out = msymbol ("input-focus-out");
2260 Minput_toggle = msymbol ("input-toggle");
2261 Minput_reset = msymbol ("input-reset");
2263 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2264 Mcandidate_index = msymbol (" candidate-index");
2266 Minit = msymbol ("init");
2267 Mfini = msymbol ("fini");
2269 M_key_alias = msymbol (" key-alias");
2270 M_description = msymbol ("description");
2271 M_command = msymbol ("command");
2272 M_variable = msymbol ("variable");
2274 Mdetail_text = msymbol_as_managing_key (" detail-text");
2276 load_im_info_keys = mplist ();
2277 plist = mplist_add (load_im_info_keys, Mmap, Mnil);
2278 plist = mplist_add (plist, Mstate, Mnil);
2279 plist = mplist_add (plist, Mmacro, Mnil);
2280 plist = mplist_add (plist, Mmodule, Mnil);
2285 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2287 one_char_symbol[i] = msymbol (buf);
2289 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (key_names[i]));
2291 for (buf[2] = i; i < 127; i++, buf[2]++)
2292 one_char_symbol[i] = msymbol (buf + 2);
2293 one_char_symbol[i++] = msymbol ("Delete");
2299 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2301 one_char_symbol[i] = msymbol (buf);
2302 if (key_names[i - 128])
2304 strcpy (buf2 + 2, key_names[i - 128]);
2305 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2308 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2309 one_char_symbol[i] = msymbol (buf + 2);
2310 one_char_symbol[i] = msymbol ("M-Delete");
2312 command_list = variable_list = NULL;
2314 minput_default_driver.open_im = open_im;
2315 minput_default_driver.close_im = close_im;
2316 minput_default_driver.create_ic = create_ic;
2317 minput_default_driver.destroy_ic = destroy_ic;
2318 minput_default_driver.filter = filter;
2319 minput_default_driver.lookup = lookup;
2320 minput_default_driver.callback_list = mplist ();
2321 mplist_put (minput_default_driver.callback_list, Minput_reset,
2323 minput_driver = &minput_default_driver;
2330 MPlist *par_lang, *par_im, *p;
2334 MPLIST_DO (par_lang, command_list)
2336 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2338 MPLIST_DO (p, MPLIST_VAL (par_im))
2339 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2340 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2342 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2344 M17N_OBJECT_UNREF (command_list);
2345 command_list = NULL;
2349 MPLIST_DO (par_lang, variable_list)
2351 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2353 MPLIST_DO (p, MPLIST_VAL (par_im))
2354 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2355 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2357 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2359 M17N_OBJECT_UNREF (variable_list);
2360 variable_list = NULL;
2363 if (minput_default_driver.callback_list)
2365 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2366 minput_default_driver.callback_list = NULL;
2368 if (minput_driver->callback_list)
2370 M17N_OBJECT_UNREF (minput_driver->callback_list);
2371 minput_driver->callback_list = NULL;
2374 M17N_OBJECT_UNREF (load_im_info_keys);
2378 minput__callback (MInputContext *ic, MSymbol command)
2380 if (ic->im->driver.callback_list)
2382 MInputCallbackFunc func
2383 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2387 (func) (ic, command);
2392 minput__char_to_key (int c)
2394 if (c < 0 || c >= 0x100)
2397 return one_char_symbol[c];
2401 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2406 /*** @addtogroup m17nInputMethod */
2411 @name Variables: Predefined symbols for callback commands.
2413 These are the predefined symbols that are used as the @c COMMAND
2414 argument of callback functions of an input method driver (see
2415 #MInputDriver::callback_list ). */
2417 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2419 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2420 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2425 MSymbol Minput_preedit_start;
2426 MSymbol Minput_preedit_done;
2427 MSymbol Minput_preedit_draw;
2428 MSymbol Minput_status_start;
2429 MSymbol Minput_status_done;
2430 MSymbol Minput_status_draw;
2431 MSymbol Minput_candidates_start;
2432 MSymbol Minput_candidates_done;
2433 MSymbol Minput_candidates_draw;
2434 MSymbol Minput_set_spot;
2435 MSymbol Minput_focus_move;
2436 MSymbol Minput_focus_in;
2437 MSymbol Minput_focus_out;
2438 MSymbol Minput_toggle;
2439 MSymbol Minput_reset;
2445 @brief The default driver for internal input methods.
2447 The variable #minput_default_driver is the default driver for
2448 internal input methods.
2450 The member MInputDriver::open_im () searches the m17n database for
2451 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2452 $NAME\> and loads it.
2454 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2455 programmers responsibility to set it to a plist of proper callback
2456 functions. Otherwise, no feedback information (e.g. preedit text)
2457 can be shown to users.
2459 The macro M17N_INIT () sets the variable #minput_driver to the
2460 pointer to this driver so that all internal input methods use it.
2462 Therefore, unless @c minput_driver is set differently, the driver
2463 dependent arguments $ARG of the functions whose name begin with
2464 "minput_" are all ignored. */
2467 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2469 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2471 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2472 \< #Minput_method, $LANGUAGE, $NAME\>
2473 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2475 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2476 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2477 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2478 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2480 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2481 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2483 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2484 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2486 MInputDriver minput_default_driver;
2490 @brief The driver for internal input methods.
2492 The variable #minput_driver is a pointer to the input method
2493 driver that is used by internal input methods. The macro
2494 M17N_INIT () initializes it to a pointer to #minput_default_driver
2495 if <m17n<EM></EM>.h> is included. */
2497 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
2499 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
2500 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
2501 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
2502 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
2504 MInputDriver *minput_driver;
2506 MSymbol Minput_driver;
2511 @brief Open an input method.
2513 The minput_open_im () function opens an input method that matches
2514 language $LANGUAGE and name $NAME, and returns a pointer to the
2515 input method object newly allocated.
2517 This function at first decides an driver for the input method as
2520 If $LANGUAGE is not #Mnil, the driver pointed by the variable
2521 #minput_driver is used.
2523 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
2524 driver pointed to by the property value is used to open the input
2525 method. If $NAME has no such property, @c NULL is returned.
2527 Then, the member MInputDriver::open_im () of the driver is
2530 $ARG is set in the member @c arg of the structure MInputMethod so
2531 that the driver can refer to it. */
2534 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
2536 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
2537 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2539 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
2541 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
2542 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
2544 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
2545 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
2546 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2548 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
2550 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
2552 @latexonly \IPAlabel{minput_open} @endlatexonly
2557 minput_open_im (MSymbol language, MSymbol name, void *arg)
2560 MInputDriver *driver;
2562 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
2563 msymbol_name (language), msymbol_name (name));
2565 driver = minput_driver;
2568 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
2570 MERROR (MERROR_IM, NULL);
2573 MSTRUCT_CALLOC (im, MERROR_IM);
2574 im->language = language;
2577 im->driver = *driver;
2578 if ((*im->driver.open_im) (im) < 0)
2580 MDEBUG_PRINT (" failed\n");
2584 MDEBUG_PRINT (" ok\n");
2591 @brief Close an input method.
2593 The minput_close_im () function closes the input method $IM, which
2594 must have been created by minput_open_im (). */
2597 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
2599 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
2600 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
2603 minput_close_im (MInputMethod *im)
2605 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
2606 msymbol_name (im->name), msymbol_name (im->language));
2607 (*im->driver.close_im) (im);
2609 MDEBUG_PRINT (" done\n");
2615 @brief Create an input context.
2617 The minput_create_ic () function creates an input context object
2618 associated with input method $IM, and calls callback functions
2619 corresponding to #Minput_preedit_start, #Minput_status_start, and
2620 #Minput_status_draw in this order.
2624 If an input context is successfully created, minput_create_ic ()
2625 returns a pointer to it. Otherwise it returns @c NULL. */
2628 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
2630 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
2631 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
2632 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
2633 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2637 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
2638 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2642 minput_create_ic (MInputMethod *im, void *arg)
2646 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
2647 msymbol_name (im->name), msymbol_name (im->language));
2648 MSTRUCT_CALLOC (ic, MERROR_IM);
2651 ic->preedit = mtext ();
2652 ic->candidate_list = NULL;
2653 ic->produced = mtext ();
2654 ic->spot.x = ic->spot.y = 0;
2656 ic->plist = mplist ();
2657 if ((*im->driver.create_ic) (ic) < 0)
2659 MDEBUG_PRINT (" failed\n");
2660 M17N_OBJECT_UNREF (ic->preedit);
2661 M17N_OBJECT_UNREF (ic->produced);
2662 M17N_OBJECT_UNREF (ic->plist);
2667 if (im->driver.callback_list)
2669 minput__callback (ic, Minput_preedit_start);
2670 minput__callback (ic, Minput_status_start);
2671 minput__callback (ic, Minput_status_draw);
2674 MDEBUG_PRINT (" ok\n");
2681 @brief Destroy an input context.
2683 The minput_destroy_ic () function destroys the input context $IC,
2684 which must have been created by minput_create_ic (). It calls
2685 callback functions corresponding to #Minput_preedit_done,
2686 #Minput_status_done, and #Minput_candidates_done in this order. */
2689 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
2691 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
2692 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
2693 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
2694 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
2695 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2699 minput_destroy_ic (MInputContext *ic)
2701 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
2702 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
2703 if (ic->im->driver.callback_list)
2705 minput__callback (ic, Minput_preedit_done);
2706 minput__callback (ic, Minput_status_done);
2707 minput__callback (ic, Minput_candidates_done);
2709 (*ic->im->driver.destroy_ic) (ic);
2710 M17N_OBJECT_UNREF (ic->preedit);
2711 M17N_OBJECT_UNREF (ic->produced);
2712 M17N_OBJECT_UNREF (ic->plist);
2713 MDEBUG_PRINT (" done\n");
2720 @brief Filter an input key.
2722 The minput_filter () function filters input key $KEY according to
2723 input context $IC, and calls callback functions corresponding to
2724 #Minput_preedit_draw, #Minput_status_draw, and
2725 #Minput_candidates_draw if the preedit text, the status, and the
2726 current candidate are changed respectively.
2729 If $KEY is filtered out, this function returns 1. In that case,
2730 the caller should discard the key. Otherwise, it returns 0, and
2731 the caller should handle the key, for instance, by calling the
2732 function minput_lookup () with the same key. */
2735 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
2737 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2738 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
2739 #Minput_preedit_draw, #Minput_status_draw,
2740 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
2743 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
2744 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
2745 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
2746 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
2748 @latexonly \IPAlabel{minput_filter} @endlatexonly
2752 minput_filter (MInputContext *ic, MSymbol key, void *arg)
2759 ret = (*ic->im->driver.filter) (ic, key, arg);
2761 if (ic->im->driver.callback_list)
2763 if (ic->preedit_changed)
2764 minput__callback (ic, Minput_preedit_draw);
2765 if (ic->status_changed)
2766 minput__callback (ic, Minput_status_draw);
2767 if (ic->candidates_changed)
2768 minput__callback (ic, Minput_candidates_draw);
2777 @brief Look up a text produced in the input context.
2779 The minput_lookup () function looks up a text in the input context
2780 $IC. $KEY must be the same one provided to the previous call of
2783 If a text was produced by the input method, it is concatenated
2786 This function calls #MInputDriver::lookup .
2789 If $KEY was correctly handled by the input method, this function
2790 returns 0. Otherwise, returns -1, even in that case, some text
2791 may be produced in $MT. */
2794 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
2796 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
2797 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2799 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
2802 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
2805 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
2806 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
2807 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
2809 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
2812 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2814 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
2819 @brief Set the spot of the input context.
2821 The minput_set_spot () function set the spot of input context $IC
2822 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
2823 The semantics of these values depend on the input method driver.
2825 For instance, a driver designed to work in a CUI environment may
2826 use $X and $Y as column and row numbers, and ignore $ASCENT and
2827 $DESCENT . A driver designed to work in a window system may
2828 interpret $X and $Y as pixel offsets relative to the origin of the
2829 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
2830 descent pixels of the line at ($X . $Y ).
2832 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
2834 $MT and $POS is the M-text and the character position at the spot.
2835 $MT may be @c NULL, in which case, the input method cannot get
2836 information about the text around the spot. */
2839 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
2841 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
2842 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
2843 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
2845 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
2846 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
2847 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
2848 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
2849 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
2850 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
2852 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
2854 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
2855 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
2859 minput_set_spot (MInputContext *ic, int x, int y,
2860 int ascent, int descent, int fontsize,
2865 ic->spot.ascent = ascent;
2866 ic->spot.descent = descent;
2867 ic->spot.fontsize = fontsize;
2870 if (ic->im->driver.callback_list)
2871 minput__callback (ic, Minput_set_spot);
2876 @brief Toggle input method.
2878 The minput_toggle () function toggles the input method associated
2879 with input context $IC. */
2881 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
2883 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2884 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
2888 minput_toggle (MInputContext *ic)
2890 if (ic->im->driver.callback_list)
2891 minput__callback (ic, Minput_toggle);
2892 ic->active = ! ic->active;
2896 @brief Reset an input context.
2898 The minput_reset_ic () function resets input context $IC by
2899 calling a callback function corresponding to #Minput_reset. It
2900 actually shifts the state to the initial one, and thus the current
2901 preediting text (if any) is committed. If necessary, a program
2902 can extract that committed text by calling minput_lookup () just
2903 after the call of minput_reset_ic (). In that case, the arguments
2904 @c KEY and @c ARG of minput_lookup () are ignored. */
2906 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
2908 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
2909 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2910 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
2911 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
2912 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
2913 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
2916 minput_reset_ic (MInputContext *ic)
2918 if (ic->im->driver.callback_list)
2919 minput__callback (ic, Minput_reset);
2924 @brief Key of a text property for detailed description.
2926 The symbol #Mdetail_text is a managing key usually used for a
2927 text property whose value is an M-text that contains detailed
2930 @brief ¾ÜºÙÀâÌÀÍѥƥ¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼.
2932 ¥·¥ó¥Ü¥ë #Mdetail_text ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ê¡¢Ä̾ï¾ÜºÙ¤ÊÀâÌÀ¤ò´Þ¤à
2933 M-text ¤òÃͤȤ·¤Æ»ý¤Ä¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ËÍѤ¤¤é¤ì¤ë¡£
2935 MSymbol Mdetail_text;
2938 @brief Get description text of an input method.
2940 The minput_get_description () function returns an M-text that
2941 briefly describes the input method specified by $LANGUAGE and
2942 $NAME. The returned M-text may have a text property, from its
2943 beginning to end, #Mdetail_text whose value is an M-text
2944 describing the input method in more detail.
2947 If the specified input method has a description text, a pointer to
2948 #MText is returned. A caller have to free it by m17n_object_unref ().
2949 If the input method does not have a description text, @c NULL is
2952 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
2954 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME
2955 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£ÊÖ¤µ¤ì¤ë M-text
2956 ¤Ë¤Ï¡¢¤½¤ÎÁ´ÂΤËÂФ·¤Æ #Mdetail_text
2957 ¤È¤¤¤¦¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬Éղ䵤ì¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ê¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¤µ¤é¤Ë¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
2961 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
2962 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
2963 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
2966 minput_get_description (MSymbol language, MSymbol name)
2968 MPlist *plist = load_im_info (language, name, M_description);
2974 if (! MPLIST_PLIST_P (plist))
2976 M17N_OBJECT_UNREF (plist);
2979 pl = MPLIST_PLIST (plist);
2980 while (! MPLIST_TAIL_P (pl) && ! MPLIST_MTEXT_P (pl))
2981 pl = MPLIST_NEXT (pl);
2982 if (MPLIST_MTEXT_P (pl))
2983 mt = get_description_advance (pl);
2984 M17N_OBJECT_UNREF (plist);
2989 @brief Get information about input method commands.
2991 The minput_get_commands () function returns information about
2992 input method commands of the input method specified by $LANGUAGE
2993 and $NAME. An input method command is a pseudo key event to which
2994 one or more actual input key sequences are assigned.
2996 There are two kinds of commands, global and local. Global
2997 commands are used by multiple input methods for the same purpose,
2998 and have global key assignments. Local commands are used only in
2999 a specific input method, and have only local key assignments.
3001 Each input method may locally change key assignments for global
3002 commands. A global key assignment for a global command are
3003 effective only when the current input method does not have local
3004 key assignments for that command.
3006 If $NAME is #Mnil, information about global commands is returned.
3007 In this case $LANGUAGE is ignored.
3009 If $NAME is not #Mnil, information about those commands that have
3010 local key assignments in the input method specified by $LANGUAGE
3011 and $NAME is returned.
3014 If no input method commands are found, this function returns @c NULL.
3016 Otherwise, a pointer to a plist is returned. The key of each
3017 element in the plist is a symbol representing a command, and the
3018 value is a plist of the form COMMAND-INFO described below.
3020 The first element of COMMAND-INFO has the key #Mtext, and the
3021 value is an M-text describing the command briefly. This M-text
3022 may have a text property whose key is #Mdetail_text and whose
3023 value is an M-text describing the command in more detail.
3025 If there are no more elements, that means no key sequences are
3026 assigned to the command. Otherwise, each of the remaining
3027 elements has the key #Mplist, and the value is a plist whose keys are
3028 #Msymbol and values are symbols representing input keys, which are
3029 currently assigned to the command.
3031 As the returned plist is kept in the library, the caller must not
3032 modify nor free it. */
3034 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3036 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3037 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3038 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3040 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£
3041 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ÇÍѤ¤¤é¤ì¤ë¡£
3042 ¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3044 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
3045 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ß͸ú¤Ç¤¢¤ë¡£
3047 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3048 ¤³¤Î¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3050 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME
3051 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3054 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3056 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3057 ¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î
3058 COMMAND-INFO ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3060 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext
3061 ¤ò¡¢ÃͤȤ·¤Æ¤½¤Î¥³¥Þ¥ó¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤ò»ý¤Ä¡£¤³¤Î M-text
3063 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤Î¥³¥Þ¥ó¥É¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3066 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
3067 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ#Mplist
3068 ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£
3069 ¤³¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol
3070 ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3072 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3075 minput_get_commands (MSymbol language, MSymbol name)
3077 MPlist *plist = get_command_list (language, name);
3079 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3083 @brief Assign a key sequence to an input method command.
3085 The minput_assign_command_keys () function assigns input key
3086 sequence $KEYSEQ to input method command $COMMAND for the input
3087 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3088 key sequence is assigned globally no matter what $LANGUAGE is.
3089 Otherwise the key sequence is assigned locally.
3091 Each element of $KEYSEQ must have the key $Msymbol and the value
3092 must be a symbol representing an input key.
3094 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3095 globally or locally.
3097 This assignment gets effective in a newly opened input method.
3100 If the operation was successful, 0 is returned. Otherwise -1 is
3101 returned, and #merror_code is set to #MERROR_IM. */
3103 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3105 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3106 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND
3107 ¤ËÂФ·¤Æ¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil
3108 ¤Ê¤é¤Ð¡¢$LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
3109 ¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3111 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol
3112 ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3114 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£
3115 ¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3117 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤Ë¤Ê¤ë¡£
3120 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3121 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3124 minput_assign_command_keys (MSymbol language, MSymbol name,
3125 MSymbol command, MPlist *keyseq)
3127 MPlist *plist, *pl, *p;
3129 if (check_command_keyseq (keyseq) < 0
3130 || ! (plist = get_command_list (language, name)))
3131 MERROR (MERROR_IM, -1);
3132 pl = mplist_get (plist, command);
3135 pl = MPLIST_NEXT (pl);
3137 while ((p = mplist_pop (pl)))
3138 M17N_OBJECT_UNREF (p);
3141 keyseq = mplist_copy (keyseq);
3142 mplist_push (pl, Mplist, keyseq);
3143 M17N_OBJECT_UNREF (keyseq);
3149 MERROR (MERROR_IM, -1);
3152 pl = get_command_list (Mnil, Mnil); /* Get global commands. */
3153 pl = mplist_get (pl, command);
3155 MERROR (MERROR_IM, -1);
3157 mplist_add (p, Mtext, mplist_value (pl));
3158 keyseq = mplist_copy (keyseq);
3159 mplist_add (p, Mplist, keyseq);
3160 M17N_OBJECT_UNREF (keyseq);
3161 mplist_push (plist, command, p);
3167 @brief Get a list of variables of an input method.
3169 The minput_get_variables () function returns a plist (#MPlist) of
3170 variables used to control the behavior of the input method
3171 specified by $LANGUAGE and $NAME. The key of an element of the
3172 plist is a symbol representing a variable, and the value is a
3173 plist of the form VAR-INFO (described below) that carries the
3174 information about the variable.
3176 The first element of VAR-INFO has the key #Mtext, and the value is
3177 an M-text describing the variable briefly. This M-text may have a
3178 text property #Mdetail_text whose value is an M-text describing
3179 the variable in more detail.
3181 The second element of VAR-INFO is for the value of the variable.
3182 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3183 integer, a symbol, or an M-text, respectively. The variable is
3184 set to this value when an input context is created for the input
3187 If there are no more elements, the variable can take any value
3188 that matches with the above type. Otherwise, the remaining
3189 elements of VAR-INFO are to specify valid values of the variable.
3191 If the type of the variable is integer, the following elements
3192 have the key #Minteger or #Mplist. If it is #Minteger, the value
3193 is a valid integer value. If it is #Mplist, the value is a plist
3194 of two of elements. Both of them have the key #Minteger, and
3195 values are the minimum and maximum bounds of the valid value
3198 If the type of the variable is symbol or M-text, the following
3199 elements of the plist have the key #Msymbol or #Mtext,
3200 respectively, and the value must be a valid one.
3202 For instance, suppose an input method has the variables:
3204 @li name:intvar, description: "value is an integer",
3205 initial value:0, value-range:0..3,10,20
3207 @li name:symvar, description: "value is a symbol",
3208 initial value:nil, value-range:a, b, c, nil
3210 @li name:txtvar, description: "value is an M-text",
3211 initial value:empty text, no value-range (i.e. any text)
3213 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3214 a value, and '(...)' means a plist):
3217 plist:(intvar:(mtext:'value is an integer'
3219 plist:(integer:0 integer:3)
3222 symvar:(mtext:"value is a symbol"
3228 txtvar:(mtext:"value is an M-text"
3233 If the input method uses any variables, a pointer to #MPlist is
3234 returned. As the plist is kept in the library, a caller must not
3235 modify nor free it. If the input method does not use any
3236 variable, @c NULL is returned. */
3238 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3240 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3241 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3242 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3243 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3244 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3246 VAR-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext ¤ò¡¢ÃͤȤ·¤Æ¤½¤ÎÊÑ¿ô¤ò´Êñ¤ËÀâÌÀ¤¹¤ë
3247 M-text ¤ò»ý¤Ä¡£¤³¤Î M-text ¤Ï¡¢#Mdetail_text
3248 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤ÎÊÑ¿ô¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3251 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3252 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3253 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3255 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3256 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3258 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3259 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3260 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3261 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3263 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3264 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3266 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3268 @li name:intvar, ÀâÌÀ:"value is an integer",
3269 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3271 @li name:symvar, ÀâÌÀ:"value is a symbol",
3272 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3274 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3275 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3277 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3278 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3281 plist:(intvar:(mtext:"value is an integer"
3283 plist:(integer:0 integer:3)
3286 symvar:(mtext:"value is a symbol"
3292 txtvar:(mtext:"value is an M-text"
3297 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3298 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3299 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3302 minput_get_variables (MSymbol language, MSymbol name)
3304 MPlist *plist = get_variable_list (language, name);
3306 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3310 @brief Set the initial value of an input method variable.
3312 The minput_set_variable () function sets the initial value of
3313 input method variable $VARIABLE to $VALUE for the input method
3314 specified by $LANGUAGE and $NAME.
3316 By default, the initial value is 0.
3318 This setting gets effective in a newly opened input method.
3321 If the operation was successful, 0 is returned. Otherwise -1 is
3322 returned, and #merror_code is set to #MERROR_IM. */
3324 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3326 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3327 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3328 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3330 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3332 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3335 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3336 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3339 minput_set_variable (MSymbol language, MSymbol name,
3340 MSymbol variable, void *value)
3342 MPlist *plist, *val_element, *range_element;
3345 if (language == Mnil || name == Mnil)
3346 MERROR (MERROR_IM, -1);
3347 plist = get_variable_list (language, name);
3349 MERROR (MERROR_IM, -1);
3350 plist = (MPlist *) mplist_get (plist, variable);
3352 MERROR (MERROR_IM, -1);
3353 val_element = MPLIST_NEXT (plist);
3354 type = MPLIST_KEY (val_element);
3355 range_element = MPLIST_NEXT (val_element);
3357 if (! MPLIST_TAIL_P (range_element))
3359 if (type == Minteger)
3361 int val = (int) value, this_val;
3363 MPLIST_DO (plist, range_element)
3365 this_val = (int) MPLIST_VAL (plist);
3366 if (MPLIST_PLIST_P (plist))
3368 int min_bound, max_bound;
3369 MPlist *pl = MPLIST_PLIST (plist);
3371 min_bound = (int) MPLIST_VAL (pl);
3372 pl = MPLIST_NEXT (pl);
3373 max_bound = (int) MPLIST_VAL (pl);
3374 if (val >= min_bound && val <= max_bound)
3377 else if (val == this_val)
3380 if (MPLIST_TAIL_P (plist))
3381 MERROR (MERROR_IM, -1);
3383 else if (type == Msymbol)
3385 MPLIST_DO (plist, range_element)
3386 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3388 if (MPLIST_TAIL_P (plist))
3389 MERROR (MERROR_IM, -1);
3391 else /* type == Mtext */
3393 MPLIST_DO (plist, range_element)
3394 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3396 if (MPLIST_TAIL_P (plist))
3397 MERROR (MERROR_IM, -1);
3398 M17N_OBJECT_REF (value);
3402 mplist_set (val_element, type, value);
3408 /*** @addtogroup m17nDebug */
3414 @brief Dump an input method.
3416 The mdebug_dump_im () function prints the input method $IM in a
3417 human readable way to the stderr. $INDENT specifies how many
3418 columns to indent the lines but the first one.
3421 This function returns $IM. */
3423 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3425 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3426 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3429 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3432 mdebug_dump_im (MInputMethod *im, int indent)
3434 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3437 prefix = (char *) alloca (indent + 1);
3438 memset (prefix, 32, indent);
3439 prefix[indent] = '\0';
3441 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3442 msymbol_name (im->name));
3443 mdebug_dump_mtext (im_info->title, 0, 0);
3444 if (im->name != Mnil)
3448 MPLIST_DO (state, im_info->states)
3450 fprintf (stderr, "\n%s ", prefix);
3451 dump_im_state (MPLIST_VAL (state), indent + 2);
3454 fprintf (stderr, ")");