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->key_head == ic_info->used
883 && ic_info->map == ic_info->state->map
884 && ic_info->map->map_actions)
886 MDEBUG_PRINT (" init-actions:");
887 take_action_list (ic, ic_info->map->map_actions);
891 /* Find a candidate group that contains a candidate number INDEX from
892 PLIST. Set START_INDEX to the first candidate number of the group,
893 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
894 candidate group number if they are non-NULL. If INDEX is -1, find
895 the last candidate group. */
898 find_candidates_group (MPlist *plist, int index,
899 int *start_index, int *end_index, int *group_index)
901 int i = 0, gidx = 0, len;
903 MPLIST_DO (plist, plist)
905 if (MPLIST_MTEXT_P (plist))
906 len = mtext_nchars (MPLIST_MTEXT (plist));
908 len = mplist_length (MPLIST_PLIST (plist));
909 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
915 *end_index = i + len;
927 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
929 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
931 int nchars = mt ? mtext_nchars (mt) : 1;
934 mtext_ins (ic->preedit, pos, mt);
936 mtext_ins_char (ic->preedit, pos, c, 1);
937 MPLIST_DO (markers, ic_info->markers)
938 if (MPLIST_INTEGER (markers) > pos)
939 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
940 if (ic->cursor_pos >= pos)
941 ic->cursor_pos += nchars;
942 ic->preedit_changed = 1;
947 preedit_delete (MInputContext *ic, int from, int to)
949 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
952 mtext_del (ic->preedit, from, to);
953 MPLIST_DO (markers, ic_info->markers)
955 if (MPLIST_INTEGER (markers) > to)
957 = (void *) (MPLIST_INTEGER (markers) - (to - from));
958 else if (MPLIST_INTEGER (markers) > from);
959 MPLIST_VAL (markers) = (void *) from;
961 if (ic->cursor_pos >= to)
962 ic->cursor_pos -= to - from;
963 else if (ic->cursor_pos > from)
964 ic->cursor_pos = from;
965 ic->preedit_changed = 1;
970 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
972 int code = marker_code (sym);
974 if (mt && (code == '[' || code == ']'))
978 if (code == '[' && current > 0)
980 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
984 else if (code == ']' && current < mtext_nchars (mt))
986 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
992 return (code == '<' ? 0
993 : code == '>' ? limit
994 : code == '-' ? current - 1
995 : code == '+' ? current + 1
996 : code == '=' ? current
997 : code - '0' > limit ? limit
1001 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1005 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1007 int from = mtext_property_start (prop);
1008 int to = mtext_property_end (prop);
1010 MPlist *candidate_list = mtext_property_value (prop);
1011 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1013 int ingroup_index = idx - start;
1016 preedit_delete (ic, from, to);
1017 if (MPLIST_MTEXT_P (group))
1019 mt = MPLIST_MTEXT (group);
1020 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1028 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1029 i++, plist = MPLIST_NEXT (plist));
1030 mt = MPLIST_MTEXT (plist);
1031 preedit_insert (ic, from, mt, 0);
1032 to = from + mtext_nchars (mt);
1034 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1035 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1036 ic->cursor_pos = to;
1041 take_action_list (MInputContext *ic, MPlist *action_list)
1043 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1044 MPlist *candidate_list = ic->candidate_list;
1045 int candidate_index = ic->candidate_index;
1046 int candidate_show = ic->candidate_show;
1047 MTextProperty *prop;
1049 MPLIST_DO (action_list, action_list)
1055 if (MPLIST_MTEXT_P (action_list)
1056 || MPLIST_INTEGER_P (action_list))
1057 name = Minsert, args = action_list;
1058 else if (MPLIST_PLIST_P (action_list)
1059 && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list))
1060 || MPLIST_PLIST_P (MPLIST_PLIST (action_list))))
1061 name = Minsert, args = action_list;
1064 action = MPLIST_PLIST (action_list);
1065 name = MPLIST_SYMBOL (action);
1066 args = MPLIST_NEXT (action);
1069 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1070 if (name == Minsert)
1072 if (MPLIST_MTEXT_P (args))
1073 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1074 else if (MPLIST_INTEGER_P (args))
1075 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1076 else if (MPLIST_SYMBOL_P (args))
1078 int c = integer_value (ic, args);
1080 if (c >= 0 && c <= MCHAR_MAX)
1081 preedit_insert (ic, ic->cursor_pos, NULL, c);
1088 args = MPLIST_PLIST (args);
1089 if (MPLIST_MTEXT_P (args))
1091 preedit_insert (ic, ic->cursor_pos, NULL,
1092 mtext_ref_char (MPLIST_MTEXT (args), 0));
1097 mt = MPLIST_MTEXT (MPLIST_PLIST (args));
1098 preedit_insert (ic, ic->cursor_pos, mt, 0);
1099 len = mtext_nchars (mt);
1101 mtext_put_prop (ic->preedit,
1102 ic->cursor_pos - len, ic->cursor_pos,
1103 Mcandidate_list, args);
1104 mtext_put_prop (ic->preedit,
1105 ic->cursor_pos - len, ic->cursor_pos,
1106 Mcandidate_index, (void *) 0);
1109 else if (name == Mselect)
1112 int code, idx, gindex;
1113 int pos = ic->cursor_pos;
1117 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1120 if (MPLIST_SYMBOL_P (args))
1122 code = marker_code (MPLIST_SYMBOL (args));
1128 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1129 group = find_candidates_group (mtext_property_value (prop), idx,
1130 &start, &end, &gindex);
1132 if (code != '[' && code != ']')
1136 ? new_index (NULL, ic->candidate_index - start,
1137 end - start - 1, MPLIST_SYMBOL (args),
1139 : MPLIST_INTEGER (args)));
1142 find_candidates_group (mtext_property_value (prop), -1,
1147 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1152 int ingroup_index = idx - start;
1155 group = mtext_property_value (prop);
1156 len = mplist_length (group);
1169 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1170 idx += (MPLIST_MTEXT_P (group)
1171 ? mtext_nchars (MPLIST_MTEXT (group))
1172 : mplist_length (MPLIST_PLIST (group)));
1173 len = (MPLIST_MTEXT_P (group)
1174 ? mtext_nchars (MPLIST_MTEXT (group))
1175 : mplist_length (MPLIST_PLIST (group)));
1176 if (ingroup_index >= len)
1177 ingroup_index = len - 1;
1178 idx += ingroup_index;
1180 update_candidate (ic, prop, idx);
1182 else if (name == Mshow)
1183 ic->candidate_show = 1;
1184 else if (name == Mhide)
1185 ic->candidate_show = 0;
1186 else if (name == Mdelete)
1188 int len = mtext_nchars (ic->preedit);
1189 int to = (MPLIST_SYMBOL_P (args)
1190 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1192 : MPLIST_INTEGER (args));
1198 if (to < ic->cursor_pos)
1199 preedit_delete (ic, to, ic->cursor_pos);
1200 else if (to > ic->cursor_pos)
1201 preedit_delete (ic, ic->cursor_pos, to);
1203 else if (name == Mmove)
1205 int len = mtext_nchars (ic->preedit);
1207 = (MPLIST_SYMBOL_P (args)
1208 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1210 : MPLIST_INTEGER (args));
1216 if (pos != ic->cursor_pos)
1218 ic->cursor_pos = pos;
1219 ic->preedit_changed = 1;
1222 else if (name == Mmark)
1224 int code = marker_code (MPLIST_SYMBOL (args));
1227 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1228 (void *) ic->cursor_pos);
1230 else if (name == Mpushback)
1232 if (MPLIST_INTEGER_P (args))
1234 int num = MPLIST_INTEGER (args);
1237 ic_info->key_head -= num;
1239 ic_info->key_head = num;
1240 if (ic_info->key_head > ic_info->used)
1241 ic_info->key_head = ic_info->used;
1243 else if (MPLIST_MTEXT_P (args))
1245 MText *mt = MPLIST_MTEXT (args);
1246 int i, len = mtext_nchars (mt);
1249 ic_info->key_head--;
1250 for (i = 0; i < len; i++)
1252 key = one_char_symbol[MTEXT_DATA (mt)[i]];
1253 if (ic_info->key_head < ic_info->used)
1254 ic_info->keys[ic_info->key_head + i] = key;
1256 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1261 MPlist *plist = MPLIST_PLIST (args), *pl;
1265 ic_info->key_head--;
1267 MPLIST_DO (pl, plist)
1269 key = MPLIST_SYMBOL (pl);
1270 if (ic_info->key_head < ic_info->used)
1271 ic_info->keys[ic_info->key_head + i] = key;
1273 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1278 else if (name == Mcall)
1280 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1281 MIMExternalFunc func = NULL;
1282 MSymbol module, func_name;
1283 MPlist *func_args, *val;
1286 module = MPLIST_SYMBOL (args);
1287 args = MPLIST_NEXT (args);
1288 func_name = MPLIST_SYMBOL (args);
1290 if (im_info->externals)
1292 MIMExternalModule *external
1293 = (MIMExternalModule *) mplist_get (im_info->externals,
1296 func = (MIMExternalFunc) mplist_get (external->func_list,
1301 func_args = mplist ();
1302 mplist_add (func_args, Mt, ic);
1303 MPLIST_DO (args, MPLIST_NEXT (args))
1307 if (MPLIST_KEY (args) == Msymbol
1308 && MPLIST_KEY (args) != Mnil
1309 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1311 code = new_index (ic, ic->cursor_pos,
1312 mtext_nchars (ic->preedit),
1313 MPLIST_SYMBOL (args), ic->preedit);
1314 mplist_add (func_args, Minteger, (void *) code);
1317 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1319 val = (func) (func_args);
1320 M17N_OBJECT_UNREF (func_args);
1321 if (val && ! MPLIST_TAIL_P (val))
1322 ret = take_action_list (ic, val);
1323 M17N_OBJECT_UNREF (val);
1327 else if (name == Mshift)
1329 shift_state (ic, MPLIST_SYMBOL (args));
1331 else if (name == Mundo)
1333 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1336 mtext_reset (ic->preedit);
1337 mtext_reset (ic_info->preedit_saved);
1338 ic->cursor_pos = ic_info->state_pos = 0;
1339 ic_info->state_key_head = ic_info->key_head = 0;
1341 if (ic_info->used < 0)
1346 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1351 else if (name == Mset || name == Madd || name == Msub
1352 || name == Mmul || name == Mdiv)
1354 MSymbol sym = MPLIST_SYMBOL (args);
1355 int val1 = (int) mplist_get (ic_info->vars, sym), val2;
1357 args = MPLIST_NEXT (args);
1358 val2 = integer_value (ic, args);
1361 else if (name == Madd)
1363 else if (name == Msub)
1365 else if (name == Mmul)
1369 mplist_put (ic_info->vars, sym, (void *) val1);
1370 MDEBUG_PRINT2 ("(%s=%d)", MSYMBOL_NAME (sym), val1);
1372 else if (name == Mequal || name == Mless || name == Mgreater)
1375 MPlist *actions1, *actions2;
1378 val1 = integer_value (ic, args);
1379 args = MPLIST_NEXT (args);
1380 val2 = integer_value (ic, args);
1381 args = MPLIST_NEXT (args);
1382 actions1 = MPLIST_PLIST (args);
1383 args = MPLIST_NEXT (args);
1384 if (MPLIST_TAIL_P (args))
1387 actions2 = MPLIST_PLIST (args);
1388 MDEBUG_PRINT2 ("(%d,%d)", val1, val2);
1389 if (name == Mequal ? val1 == val2
1390 : name == Mless ? val1 < val2
1393 MDEBUG_PRINT ("ok");
1394 ret = take_action_list (ic, actions1);
1398 MDEBUG_PRINT ("no");
1400 ret = take_action_list (ic, actions2);
1407 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1411 && (actions = mplist_get (im_info->macros, name)))
1413 if (take_action_list (ic, actions) < 0)
1420 ic->candidate_list = NULL;
1421 if (ic->cursor_pos > 0
1422 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
1425 ic->candidate_list = mtext_property_value (prop);
1427 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
1429 ic->candidate_from = mtext_property_start (prop);
1430 ic->candidate_to = mtext_property_end (prop);
1433 ic->candidates_changed |= (candidate_list != ic->candidate_list
1434 || candidate_index != ic->candidate_index
1435 || candidate_show != ic->candidate_show);
1440 /* Handle the input key KEY in the current state and map specified in
1441 the input context IC. If KEY is handled correctly, return 0.
1442 Otherwise, return -1. */
1445 handle_key (MInputContext *ic)
1447 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1448 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1449 MIMMap *map = ic_info->map;
1450 MIMMap *submap = NULL;
1451 MSymbol key = ic_info->keys[ic_info->key_head];
1454 MDEBUG_PRINT2 ("[IM] handle `%s' in state %s",
1455 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
1459 submap = mplist_get (map->submaps, key);
1460 if (! submap && (key = msymbol_get (key, M_key_alias)) != Mnil)
1461 submap = mplist_get (map->submaps, key);
1466 MDEBUG_PRINT (" submap-found");
1467 mtext_cpy (ic->preedit, ic_info->preedit_saved);
1468 ic->cursor_pos = ic_info->state_pos;
1469 ic_info->key_head++;
1470 ic_info->map = map = submap;
1471 if (map->map_actions)
1473 MDEBUG_PRINT (" map-actions:");
1474 if (take_action_list (ic, map->map_actions) < 0)
1476 MDEBUG_PRINT ("\n");
1480 else if (map->submaps)
1482 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
1484 MSymbol key = ic_info->keys[i];
1485 char *name = msymbol_name (key);
1487 if (! name[0] || ! name[1])
1488 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
1490 ic->preedit_changed = 1;
1493 /* If this is the terminal map or we have shifted to another
1494 state, perform branch actions (if any). */
1495 if (! map->submaps || map != ic_info->map)
1497 if (map->branch_actions)
1499 MDEBUG_PRINT (" branch-actions:");
1500 if (take_action_list (ic, map->branch_actions) < 0)
1502 MDEBUG_PRINT ("\n");
1506 /* If MAP is still not the root map, shift to the current
1508 if (ic_info->map != ic_info->state->map)
1509 shift_state (ic, ic_info->state->name);
1514 /* MAP can not handle KEY. */
1516 /* If MAP is the root map of the initial state, it means that
1517 the current input method can not handle KEY. */
1518 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
1520 MDEBUG_PRINT (" unhandled\n");
1524 if (map != ic_info->state->map)
1526 /* If MAP is not the root map... */
1527 /* If MAP has branch actions, perform them. */
1528 if (map->branch_actions)
1530 MDEBUG_PRINT (" branch-actions:");
1531 take_action_list (ic, map->branch_actions);
1533 /* If MAP is still not the root map, shift to the current
1535 if (ic_info->map != ic_info->state->map)
1537 shift_state (ic, ic_info->state->name);
1538 /* If MAP has branch_actions, perform them. */
1539 if (ic_info->map->branch_actions)
1541 MDEBUG_PRINT (" init-actions:");
1542 take_action_list (ic, ic_info->map->branch_actions);
1548 /* MAP is the root map, perform branch actions (if any) or
1549 shift to the initial state. */
1550 if (map->branch_actions)
1552 MDEBUG_PRINT (" branch-actions:");
1553 take_action_list (ic, map->branch_actions);
1557 ((MIMState *) MPLIST_VAL (im_info->states))->name);
1560 MDEBUG_PRINT ("\n");
1565 reset_ic (MInputContext *ic, MSymbol ignore)
1567 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1568 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1570 if (im_info->states)
1571 /* Shift to the initial state. */
1572 shift_state (ic, Mnil);
1574 ic_info->state = NULL;
1575 MLIST_RESET (ic_info);
1576 ic_info->map = ic_info->state ? ic_info->state->map : NULL;
1577 ic_info->state_key_head = ic_info->key_head = 0;
1578 ic_info->key_unhandled = 0;
1579 ic->cursor_pos = ic_info->state_pos = 0;
1580 ic->status = ic_info->state ? ic_info->state->title : NULL;
1582 ic->status = im_info->title;
1583 ic->candidate_list = NULL;
1584 ic->candidate_show = 0;
1585 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1;
1589 open_im (MInputMethod *im)
1592 MInputMethodInfo *im_info;
1596 mdb = mdatabase_find (Minput_method, im->language, im->name, Mnil);
1599 plist = mdatabase_load (mdb);
1601 MERROR (MERROR_IM, -1);
1602 MSTRUCT_CALLOC (im_info, MERROR_IM);
1604 result = load_input_method (im->language, im->name, plist, im_info);
1605 M17N_OBJECT_UNREF (plist);
1607 MERROR (MERROR_IM, -1);
1612 close_im (MInputMethod *im)
1614 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1618 M17N_OBJECT_UNREF (im_info->title);
1619 if (im_info->states)
1621 MPLIST_DO (plist, im_info->states)
1623 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1626 M17N_OBJECT_UNREF (state->title);
1628 free_map (state->map);
1631 M17N_OBJECT_UNREF (im_info->states);
1634 if (im_info->macros)
1636 MPLIST_DO (plist, im_info->macros)
1637 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1638 M17N_OBJECT_UNREF (im_info->macros);
1641 if (im_info->externals)
1643 MPLIST_DO (plist, im_info->externals)
1645 MIMExternalModule *external = MPLIST_VAL (plist);
1647 dlclose (external->handle);
1648 M17N_OBJECT_UNREF (external->func_list);
1650 MPLIST_KEY (plist) = Mt;
1652 M17N_OBJECT_UNREF (im_info->externals);
1660 create_ic (MInputContext *ic)
1662 MInputMethod *im = ic->im;
1663 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
1664 MInputContextInfo *ic_info;
1667 ic_info = (MInputContextInfo *) ic->info;
1670 MSTRUCT_CALLOC (ic_info, MERROR_IM);
1673 MLIST_INIT1 (ic_info, keys, 8);
1674 ic_info->markers = mplist ();
1675 ic_info->vars = mplist ();
1676 ic_info->preedit_saved = mtext ();
1677 if (im_info->externals)
1679 MPlist *func_args = mplist (), *plist;
1681 mplist_add (func_args, Mt, ic);
1682 MPLIST_DO (plist, im_info->externals)
1684 MIMExternalModule *external = MPLIST_VAL (plist);
1685 MIMExternalFunc func
1686 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
1691 M17N_OBJECT_UNREF (func_args);
1693 reset_ic (ic, Mnil);
1698 destroy_ic (MInputContext *ic)
1700 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1701 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1703 if (im_info->externals)
1705 MPlist *func_args = mplist (), *plist;
1707 mplist_add (func_args, Mt, ic);
1708 MPLIST_DO (plist, im_info->externals)
1710 MIMExternalModule *external = MPLIST_VAL (plist);
1711 MIMExternalFunc func
1712 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
1717 M17N_OBJECT_UNREF (func_args);
1719 MLIST_FREE1 (ic_info, keys);
1720 M17N_OBJECT_UNREF (ic_info->preedit_saved);
1721 M17N_OBJECT_UNREF (ic_info->markers);
1722 M17N_OBJECT_UNREF (ic_info->vars);
1727 /** Handle the input key KEY in the current state and map of IC->info.
1728 If KEY is handled but no text is produced, return 0, otherwise
1734 filter (MInputContext *ic, MSymbol key, void *arg)
1736 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1737 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1740 if (! ic_info->state)
1742 ic_info->key_unhandled = 1;
1745 mtext_reset (ic->produced);
1746 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
1747 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1748 ic_info->key_unhandled = 0;
1750 if (handle_key (ic) < 0)
1752 /* KEY was not handled. Reset the status and break the
1754 reset_ic (ic, Mnil);
1755 /* This forces returning 1. */
1756 ic_info->key_unhandled = 1;
1762 reset_ic (ic, Mnil);
1763 ic_info->key_unhandled = 1;
1766 /* Break the loop if all keys were handled. */
1767 } while (ic_info->key_head < ic_info->used);
1769 /* If the current map is the root of the initial state, we should
1770 produce any preedit text in ic->produced. */
1771 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
1772 && mtext_nchars (ic->preedit) > 0)
1773 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
1775 if (mtext_nchars (ic->produced) > 0)
1777 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
1780 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1781 Mlanguage, ic->im->language);
1784 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
1788 /** Return 1 if the last event or key was not handled, otherwise
1791 There is no need of looking up because ic->produced should already
1792 contain the produced text (if any).
1797 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1799 mtext_cat (mt, ic->produced);
1800 mtext_reset (ic->produced);
1801 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
1804 static MPlist *load_im_info_keys;
1807 load_im_info (MSymbol language, MSymbol name, MSymbol key)
1812 if (language == Mnil || name == Mnil)
1813 MERROR (MERROR_IM, NULL);
1815 mdb = mdatabase_find (Minput_method, language, name, Mnil);
1817 MERROR (MERROR_IM, NULL);
1818 mplist_push (load_im_info_keys, key, Mt);
1819 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
1820 mplist_pop (load_im_info_keys);
1825 /* Input method command handler. */
1827 /* List of all (global and local) commands.
1828 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
1829 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
1830 Global commands are storead as (t (t COMMAND ...)) */
1831 static MPlist *command_list;
1833 /* Check if PLIST is a valid command key sequence.
1834 PLIST must be NULL or:
1835 [ symbol:KEY | integer:KEY ] ... */
1838 check_command_keyseq (MPlist *plist)
1842 MPLIST_DO (plist, plist)
1844 if (MPLIST_SYMBOL_P (plist))
1846 else if (MPLIST_INTEGER_P (plist))
1848 int n = MPLIST_INTEGER (plist);
1852 MPLIST_KEY (plist) = Msymbol;
1853 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
1862 get_description_advance (MPlist *plist)
1867 if (! MPLIST_MTEXT_P (plist))
1869 mt = mplist_pop (plist);
1870 pos = mtext_chr (mt, '\n');
1873 MText *detail = mtext_copy (mtext (), 0, mt, pos + 1, mtext_nchars (mt));
1874 mtext_del (mt, pos, mtext_nchars (mt));
1875 mtext_put_prop (mt, 0, pos, Mdetail_text, detail);
1876 M17N_OBJECT_UNREF (detail);
1882 parse_command_list (MPlist *plist, MPlist *global_list)
1884 MPlist *val = mplist ();
1886 /* PLIST ::= (sym:CMD mtext:DESCRIPTION ? (sym:KEY ...) ...) ... */
1887 MPLIST_DO (plist, plist)
1891 MPlist *this_val, *pl, *p;
1893 if (! MPLIST_PLIST_P (plist))
1895 pl = MPLIST_PLIST (plist);
1896 if (! MPLIST_SYMBOL_P (pl))
1898 cmd = MPLIST_SYMBOL (pl);
1899 pl = MPLIST_NEXT (pl);
1900 mt = get_description_advance (pl);
1901 this_val = mplist ();
1903 if (! mt && global_list)
1905 /* Get the description from global_list. */
1906 p = mplist_get (global_list, cmd);
1907 if (p && MPLIST_MTEXT (p))
1909 mt = MPLIST_MTEXT (p);
1910 M17N_OBJECT_REF (mt);
1915 mplist_add (this_val, Mtext, mt);
1916 M17N_OBJECT_UNREF (mt);
1918 /* PL ::= (sym:KEY ...) ... */
1921 if (MPLIST_PLIST_P (pl)
1922 && check_command_keyseq (MPLIST_PLIST (pl)) >= 0)
1923 /* All the elements are valid keys. */
1924 mplist_add (this_val, Mplist, MPLIST_PLIST (pl));
1927 mplist_put (val, cmd, this_val);
1933 get_command_list (MSymbol language, MSymbol name)
1939 language = name = Mt;
1943 MDatabase *mdb = mdatabase_find (msymbol ("input"), M_command,
1946 if (mdb && (plist = mdatabase_load (mdb)))
1948 pl = parse_command_list (plist, NULL);
1949 M17N_OBJECT_UNREF (plist);
1954 mplist_add (plist, Mt, pl);
1955 command_list = mplist ();
1956 mplist_add (command_list, Mt, plist);
1959 per_lang = mplist_get (command_list, language);
1962 plist = mplist_find_by_key (per_lang, name);
1964 return (MPLIST_VAL (plist));
1968 per_lang = mplist ();
1969 mplist_add (command_list, language, per_lang);
1972 /* Now we are sure that we are loading per-im info. */
1973 /* Get the global command list. */
1974 plist = load_im_info (language, name, M_command);
1975 if (! plist || mplist_key (plist) == Mnil)
1979 mplist_add (per_lang, name, plist);
1982 pl = parse_command_list (mplist_value (plist),
1983 mplist_get ((MPlist *) mplist_get (command_list, Mt),
1985 M17N_OBJECT_UNREF (plist);
1986 mplist_put (per_lang, name, pl);
1991 /* Input method variable handler. */
1993 /* List of all variables.
1994 (LANG:(IM-NAME:(VAR ...) ...) ...) ...
1995 VAR is VAR-NAME:(mtext:DESCRIPTION TYPE:VALUE ...)) */
1997 static MPlist *variable_list;
2000 parse_variable_list (MPlist *plist)
2002 MPlist *val = mplist (), *pl, *p;
2004 /* PLIST ::= (sym:VAR mtext:DESCRIPTION TYPE:INIT-VAL ...) ... */
2005 MPLIST_DO (plist, plist)
2011 if (! MPLIST_PLIST_P (plist))
2013 pl = MPLIST_PLIST (plist);
2014 if (! MPLIST_SYMBOL_P (pl))
2016 var = MPLIST_SYMBOL (pl);
2017 pl = MPLIST_NEXT (pl);
2018 mt = get_description_advance (pl);
2019 if (! mt || MPLIST_TAIL_P (pl))
2021 this_val = mplist ();
2022 mplist_add (this_val, Mtext, mt);
2023 M17N_OBJECT_UNREF (mt);
2024 type = MPLIST_KEY (pl);
2025 mplist_add (this_val, type, MPLIST_VAL (pl));
2026 MPLIST_DO (pl, MPLIST_NEXT (pl))
2028 if (type != MPLIST_KEY (pl)
2029 && (type != Minteger || ! MPLIST_PLIST_P (pl)))
2031 if (MPLIST_PLIST_P (pl))
2033 MPLIST_DO (p, MPLIST_PLIST (pl))
2034 if (! MPLIST_INTEGER_P (p))
2036 if (! MPLIST_TAIL_P (p))
2039 mplist_add (this_val, MPLIST_KEY (pl), MPLIST_VAL (pl));
2042 mplist_put (val, var, this_val);
2049 get_variable_list (MSymbol language, MSymbol name)
2054 if (language == Mnil || name == Mnil)
2055 MERROR (MERROR_IM, NULL);
2056 if (! variable_list)
2057 variable_list = mplist ();
2058 per_lang = mplist_get (variable_list, language);
2061 plist = mplist_find_by_key (per_lang, name);
2063 return (MPLIST_VAL (plist));
2067 per_lang = mplist ();
2068 mplist_add (variable_list, language, per_lang);
2070 plist = load_im_info (language, name, M_variable);
2071 if (! plist || mplist_key (plist) == Mnil)
2075 mplist_add (per_lang, name, plist);
2078 pl = parse_variable_list (mplist_value (plist));
2079 M17N_OBJECT_UNREF (plist);
2080 mplist_put (per_lang, name, pl);
2085 input_method_hook (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
2087 MPlist *plist, *pl, *p;
2088 char path[PATH_MAX];
2090 /* Cancel the hook. */
2091 msymbol_put (tag0, M_database_hook, NULL);
2094 mplist_push (load_im_info_keys, M_description, Mt);
2095 MPLIST_DO (plist, mdatabase__dir_list)
2097 char *dirname = (char *) MPLIST_VAL (plist);
2099 DIR *dir = opendir (dirname);
2104 dirlen = strlen (dirname);
2105 strcpy (path, dirname);
2106 while ((dp = readdir (dir)) != NULL)
2108 /* We can't trust dp->d_nameln. */
2109 int len = strlen (dp->d_name);
2112 if (len > 4 && memcmp (dp->d_name + len - 4, ".mim", 4) == 0)
2114 strcpy (path + dirlen, dp->d_name);
2115 fp = fopen (path, "r");
2118 pl = mplist__from_file (fp, load_im_info_keys);
2122 if (MPLIST_PLIST_P (pl))
2124 p = MPLIST_PLIST (pl);
2125 p = MPLIST_NEXT (p);
2126 if (MPLIST_SYMBOL_P (p))
2128 tag1 = MPLIST_VAL (p);
2129 p = MPLIST_NEXT (p);
2130 if (MPLIST_SYMBOL_P (p))
2132 tag2 = MPLIST_VAL (p);
2133 mdatabase_define (tag0, tag1, tag2, tag3,
2138 M17N_OBJECT_UNREF (pl);
2144 mplist_pop (load_im_info_keys);
2148 /* Support functions for mdebug_dump_im. */
2151 dump_im_map (MPlist *map_list, int indent)
2154 MSymbol key = MPLIST_KEY (map_list);
2155 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2157 prefix = (char *) alloca (indent + 1);
2158 memset (prefix, 32, indent);
2159 prefix[indent] = '\0';
2161 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2162 if (map->map_actions)
2163 mdebug_dump_plist (map->map_actions, indent + 2);
2166 MPLIST_DO (map_list, map->submaps)
2168 fprintf (stderr, "\n%s ", prefix);
2169 dump_im_map (map_list, indent + 2);
2172 if (map->branch_actions)
2174 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2175 mdebug_dump_plist (map->branch_actions, indent + 4);
2176 fprintf (stderr, ")");
2178 fprintf (stderr, ")");
2183 dump_im_state (MIMState *state, int indent)
2188 prefix = (char *) alloca (indent + 1);
2189 memset (prefix, 32, indent);
2190 prefix[indent] = '\0';
2192 fprintf (stderr, "(%s", msymbol_name (state->name));
2193 if (state->map->submaps)
2195 MPLIST_DO (map_list, state->map->submaps)
2197 fprintf (stderr, "\n%s ", prefix);
2198 dump_im_map (map_list, indent + 2);
2201 fprintf (stderr, ")");
2210 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2211 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2212 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2213 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2214 char buf[6], buf2[256];
2218 Minput_method = msymbol ("input-method");
2219 msymbol_put (Minput_method, M_database_hook, (void *) input_method_hook);
2220 Minput_driver = msymbol ("input-driver");
2221 Mtitle = msymbol ("title");
2222 Mmacro = msymbol ("macro");
2223 Mmodule = msymbol ("module");
2224 Mmap = msymbol ("map");
2225 Mstate = msymbol ("state");
2226 Minsert = msymbol ("insert");
2227 Mdelete = msymbol ("delete");
2228 Mmove = msymbol ("move");
2229 Mmark = msymbol ("mark");
2230 Mpushback = msymbol ("pushback");
2231 Mundo = msymbol ("undo");
2232 Mcall = msymbol ("call");
2233 Mshift = msymbol ("shift");
2234 Mselect = msymbol ("select");
2235 Mshow = msymbol ("show");
2236 Mhide = msymbol ("hide");
2237 Mset = msymbol ("set");
2238 Madd = msymbol ("add");
2239 Msub = msymbol ("sub");
2240 Mmul = msymbol ("mul");
2241 Mdiv = msymbol ("div");
2242 Mequal = msymbol ("=");
2243 Mless = msymbol ("<");
2244 Mgreater = msymbol (">");
2246 Minput_preedit_start = msymbol ("input-preedit-start");
2247 Minput_preedit_done = msymbol ("input-preedit-done");
2248 Minput_preedit_draw = msymbol ("input-preedit-draw");
2249 Minput_status_start = msymbol ("input-status-start");
2250 Minput_status_done = msymbol ("input-status-done");
2251 Minput_status_draw = msymbol ("input-status-draw");
2252 Minput_candidates_start = msymbol ("input-candidates-start");
2253 Minput_candidates_done = msymbol ("input-candidates-done");
2254 Minput_candidates_draw = msymbol ("input-candidates-draw");
2255 Minput_set_spot = msymbol ("input-set-spot");
2256 Minput_toggle = msymbol ("input-toggle");
2257 Minput_reset = msymbol ("input-reset");
2259 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2260 Mcandidate_index = msymbol (" candidate-index");
2262 Minit = msymbol ("init");
2263 Mfini = msymbol ("fini");
2265 M_key_alias = msymbol (" key-alias");
2266 M_description = msymbol ("description");
2267 M_command = msymbol ("command");
2268 M_variable = msymbol ("variable");
2270 Mdetail_text = msymbol_as_managing_key (" detail-text");
2272 load_im_info_keys = mplist ();
2273 plist = mplist_add (load_im_info_keys, Mmap, Mnil);
2274 plist = mplist_add (plist, Mstate, Mnil);
2275 plist = mplist_add (plist, Mmacro, Mnil);
2276 plist = mplist_add (plist, Mmodule, Mnil);
2281 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2283 one_char_symbol[i] = msymbol (buf);
2285 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (key_names[i]));
2287 for (buf[2] = i; i < 127; i++, buf[2]++)
2288 one_char_symbol[i] = msymbol (buf + 2);
2289 one_char_symbol[i++] = msymbol ("Delete");
2295 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2297 one_char_symbol[i] = msymbol (buf);
2298 if (key_names[i - 128])
2300 strcpy (buf2 + 2, key_names[i - 128]);
2301 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2304 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2305 one_char_symbol[i] = msymbol (buf + 2);
2306 one_char_symbol[i] = msymbol ("M-Delete");
2308 command_list = variable_list = NULL;
2310 minput_default_driver.open_im = open_im;
2311 minput_default_driver.close_im = close_im;
2312 minput_default_driver.create_ic = create_ic;
2313 minput_default_driver.destroy_ic = destroy_ic;
2314 minput_default_driver.filter = filter;
2315 minput_default_driver.lookup = lookup;
2316 minput_default_driver.callback_list = mplist ();
2317 mplist_put (minput_default_driver.callback_list, Minput_reset,
2319 minput_driver = &minput_default_driver;
2326 MPlist *par_lang, *par_im, *p;
2330 MPLIST_DO (par_lang, command_list)
2332 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2334 MPLIST_DO (p, MPLIST_VAL (par_im))
2335 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2336 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2338 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2340 M17N_OBJECT_UNREF (command_list);
2341 command_list = NULL;
2345 MPLIST_DO (par_lang, variable_list)
2347 MPLIST_DO (par_im, MPLIST_VAL (par_lang))
2349 MPLIST_DO (p, MPLIST_VAL (par_im))
2350 M17N_OBJECT_UNREF (MPLIST_VAL (p));
2351 M17N_OBJECT_UNREF (MPLIST_VAL (par_im));
2353 M17N_OBJECT_UNREF (MPLIST_VAL (par_lang));
2355 M17N_OBJECT_UNREF (variable_list);
2356 variable_list = NULL;
2359 if (minput_default_driver.callback_list)
2361 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2362 minput_default_driver.callback_list = NULL;
2364 if (minput_driver->callback_list)
2366 M17N_OBJECT_UNREF (minput_driver->callback_list);
2367 minput_driver->callback_list = NULL;
2370 M17N_OBJECT_UNREF (load_im_info_keys);
2374 minput__callback (MInputContext *ic, MSymbol command)
2376 if (ic->im->driver.callback_list)
2378 MInputCallbackFunc func
2379 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2383 (func) (ic, command);
2388 minput__char_to_key (int c)
2390 if (c < 0 || c >= 0x100)
2393 return one_char_symbol[c];
2397 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2402 /*** @addtogroup m17nInputMethod */
2407 @name Variables: Predefined symbols for callback commands.
2409 These are the predefined symbols that are used as the @c COMMAND
2410 argument of callback functions of an input method driver (see
2411 #MInputDriver::callback_list ). */
2413 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2415 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2416 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2421 MSymbol Minput_preedit_start;
2422 MSymbol Minput_preedit_done;
2423 MSymbol Minput_preedit_draw;
2424 MSymbol Minput_status_start;
2425 MSymbol Minput_status_done;
2426 MSymbol Minput_status_draw;
2427 MSymbol Minput_candidates_start;
2428 MSymbol Minput_candidates_done;
2429 MSymbol Minput_candidates_draw;
2430 MSymbol Minput_set_spot;
2431 MSymbol Minput_toggle;
2432 MSymbol Minput_reset;
2437 @brief The default driver for internal input methods.
2439 The variable #minput_default_driver is the default driver for
2440 internal input methods.
2442 The member MInputDriver::open_im () searches the m17n database for
2443 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2444 $NAME\> and loads it.
2446 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2447 programmers responsibility to set it to a plist of proper callback
2448 functions. Otherwise, no feedback information (e.g. preedit text)
2449 can be shown to users.
2451 The macro M17N_INIT () sets the variable #minput_driver to the
2452 pointer to this driver so that all internal input methods use it.
2454 Therefore, unless @c minput_driver is set differently, the driver
2455 dependent arguments $ARG of the functions whose name begin with
2456 "minput_" are all ignored. */
2459 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2461 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2463 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2464 \< #Minput_method, $LANGUAGE, $NAME\>
2465 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2467 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2468 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2469 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2470 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2472 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2473 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2475 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2476 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2478 MInputDriver minput_default_driver;
2482 @brief The driver for internal input methods.
2484 The variable #minput_driver is a pointer to the input method
2485 driver that is used by internal input methods. The macro
2486 M17N_INIT () initializes it to a pointer to #minput_default_driver
2487 if <m17n<EM></EM>.h> is included. */
2489 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
2491 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
2492 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
2493 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
2494 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
2496 MInputDriver *minput_driver;
2498 MSymbol Minput_driver;
2503 @brief Open an input method.
2505 The minput_open_im () function opens an input method that matches
2506 language $LANGUAGE and name $NAME, and returns a pointer to the
2507 input method object newly allocated.
2509 This function at first decides an driver for the input method as
2512 If $LANGUAGE is not #Mnil, the driver pointed by the variable
2513 #minput_driver is used.
2515 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
2516 driver pointed to by the property value is used to open the input
2517 method. If $NAME has no such property, @c NULL is returned.
2519 Then, the member MInputDriver::open_im () of the driver is
2522 $ARG is set in the member @c arg of the structure MInputMethod so
2523 that the driver can refer to it. */
2526 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
2528 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
2529 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
2531 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
2533 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
2534 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
2536 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
2537 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
2538 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2540 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
2542 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
2544 @latexonly \IPAlabel{minput_open} @endlatexonly
2549 minput_open_im (MSymbol language, MSymbol name, void *arg)
2552 MInputDriver *driver;
2554 MDEBUG_PRINT2 ("[IM] opening (%s %s) ... ",
2555 msymbol_name (language), msymbol_name (name));
2557 driver = minput_driver;
2560 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
2562 MERROR (MERROR_IM, NULL);
2565 MSTRUCT_CALLOC (im, MERROR_IM);
2566 im->language = language;
2569 im->driver = *driver;
2570 if ((*im->driver.open_im) (im) < 0)
2572 MDEBUG_PRINT (" failed\n");
2576 MDEBUG_PRINT (" ok\n");
2583 @brief Close an input method.
2585 The minput_close_im () function closes the input method $IM, which
2586 must have been created by minput_open_im (). */
2589 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
2591 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
2592 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
2595 minput_close_im (MInputMethod *im)
2597 MDEBUG_PRINT2 ("[IM] closing (%s %s) ... ",
2598 msymbol_name (im->name), msymbol_name (im->language));
2599 (*im->driver.close_im) (im);
2601 MDEBUG_PRINT (" done\n");
2607 @brief Create an input context.
2609 The minput_create_ic () function creates an input context object
2610 associated with input method $IM, and calls callback functions
2611 corresponding to #Minput_preedit_start, #Minput_status_start, and
2612 #Minput_status_draw in this order.
2616 If an input context is successfully created, minput_create_ic ()
2617 returns a pointer to it. Otherwise it returns @c NULL. */
2620 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
2622 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
2623 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
2624 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
2625 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2629 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
2630 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
2634 minput_create_ic (MInputMethod *im, void *arg)
2638 MDEBUG_PRINT2 ("[IM] creating context (%s %s) ... ",
2639 msymbol_name (im->name), msymbol_name (im->language));
2640 MSTRUCT_CALLOC (ic, MERROR_IM);
2643 ic->preedit = mtext ();
2644 ic->candidate_list = NULL;
2645 ic->produced = mtext ();
2646 ic->spot.x = ic->spot.y = 0;
2648 ic->plist = mplist ();
2649 if ((*im->driver.create_ic) (ic) < 0)
2651 MDEBUG_PRINT (" failed\n");
2652 M17N_OBJECT_UNREF (ic->preedit);
2653 M17N_OBJECT_UNREF (ic->produced);
2654 M17N_OBJECT_UNREF (ic->plist);
2659 if (im->driver.callback_list)
2661 minput__callback (ic, Minput_preedit_start);
2662 minput__callback (ic, Minput_status_start);
2663 minput__callback (ic, Minput_status_draw);
2666 MDEBUG_PRINT (" ok\n");
2673 @brief Destroy an input context.
2675 The minput_destroy_ic () function destroys the input context $IC,
2676 which must have been created by minput_create_ic (). It calls
2677 callback functions corresponding to #Minput_preedit_done,
2678 #Minput_status_done, and #Minput_candidates_done in this order. */
2681 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
2683 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
2684 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
2685 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
2686 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
2687 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
2691 minput_destroy_ic (MInputContext *ic)
2693 MDEBUG_PRINT2 ("[IM] destroying context (%s %s) ... ",
2694 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
2695 if (ic->im->driver.callback_list)
2697 minput__callback (ic, Minput_preedit_done);
2698 minput__callback (ic, Minput_status_done);
2699 minput__callback (ic, Minput_candidates_done);
2701 (*ic->im->driver.destroy_ic) (ic);
2702 M17N_OBJECT_UNREF (ic->preedit);
2703 M17N_OBJECT_UNREF (ic->produced);
2704 M17N_OBJECT_UNREF (ic->plist);
2705 MDEBUG_PRINT (" done\n");
2712 @brief Filter an input key.
2714 The minput_filter () function filters input key $KEY according to
2715 input context $IC, and calls callback functions corresponding to
2716 #Minput_preedit_draw, #Minput_status_draw, and
2717 #Minput_candidates_draw if the preedit text, the status, and the
2718 current candidate are changed respectively.
2721 If $KEY is filtered out, this function returns 1. In that case,
2722 the caller should discard the key. Otherwise, it returns 0, and
2723 the caller should handle the key, for instance, by calling the
2724 function minput_lookup () with the same key. */
2727 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
2729 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2730 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
2731 #Minput_preedit_draw, #Minput_status_draw,
2732 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
2735 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
2736 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
2737 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
2738 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
2740 @latexonly \IPAlabel{minput_filter} @endlatexonly
2744 minput_filter (MInputContext *ic, MSymbol key, void *arg)
2751 ret = (*ic->im->driver.filter) (ic, key, arg);
2753 if (ic->im->driver.callback_list)
2755 if (ic->preedit_changed)
2756 minput__callback (ic, Minput_preedit_draw);
2757 if (ic->status_changed)
2758 minput__callback (ic, Minput_status_draw);
2759 if (ic->candidates_changed)
2760 minput__callback (ic, Minput_candidates_draw);
2769 @brief Look up a text produced in the input context.
2771 The minput_lookup () function looks up a text in the input context
2772 $IC. $KEY must be the same one provided to the previous call of
2775 If a text was produced by the input method, it is concatenated
2778 This function calls #MInputDriver::lookup .
2781 If $KEY was correctly handled by the input method, this function
2782 returns 0. Otherwise, returns -1, even in that case, some text
2783 may be produced in $MT. */
2786 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
2788 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
2789 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2791 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
2794 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
2797 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
2798 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
2799 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
2801 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
2804 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2806 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
2811 @brief Set the spot of the input context.
2813 The minput_set_spot () function set the spot of input context $IC
2814 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
2815 The semantics of these values depend on the input method driver.
2817 For instance, a driver designed to work in a CUI environment may
2818 use $X and $Y as column and row numbers, and ignore $ASCENT and
2819 $DESCENT . A driver designed to work in a window system may
2820 interpret $X and $Y as pixel offsets relative to the origin of the
2821 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
2822 descent pixels of the line at ($X . $Y ).
2824 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
2826 $MT and $POS is the M-text and the character position at the spot.
2827 $MT may be @c NULL, in which case, the input method cannot get
2828 information about the text around the spot. */
2831 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
2833 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
2834 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
2835 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
2837 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
2838 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
2839 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
2840 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
2841 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
2842 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
2844 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
2846 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
2847 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
2851 minput_set_spot (MInputContext *ic, int x, int y,
2852 int ascent, int descent, int fontsize,
2857 ic->spot.ascent = ascent;
2858 ic->spot.descent = descent;
2859 ic->spot.fontsize = fontsize;
2862 if (ic->im->driver.callback_list)
2863 minput__callback (ic, Minput_set_spot);
2868 @brief Toggle input method.
2870 The minput_toggle () function toggles the input method associated
2871 with input context $IC. */
2873 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
2875 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2876 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
2880 minput_toggle (MInputContext *ic)
2882 if (ic->im->driver.callback_list)
2883 minput__callback (ic, Minput_toggle);
2884 ic->active = ! ic->active;
2888 @brief Reset an input context.
2890 The minput_reset_ic () function resets input context $IC by
2891 calling a callback function corresponding to #Minput_reset. It
2892 actually shifts the state to the initial one, and thus the current
2893 preediting text (if any) is committed. If necessary, a program
2894 can extract that committed text by calling minput_lookup () just
2895 after the call of minput_reset_ic (). In that case, the arguments
2896 @c KEY and @c ARG of minput_lookup () are ignored. */
2898 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
2900 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
2901 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
2902 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
2903 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
2904 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
2905 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
2908 minput_reset_ic (MInputContext *ic)
2910 if (ic->im->driver.callback_list)
2911 minput__callback (ic, Minput_reset);
2916 @brief Key of a text property for detailed description.
2918 The symbol #Mdetail_text is a managing key usually used for a
2919 text property whose value is an M-text that contains detailed
2922 @brief ¾ÜºÙÀâÌÀÍѥƥ¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼.
2924 ¥·¥ó¥Ü¥ë #Mdetail_text ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ê¡¢Ä̾ï¾ÜºÙ¤ÊÀâÌÀ¤ò´Þ¤à
2925 M-text ¤òÃͤȤ·¤Æ»ý¤Ä¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ËÍѤ¤¤é¤ì¤ë¡£
2927 MSymbol Mdetail_text;
2930 @brief Get description text of an input method.
2932 The minput_get_description () function returns an M-text that
2933 briefly describes the input method specified by $LANGUAGE and
2934 $NAME. The returned M-text may have a text property, from its
2935 beginning to end, #Mdetail_text whose value is an M-text
2936 describing the input method in more detail.
2939 If the specified input method has a description text, a pointer to
2940 #MText is returned. A caller have to free it by m17n_object_unref ().
2941 If the input method does not have a description text, @c NULL is
2944 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
2946 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME
2947 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£ÊÖ¤µ¤ì¤ë M-text
2948 ¤Ë¤Ï¡¢¤½¤ÎÁ´ÂΤËÂФ·¤Æ #Mdetail_text
2949 ¤È¤¤¤¦¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬Éղ䵤ì¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ê¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¤µ¤é¤Ë¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
2953 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
2954 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
2955 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
2958 minput_get_description (MSymbol language, MSymbol name)
2960 MPlist *plist = load_im_info (language, name, M_description);
2966 if (! MPLIST_PLIST_P (plist))
2968 M17N_OBJECT_UNREF (plist);
2971 pl = MPLIST_PLIST (plist);
2972 while (! MPLIST_TAIL_P (pl) && ! MPLIST_MTEXT_P (pl))
2973 pl = MPLIST_NEXT (pl);
2974 if (MPLIST_MTEXT_P (pl))
2975 mt = get_description_advance (pl);
2976 M17N_OBJECT_UNREF (plist);
2981 @brief Get information about input method commands.
2983 The minput_get_commands () function returns information about
2984 input method commands of the input method specified by $LANGUAGE
2985 and $NAME. An input method command is a pseudo key event to which
2986 one or more actual input key sequences are assigned.
2988 There are two kinds of commands, global and local. Global
2989 commands are used by multiple input methods for the same purpose,
2990 and have global key assignments. Local commands are used only in
2991 a specific input method, and have only local key assignments.
2993 Each input method may locally change key assignments for global
2994 commands. A global key assignment for a global command are
2995 effective only when the current input method does not have local
2996 key assignments for that command.
2998 If $NAME is #Mnil, information about global commands is returned.
2999 In this case $LANGUAGE is ignored.
3001 If $NAME is not #Mnil, information about those commands that have
3002 local key assignments in the input method specified by $LANGUAGE
3003 and $NAME is returned.
3006 If no input method commands are found, this function returns @c NULL.
3008 Otherwise, a pointer to a plist is returned. The key of each
3009 element in the plist is a symbol representing a command, and the
3010 value is a plist of the form COMMAND-INFO described below.
3012 The first element of COMMAND-INFO has the key #Mtext, and the
3013 value is an M-text describing the command briefly. This M-text
3014 may have a text property whose key is #Mdetail_text and whose
3015 value is an M-text describing the command in more detail.
3017 If there are no more elements, that means no key sequences are
3018 assigned to the command. Otherwise, each of the remaining
3019 elements has the key #Mplist, and the value is a plist whose keys are
3020 #Msymbol and values are symbols representing input keys, which are
3021 currently assigned to the command.
3023 As the returned plist is kept in the library, the caller must not
3024 modify nor free it. */
3026 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3028 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3029 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3030 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3032 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£
3033 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ÇÍѤ¤¤é¤ì¤ë¡£
3034 ¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3036 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
3037 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ß͸ú¤Ç¤¢¤ë¡£
3039 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3040 ¤³¤Î¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3042 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME
3043 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
3046 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3048 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3049 ¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î
3050 COMMAND-INFO ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3052 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext
3053 ¤ò¡¢ÃͤȤ·¤Æ¤½¤Î¥³¥Þ¥ó¥É¤ò´Êñ¤ËÀâÌÀ¤¹¤ë M-text ¤ò»ý¤Ä¡£¤³¤Î M-text
3055 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤Î¥³¥Þ¥ó¥É¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3058 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
3059 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ#Mplist
3060 ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£
3061 ¤³¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol
3062 ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3064 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3067 minput_get_commands (MSymbol language, MSymbol name)
3069 MPlist *plist = get_command_list (language, name);
3071 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3075 @brief Assign a key sequence to an input method command.
3077 The minput_assign_command_keys () function assigns input key
3078 sequence $KEYSEQ to input method command $COMMAND for the input
3079 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3080 key sequence is assigned globally no matter what $LANGUAGE is.
3081 Otherwise the key sequence is assigned locally.
3083 Each element of $KEYSEQ must have the key $Msymbol and the value
3084 must be a symbol representing an input key.
3086 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3087 globally or locally.
3089 This assignment gets effective in a newly opened input method.
3092 If the operation was successful, 0 is returned. Otherwise -1 is
3093 returned, and #merror_code is set to #MERROR_IM. */
3095 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3097 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME
3098 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND
3099 ¤ËÂФ·¤Æ¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil
3100 ¤Ê¤é¤Ð¡¢$LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
3101 ¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3103 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol
3104 ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3106 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£
3107 ¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3109 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤Ë¤Ê¤ë¡£
3112 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3113 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3116 minput_assign_command_keys (MSymbol language, MSymbol name,
3117 MSymbol command, MPlist *keyseq)
3119 MPlist *plist, *pl, *p;
3121 if (check_command_keyseq (keyseq) < 0
3122 || ! (plist = get_command_list (language, name)))
3123 MERROR (MERROR_IM, -1);
3124 pl = mplist_get (plist, command);
3127 pl = MPLIST_NEXT (pl);
3129 while ((p = mplist_pop (pl)))
3130 M17N_OBJECT_UNREF (p);
3133 keyseq = mplist_copy (keyseq);
3134 mplist_push (pl, Mplist, keyseq);
3135 M17N_OBJECT_UNREF (keyseq);
3141 MERROR (MERROR_IM, -1);
3144 pl = get_command_list (Mnil, Mnil); /* Get global commands. */
3145 pl = mplist_get (pl, command);
3147 MERROR (MERROR_IM, -1);
3149 mplist_add (p, Mtext, mplist_value (pl));
3150 keyseq = mplist_copy (keyseq);
3151 mplist_add (p, Mplist, keyseq);
3152 M17N_OBJECT_UNREF (keyseq);
3153 mplist_push (plist, command, p);
3159 @brief Get a list of variables of an input method.
3161 The minput_get_variables () function returns a plist (#MPlist) of
3162 variables used to control the behavior of the input method
3163 specified by $LANGUAGE and $NAME. The key of an element of the
3164 plist is a symbol representing a variable, and the value is a
3165 plist of the form VAR-INFO (described below) that carries the
3166 information about the variable.
3168 The first element of VAR-INFO has the key #Mtext, and the value is
3169 an M-text describing the variable briefly. This M-text may have a
3170 text property #Mdetail_text whose value is an M-text describing
3171 the variable in more detail.
3173 The second element of VAR-INFO is for the value of the variable.
3174 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3175 integer, a symbol, or an M-text, respectively. The variable is
3176 set to this value when an input context is created for the input
3179 If there are no more elements, the variable can take any value
3180 that matches with the above type. Otherwise, the remaining
3181 elements of VAR-INFO are to specify valid values of the variable.
3183 If the type of the variable is integer, the following elements
3184 have the key #Minteger or #Mplist. If it is #Minteger, the value
3185 is a valid integer value. If it is #Mplist, the value is a plist
3186 of two of elements. Both of them have the key #Minteger, and
3187 values are the minimum and maximum bounds of the valid value
3190 If the type of the variable is symbol or M-text, the following
3191 elements of the plist have the key #Msymbol or #Mtext,
3192 respectively, and the value must be a valid one.
3194 For instance, suppose an input method has the variables:
3196 @li name:intvar, description: "value is an integer",
3197 initial value:0, value-range:0..3,10,20
3199 @li name:symvar, description: "value is a symbol",
3200 initial value:nil, value-range:a, b, c, nil
3202 @li name:txtvar, description: "value is an M-text",
3203 initial value:empty text, no value-range (i.e. any text)
3205 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3206 a value, and '(...)' means a plist):
3209 plist:(intvar:(mtext:'value is an integer'
3211 plist:(integer:0 integer:3)
3214 symvar:(mtext:"value is a symbol"
3220 txtvar:(mtext:"value is an M-text"
3225 If the input method uses any variables, a pointer to #MPlist is
3226 returned. As the plist is kept in the library, a caller must not
3227 modify nor free it. If the input method does not use any
3228 variable, @c NULL is returned. */
3230 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3232 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3233 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3234 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3235 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3236 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3238 VAR-INFO ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·¤Æ #Mtext ¤ò¡¢ÃͤȤ·¤Æ¤½¤ÎÊÑ¿ô¤ò´Êñ¤ËÀâÌÀ¤¹¤ë
3239 M-text ¤ò»ý¤Ä¡£¤³¤Î M-text ¤Ï¡¢#Mdetail_text
3240 ¤ò¥¡¼¤È¤¹¤ë¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤³¤È¤¬¤Ç¤¡¢¤½¤ÎÃͤϤ½¤ÎÊÑ¿ô¤ò¤è¤ê¾ÜºÙ¤ËÀâÌÀ¤¹¤ë
3243 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3244 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3245 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3247 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3248 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3250 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3251 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3252 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3253 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3255 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3256 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3258 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3260 @li name:intvar, ÀâÌÀ:"value is an integer",
3261 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3263 @li name:symvar, ÀâÌÀ:"value is a symbol",
3264 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3266 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3267 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3269 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3270 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3273 plist:(intvar:(mtext:"value is an integer"
3275 plist:(integer:0 integer:3)
3278 symvar:(mtext:"value is a symbol"
3284 txtvar:(mtext:"value is an M-text"
3289 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3290 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3291 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3294 minput_get_variables (MSymbol language, MSymbol name)
3296 MPlist *plist = get_variable_list (language, name);
3298 return (! plist || MPLIST_TAIL_P (plist) ? NULL : plist);
3302 @brief Set the initial value of an input method variable.
3304 The minput_set_variable () function sets the initial value of
3305 input method variable $VARIABLE to $VALUE for the input method
3306 specified by $LANGUAGE and $NAME.
3308 By default, the initial value is 0.
3310 This setting gets effective in a newly opened input method.
3313 If the operation was successful, 0 is returned. Otherwise -1 is
3314 returned, and #merror_code is set to #MERROR_IM. */
3316 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3318 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3319 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3320 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3322 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3324 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3327 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3328 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3331 minput_set_variable (MSymbol language, MSymbol name,
3332 MSymbol variable, void *value)
3334 MPlist *plist, *val_element, *range_element;
3337 if (language == Mnil || name == Mnil)
3338 MERROR (MERROR_IM, -1);
3339 plist = get_variable_list (language, name);
3341 MERROR (MERROR_IM, -1);
3342 plist = (MPlist *) mplist_get (plist, variable);
3344 MERROR (MERROR_IM, -1);
3345 val_element = MPLIST_NEXT (plist);
3346 type = MPLIST_KEY (val_element);
3347 range_element = MPLIST_NEXT (val_element);
3349 if (! MPLIST_TAIL_P (range_element))
3351 if (type == Minteger)
3353 int val = (int) value, this_val;
3355 MPLIST_DO (plist, range_element)
3357 this_val = (int) MPLIST_VAL (plist);
3358 if (MPLIST_PLIST_P (plist))
3360 int min_bound, max_bound;
3361 MPlist *pl = MPLIST_PLIST (plist);
3363 min_bound = (int) MPLIST_VAL (pl);
3364 pl = MPLIST_NEXT (pl);
3365 max_bound = (int) MPLIST_VAL (pl);
3366 if (val >= min_bound && val <= max_bound)
3369 else if (val == this_val)
3372 if (MPLIST_TAIL_P (plist))
3373 MERROR (MERROR_IM, -1);
3375 else if (type == Msymbol)
3377 MPLIST_DO (plist, range_element)
3378 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3380 if (MPLIST_TAIL_P (plist))
3381 MERROR (MERROR_IM, -1);
3383 else /* type == Mtext */
3385 MPLIST_DO (plist, range_element)
3386 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3388 if (MPLIST_TAIL_P (plist))
3389 MERROR (MERROR_IM, -1);
3390 M17N_OBJECT_REF (value);
3394 mplist_set (val_element, type, value);
3400 /*** @addtogroup m17nDebug */
3406 @brief Dump an input method.
3408 The mdebug_dump_im () function prints the input method $IM in a
3409 human readable way to the stderr. $INDENT specifies how many
3410 columns to indent the lines but the first one.
3413 This function returns $IM. */
3415 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3417 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3418 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3421 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3424 mdebug_dump_im (MInputMethod *im, int indent)
3426 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3429 prefix = (char *) alloca (indent + 1);
3430 memset (prefix, 32, indent);
3431 prefix[indent] = '\0';
3433 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3434 msymbol_name (im->name));
3435 mdebug_dump_mtext (im_info->title, 0, 0);
3436 if (im->name != Mnil)
3440 MPLIST_DO (state, im_info->states)
3442 fprintf (stderr, "\n%s ", prefix);
3443 dump_im_state (MPLIST_VAL (state), indent + 2);
3446 fprintf (stderr, ")");