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>
143 #include <sys/stat.h>
152 #include "m17n-gui.h"
153 #include "m17n-misc.h"
154 #include "internal.h"
159 #include "database.h"
162 static int mdebug_mask = MDEBUG_INPUT;
164 static MSymbol Minput_method;
166 /** Symbols to load an input method data. */
167 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
169 /** Symbols for actions. */
170 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
171 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
172 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
173 static MSymbol M_candidates;
175 static MSymbol Mcandidate_list, Mcandidate_index;
177 static MSymbol Minit, Mfini;
179 /** Symbols for variables. */
180 static MSymbol Mcandidates_group_size, Mcandidates_charset;
182 /** Symbols for key events. */
183 static MSymbol one_char_symbol[256];
185 static MSymbol M_key_alias;
187 static MSymbol M_description, M_command, M_variable;
189 /** Structure to hold a map. */
193 /** List of actions to take when we reach the map. In a root map,
194 the actions are executed only when there's no more key. */
197 /** List of deeper maps. If NULL, this is a terminal map. */
200 /** List of actions to take when we leave the map successfully. In
201 a root map, the actions are executed only when none of submaps
202 handle the current key. */
203 MPlist *branch_actions;
206 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
211 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
218 /** Name of the state. */
221 /** Title of the state, or NULL. */
224 /** Key translation map of the state. Built by merging all maps of
229 /* Lookup keys KEY1,2,3 in the nested plist PLIST, and return the
233 lookup_nested_list (MPlist *plist, MSymbol key1, MSymbol key2, MSymbol key3)
238 key[0] = key1, key[1] = key2, key[2] = key3;
239 for (i = 0; i < 3; i++)
241 plist = mplist_find_by_value (plist, key[i]);
244 plist = MPLIST_NEXT (plist);
245 plist = MPLIST_PLIST (plist);
250 /* Set VAL for keys KEY1,2,3 in the nested plist PLIST. */
253 set_nested_list (MPlist *plist, MSymbol key1, MSymbol key2, MSymbol key3,
260 key[0] = key1, key[1] = key2, key[2] = key3;
261 for (i = 0; i < 3; i++)
263 pl = mplist_find_by_value (plist, key[i]);
266 pl = MPLIST_NEXT (pl);
267 plist = MPLIST_PLIST (pl);
271 pl = mplist_add (plist, Msymbol, key[i]);
273 pl = mplist_add (pl, Mplist, plist);
274 M17N_OBJECT_UNREF (plist);
277 mplist_set (pl, Mplist, val);
278 M17N_OBJECT_UNREF (val);
282 /* Parse PLIST as a value of nested list and return an adjusted list.
287 [ mtext:DESCRIPTION | symbol:nil ]
288 ;; The remaining elements are checked CHECK_FUNC.
291 [ mtext:DESCRIPTION | symbol:nil ]
292 ;; The remaining elements are checked CHECK_FUNC.
296 GLOBAL is a global list. If a description text is missing, it is
297 extracted from GLOBAL.
299 The return value is a plist of this format:
301 plist:([ mtext:DESCRIPTION | symbol:nil ]
304 plist:([ mtext:DESCRIPTION | symbol:nil ]
308 PLIST itself is unref-ed. */
311 parse_nested_list_value (MPlist *plist, MPlist *global, MSymbol key,
312 int (*check_func) (MPlist *))
317 if (! MPLIST_PLIST_P (plist))
319 M17N_OBJECT_UNREF (plist);
322 pl = MPLIST_PLIST (plist);
323 if (! MPLIST_SYMBOL_P (pl)
324 || MPLIST_SYMBOL (pl) != key)
326 M17N_OBJECT_UNREF (plist);
330 MPLIST_DO (pl, MPLIST_NEXT (pl))
335 if (! MPLIST_PLIST_P (pl))
337 p = MPLIST_PLIST (pl);
338 if (! MPLIST_SYMBOL_P (p))
340 cmd = MPLIST_SYMBOL (p);
342 if (! MPLIST_MTEXT_P (p))
344 mplist_set (p, Msymbol, Mnil);
347 MPlist *p0 = mplist_find_by_value (global, cmd);
352 p0 = MPLIST_NEXT (p0);
353 if (MPLIST_MTEXT_P (p0))
355 description = MPLIST_MTEXT (p0);
356 mplist_set (p, Mtext, description);
361 if ((*check_func) (MPLIST_NEXT (p)) < 0)
363 mplist_add (val, Msymbol, cmd);
364 mplist_add (val, Mplist, p);
367 M17N_OBJECT_UNREF (plist);
371 static MPlist *variable_list, *command_list;
372 static int check_variable_list (MPlist *plist);
373 static int check_command_list (MPlist *plist);
374 static MPlist *load_partial_im_info (MSymbol language, MSymbol name,
375 MSymbol extra, MSymbol key);
378 get_nested_list (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
381 int (*check_func) (MPlist *);
382 MPlist *plist, *global;
384 if (key == M_variable)
387 variable_list = mplist ();
388 total_list = variable_list;
389 check_func = check_variable_list;
394 command_list = mplist ();
395 total_list = command_list;
396 check_func = check_command_list;
399 if (MPLIST_TAIL_P (total_list))
401 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, key);
403 if (mdb && (plist = mdatabase_load (mdb)))
404 global = parse_nested_list_value (plist, NULL, key, check_func);
407 set_nested_list (total_list, Mt, Mnil, key, global);
410 global = lookup_nested_list (total_list, Mt, Mnil, key);
415 plist = lookup_nested_list (total_list, language, name, extra);
419 plist = load_partial_im_info (language, name, extra, key);
421 plist = parse_nested_list_value (plist, global, key, check_func);
424 set_nested_list (total_list, language, name, extra, plist);
429 marker_code (MSymbol sym)
435 name = MSYMBOL_NAME (sym);
436 return ((name[0] == '@'
437 && ((name[1] >= '0' && name[1] <= '9')
438 || name[1] == '<' || name[1] == '>'
439 || name[1] == '=' || name[1] == '+' || name[1] == '-'
440 || name[1] == '[' || name[1] == ']')
447 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
451 MPLIST_DO (p, ic_info->vars)
453 if (MPLIST_SYMBOL (p) == var)
457 if (MPLIST_TAIL_P (p))
460 mplist_push (p, Minteger, (void *) 0);
461 mplist_push (p, Msymbol, var);
463 return (MPLIST_NEXT (p));
468 integer_value (MInputContext *ic, MPlist *arg, MPlist **value)
470 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
472 MText *preedit = ic->preedit;
473 int len = mtext_nchars (preedit);
477 if (MPLIST_INTEGER_P (arg))
478 return MPLIST_INTEGER (arg);
479 code = marker_code (MPLIST_SYMBOL (arg));
482 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
486 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
488 if (code >= '0' && code <= '9')
490 else if (code == '=')
491 code = ic->cursor_pos;
492 else if (code == '-' || code == '[')
493 code = ic->cursor_pos - 1;
494 else if (code == '+' || code == ']')
495 code = ic->cursor_pos + 1;
496 else if (code == '<')
498 else if (code == '>')
500 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
504 /* Parse PLIST as an action list. PLIST should have this form:
505 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
506 Return 0 if successfully parsed, otherwise return -1. */
509 parse_action_list (MPlist *plist, MPlist *macros)
511 MPLIST_DO (plist, plist)
513 if (MPLIST_MTEXT_P (plist))
515 /* This is a short form of (insert MTEXT). */
516 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
517 MERROR (MERROR_IM, -1); */
519 else if (MPLIST_PLIST_P (plist)
520 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
521 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
525 /* This is a short form of (insert (GROUPS *)). */
526 MPLIST_DO (pl, MPLIST_PLIST (plist))
528 if (MPLIST_PLIST_P (pl))
532 MPLIST_DO (elt, MPLIST_PLIST (pl))
533 if (! MPLIST_MTEXT_P (elt)
534 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
535 MERROR (MERROR_IM, -1);
539 if (! MPLIST_MTEXT_P (pl)
540 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
541 MERROR (MERROR_IM, -1);
545 else if (MPLIST_INTEGER_P (plist))
547 int c = MPLIST_INTEGER (plist);
549 if (c < 0 || c > MCHAR_MAX)
550 MERROR (MERROR_IM, -1);
552 else if (MPLIST_PLIST_P (plist)
553 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
555 MPlist *pl = MPLIST_PLIST (plist);
556 MSymbol action_name = MPLIST_SYMBOL (pl);
558 pl = MPLIST_NEXT (pl);
560 if (action_name == Minsert)
562 if (MPLIST_MTEXT_P (pl))
564 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
565 MERROR (MERROR_IM, -1);
567 else if (MPLIST_PLIST_P (pl))
571 if (MPLIST_PLIST_P (pl))
575 MPLIST_DO (elt, MPLIST_PLIST (pl))
576 if (! MPLIST_MTEXT_P (elt)
577 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
578 MERROR (MERROR_IM, -1);
582 if (! MPLIST_MTEXT_P (pl)
583 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
584 MERROR (MERROR_IM, -1);
588 else if (! MPLIST_SYMBOL_P (pl))
589 MERROR (MERROR_IM, -1);
591 else if (action_name == Mselect
592 || action_name == Mdelete
593 || action_name == Mmove)
595 if (! MPLIST_SYMBOL_P (pl)
596 && ! MPLIST_INTEGER_P (pl))
597 MERROR (MERROR_IM, -1);
599 else if (action_name == Mmark
600 || action_name == Mcall
601 || action_name == Mshift)
603 if (! MPLIST_SYMBOL_P (pl))
604 MERROR (MERROR_IM, -1);
606 else if (action_name == Mundo)
608 if (! MPLIST_TAIL_P (pl))
610 if (! MPLIST_INTEGER_P (pl)
611 || MPLIST_INTEGER (pl) <= 0)
612 MERROR (MERROR_IM, -1);
615 else if (action_name == Mpushback)
617 if (MPLIST_MTEXT_P (pl))
619 MText *mt = MPLIST_MTEXT (pl);
621 if (mtext_nchars (mt) != mtext_nbytes (mt))
622 MERROR (MERROR_IM, -1);
624 else if (MPLIST_PLIST_P (pl))
628 MPLIST_DO (p, MPLIST_PLIST (pl))
629 if (! MPLIST_SYMBOL_P (p))
630 MERROR (MERROR_IM, -1);
632 else if (! MPLIST_INTEGER_P (pl))
633 MERROR (MERROR_IM, -1);
635 else if (action_name == Mset || action_name == Madd
636 || action_name == Msub || action_name == Mmul
637 || action_name == Mdiv)
639 if (! (MPLIST_SYMBOL_P (pl)
640 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
641 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
642 MERROR (MERROR_IM, -1);
644 else if (action_name == Mequal || action_name == Mless
645 || action_name == Mgreater)
647 if (! ((MPLIST_INTEGER_P (pl) || MPLIST_SYMBOL_P (pl))
648 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
649 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
650 MERROR (MERROR_IM, -1);
651 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
652 if (! MPLIST_PLIST_P (pl))
653 MERROR (MERROR_IM, -1);
654 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
655 MERROR (MERROR_IM, -1);
656 pl = MPLIST_NEXT (pl);
657 if (MPLIST_PLIST_P (pl)
658 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
659 MERROR (MERROR_IM, -1);
661 else if (action_name == Mshow || action_name == Mhide
662 || action_name == Mcommit || action_name == Munhandle)
664 else if (! macros || ! mplist_get (macros, action_name))
665 MERROR (MERROR_IM, -1);
668 MERROR (MERROR_IM, -1);
675 resolve_command (MSymbol language, MSymbol name, MSymbol command)
677 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
680 || ! (plist = mplist_get (plist, command)))
682 plist = MPLIST_NEXT (plist);
683 if (! MPLIST_PLIST_P (plist))
690 /* Load a translation into MAP from PLIST.
692 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
695 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
696 MPlist *branch_actions, MPlist *macros)
701 if (MPLIST_MTEXT_P (keylist))
703 MText *mt = MPLIST_MTEXT (keylist);
705 len = mtext_nchars (mt);
706 if (len == 0 || len != mtext_nbytes (mt))
707 MERROR (MERROR_IM, -1);
708 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
709 for (i = 0; i < len; i++)
710 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
712 else if (MPLIST_PLIST_P (keylist))
714 MPlist *elt = MPLIST_PLIST (keylist);
716 len = MPLIST_LENGTH (elt);
718 MERROR (MERROR_IM, -1);
719 keyseq = (MSymbol *) alloca (sizeof (int) * len);
720 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
722 if (MPLIST_INTEGER_P (elt))
724 int c = MPLIST_INTEGER (elt);
726 if (c < 0 || c >= 0x100)
727 MERROR (MERROR_IM, -1);
728 keyseq[i] = one_char_symbol[c];
730 else if (MPLIST_SYMBOL_P (elt))
731 keyseq[i] = MPLIST_SYMBOL (elt);
733 MERROR (MERROR_IM, -1);
737 MERROR (MERROR_IM, -1);
739 for (i = 0; i < len; i++)
741 MIMMap *deeper = NULL;
744 deeper = mplist_get (map->submaps, keyseq[i]);
746 map->submaps = mplist ();
749 /* Fixme: It is better to make all deeper maps at once. */
750 MSTRUCT_CALLOC (deeper, MERROR_IM);
751 mplist_put (map->submaps, keyseq[i], deeper);
756 /* We reach a terminal map. */
758 || map->branch_actions)
759 /* This map is already defined. We avoid overriding it. */
762 if (! MPLIST_TAIL_P (map_actions))
764 if (parse_action_list (map_actions, macros) < 0)
765 MERROR (MERROR_IM, -1);
766 map->map_actions = map_actions;
770 map->branch_actions = branch_actions;
771 M17N_OBJECT_REF (branch_actions);
777 /* Load a branch from PLIST into MAP. PLIST has this form:
778 PLIST ::= ( MAP-NAME BRANCH-ACTION * )
779 MAPS is a plist of raw maps.
780 STATE is the current state. */
783 load_branch (MPlist *plist, MPlist *maps, MIMMap *map,
784 MSymbol language, MSymbol name, MPlist *macros)
787 MPlist *branch_actions;
789 if (! MPLIST_SYMBOL_P (plist))
790 MERROR (MERROR_IM, -1);
791 map_name = MPLIST_SYMBOL (plist);
792 plist = MPLIST_NEXT (plist);
793 if (MPLIST_TAIL_P (plist))
794 branch_actions = NULL;
795 else if (parse_action_list (plist, macros) < 0)
796 MERROR (MERROR_IM, -1);
798 branch_actions = plist;
799 if (map_name == Mnil)
801 map->branch_actions = branch_actions;
803 M17N_OBJECT_REF (branch_actions);
805 else if (map_name == Mt)
807 map->map_actions = branch_actions;
809 M17N_OBJECT_REF (branch_actions);
813 plist = (MPlist *) mplist_get (maps, map_name);
814 if (! plist || ! MPLIST_PLIST_P (plist))
815 MERROR (MERROR_IM, -1);
816 MPLIST_DO (plist, plist)
818 MPlist *keylist, *map_actions;
820 if (! MPLIST_PLIST_P (plist))
821 MERROR (MERROR_IM, -1);
822 keylist = MPLIST_PLIST (plist);
823 map_actions = MPLIST_NEXT (keylist);
824 if (MPLIST_SYMBOL_P (keylist))
826 MSymbol command = MPLIST_SYMBOL (keylist);
827 MPlist *pl = resolve_command (language, name, command);
832 if (load_translation (map, pl, map_actions, branch_actions,
834 MERROR (MERROR_IM, -1);
837 if (load_translation (map, keylist, map_actions, branch_actions,
839 MERROR (MERROR_IM, -1);
846 /* Load a macro from PLIST into MACROS.
848 PLIST ::= ( MACRO-NAME ACTION * )
849 MACROS is a plist of macro names vs action list. */
851 load_macros (MPlist *plist, MPlist *macros)
855 if (! MPLIST_SYMBOL_P (plist))
856 MERROR (MERROR_IM, -1);
857 name = MPLIST_SYMBOL (plist);
858 plist = MPLIST_NEXT (plist);
859 if (MPLIST_TAIL_P (plist)
860 || parse_action_list (plist, macros) < 0)
861 MERROR (MERROR_IM, -1);
862 mplist_put (macros, name, plist);
863 M17N_OBJECT_REF (plist);
867 /* Load an external module from PLIST into EXTERNALS.
869 PLIST ::= ( MODULE-NAME FUNCTION * )
870 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
873 load_external_module (MPlist *plist, MPlist *externals)
878 MIMExternalModule *external;
882 if (MPLIST_MTEXT_P (plist))
883 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
884 else if (MPLIST_SYMBOL_P (plist))
885 module = MPLIST_SYMBOL (plist);
886 module_file = alloca (strlen (MSYMBOL_NAME (module))
887 + strlen (DLOPEN_SHLIB_EXT) + 1);
888 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
890 handle = dlopen (module_file, RTLD_NOW);
893 fprintf (stderr, "%s\n", dlerror ());
894 MERROR (MERROR_IM, -1);
896 func_list = mplist ();
897 MPLIST_DO (plist, MPLIST_NEXT (plist))
899 if (! MPLIST_SYMBOL_P (plist))
900 MERROR_GOTO (MERROR_IM, err_label);
901 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
903 MERROR_GOTO (MERROR_IM, err_label);
904 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
907 MSTRUCT_MALLOC (external, MERROR_IM);
908 external->handle = handle;
909 external->func_list = func_list;
910 mplist_add (externals, module, external);
915 M17N_OBJECT_UNREF (func_list);
920 free_map (MIMMap *map, int top)
925 M17N_OBJECT_UNREF (map->map_actions);
928 MPLIST_DO (plist, map->submaps)
929 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
930 M17N_OBJECT_UNREF (map->submaps);
932 M17N_OBJECT_UNREF (map->branch_actions);
937 free_state (void *object)
939 MIMState *state = object;
942 M17N_OBJECT_UNREF (state->title);
944 free_map (state->map, 1);
948 /** Load a state from PLIST into a newly allocated state object.
950 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
951 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
952 MAPS is a plist of defined maps.
953 Return the state object. */
956 load_state (MPlist *plist, MPlist *maps, MSymbol language, MSymbol name,
961 if (! MPLIST_SYMBOL_P (plist))
962 MERROR (MERROR_IM, NULL);
963 M17N_OBJECT (state, free_state, MERROR_IM);
964 state->name = MPLIST_SYMBOL (plist);
965 plist = MPLIST_NEXT (plist);
966 if (MPLIST_MTEXT_P (plist))
968 state->title = MPLIST_MTEXT (plist);
969 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
970 Mlanguage, language);
971 M17N_OBJECT_REF (state->title);
972 plist = MPLIST_NEXT (plist);
974 MSTRUCT_CALLOC (state->map, MERROR_IM);
975 MPLIST_DO (plist, plist)
976 if (! MPLIST_PLIST_P (plist)
977 || load_branch (MPLIST_PLIST (plist), maps, state->map, language, name,
979 MERROR (MERROR_IM, NULL);
984 static MPlist *im_info_list;
987 free_im_info (MInputMethodInfo *im_info)
992 M17N_OBJECT_UNREF (im_info->title);
995 MPLIST_DO (plist, im_info->states)
997 MIMState *state = (MIMState *) MPLIST_VAL (plist);
999 M17N_OBJECT_UNREF (state);
1001 M17N_OBJECT_UNREF (im_info->states);
1004 if (im_info->macros)
1006 MPLIST_DO (plist, im_info->macros)
1007 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1008 M17N_OBJECT_UNREF (im_info->macros);
1011 if (im_info->externals)
1013 MPLIST_DO (plist, im_info->externals)
1015 MIMExternalModule *external = MPLIST_VAL (plist);
1017 dlclose (external->handle);
1018 M17N_OBJECT_UNREF (external->func_list);
1020 MPLIST_KEY (plist) = Mt;
1022 M17N_OBJECT_UNREF (im_info->externals);
1026 MPLIST_DO (plist, im_info->maps)
1028 MPlist *p = MPLIST_PLIST (plist);
1030 M17N_OBJECT_UNREF (p);
1032 M17N_OBJECT_UNREF (im_info->maps);
1038 static MInputMethodInfo *get_im_info (MSymbol language, MSymbol name,
1041 static MInputMethodInfo *
1042 get_im_info_by_tags (MPlist *plist)
1047 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1048 i++, plist = MPLIST_NEXT (plist))
1049 tag[i] = MPLIST_SYMBOL (plist);
1054 return get_im_info (tag[0], tag[1], tag[2]);
1057 /* Load an input method from PLIST into IM_INTO, and return it. */
1059 static MInputMethodInfo *
1060 load_im_info (MSymbol language, MSymbol name, MPlist *plist)
1062 MInputMethodInfo *im_info;
1063 MText *title = NULL;
1064 MPlist *maps = NULL;
1065 MPlist *states = NULL;
1066 MPlist *externals = NULL;
1067 MPlist *macros = NULL;
1070 MSTRUCT_CALLOC (im_info, MERROR_IM);
1072 while (MPLIST_PLIST_P (plist))
1074 elt = MPLIST_PLIST (plist);
1075 if (! MPLIST_SYMBOL_P (elt))
1076 MERROR_GOTO (MERROR_IM, err);
1077 if (MPLIST_SYMBOL (elt) == Mtitle)
1079 elt = MPLIST_NEXT (elt);
1080 if (! MPLIST_MTEXT_P (elt))
1081 MERROR_GOTO (MERROR_IM, err);
1082 im_info->title = title = MPLIST_MTEXT (elt);
1083 M17N_OBJECT_REF (title);
1085 else if (MPLIST_SYMBOL (elt) == Mmap)
1087 MPlist *pl = mplist__from_alist (MPLIST_NEXT (elt));
1090 MERROR_GOTO (MERROR_IM, err);
1092 im_info->maps = maps = pl;
1094 maps = mplist__conc (maps, pl);
1096 else if (MPLIST_SYMBOL (elt) == Mmacro)
1099 im_info->macros = macros = mplist ();
1100 MPLIST_DO (elt, MPLIST_NEXT (elt))
1102 if (! MPLIST_PLIST_P (elt)
1103 || load_macros (MPLIST_PLIST (elt), macros) < 0)
1104 MERROR_GOTO (MERROR_IM, err);
1107 else if (MPLIST_SYMBOL (elt) == Mmodule)
1110 im_info->externals = externals = mplist ();
1111 MPLIST_DO (elt, MPLIST_NEXT (elt))
1113 if (! MPLIST_PLIST_P (elt)
1114 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
1115 MERROR_GOTO (MERROR_IM, err);
1118 else if (MPLIST_SYMBOL (elt) == Mstate)
1120 MPLIST_DO (elt, MPLIST_NEXT (elt))
1124 if (! MPLIST_PLIST_P (elt))
1125 MERROR_GOTO (MERROR_IM, err);
1126 state = load_state (MPLIST_PLIST (elt), maps, language, name,
1129 MERROR_GOTO (MERROR_IM, err);
1131 im_info->states = states = mplist ();
1132 mplist_put (states, state->name, state);
1135 else if (MPLIST_SYMBOL (elt) == Minclude)
1137 /* elt ::= include (tag1 tag2 ...) key item ... */
1139 MInputMethodInfo *temp;
1142 elt = MPLIST_NEXT (elt);
1143 if (! MPLIST_PLIST_P (elt))
1144 MERROR_GOTO (MERROR_IM, err);
1145 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
1147 MERROR_GOTO (MERROR_IM, err);
1148 elt = MPLIST_NEXT (elt);
1149 if (! MPLIST_SYMBOL_P (elt))
1150 MERROR_GOTO (MERROR_IM, err);
1151 key = MPLIST_SYMBOL (elt);
1152 elt = MPLIST_NEXT (elt);
1156 im_info->maps = maps = mplist ();
1157 MPLIST_DO (pl, temp->maps)
1159 p = MPLIST_VAL (pl);
1160 MPLIST_ADD_PLIST (maps, MPLIST_KEY (pl), p);
1161 M17N_OBJECT_REF (p);
1164 else if (key == Mmacro)
1167 im_info->macros = macros = mplist ();
1168 MPLIST_DO (pl, temp->macros)
1170 p = MPLIST_VAL (pl);
1171 MPLIST_ADD_PLIST (macros, MPLIST_KEY (pl), p);
1172 M17N_OBJECT_REF (p);
1175 else if (key == Mstate)
1178 im_info->states = states = mplist ();
1179 MPLIST_DO (pl, temp->states)
1181 MIMState *state = MPLIST_VAL (pl);
1183 MPLIST_ADD_PLIST (states, MPLIST_KEY (pl), state);
1184 M17N_OBJECT_REF (state);
1188 MERROR_GOTO (MERROR_IM, err);
1190 plist = MPLIST_NEXT (plist);
1197 = title = mtext_from_data (MSYMBOL_NAME (im_info->im->name),
1198 MSYMBOL_NAMELEN (im_info->im->name),
1199 MTEXT_FORMAT_US_ASCII);
1203 free_im_info (im_info);
1209 static int take_action_list (MInputContext *ic, MPlist *action_list);
1210 static void preedit_commit (MInputContext *ic);
1213 shift_state (MInputContext *ic, MSymbol state_name)
1215 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1216 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1217 MIMState *orig_state = ic_info->state, *state;
1219 /* Find a state to shift to. If not found, shift to the initial
1221 if (state_name == Mt)
1223 if (! ic_info->prev_state)
1225 state = ic_info->prev_state;
1229 state = (MIMState *) mplist_get (im_info->states, state_name);
1231 state = (MIMState *) MPLIST_VAL (im_info->states);
1234 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
1236 /* Enter the new state. */
1237 ic_info->state = state;
1238 ic_info->map = state->map;
1239 ic_info->state_key_head = ic_info->key_head;
1240 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1241 /* We have shifted to the initial state. */
1242 preedit_commit (ic);
1243 mtext_cpy (ic_info->preedit_saved, ic->preedit);
1244 ic_info->state_pos = ic->cursor_pos;
1245 if (state != orig_state )
1247 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1248 ic_info->prev_state = NULL;
1250 ic_info->prev_state = orig_state;
1253 ic->status = state->title;
1254 else if (! ic->status)
1255 ic->status = im_info->title;
1256 ic->status_changed = 1;
1257 if (ic_info->map == ic_info->state->map
1258 && ic_info->map->map_actions)
1260 MDEBUG_PRINT (" init-actions:");
1261 take_action_list (ic, ic_info->map->map_actions);
1266 /* Find a candidate group that contains a candidate number INDEX from
1267 PLIST. Set START_INDEX to the first candidate number of the group,
1268 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
1269 candidate group number if they are non-NULL. If INDEX is -1, find
1270 the last candidate group. */
1273 find_candidates_group (MPlist *plist, int index,
1274 int *start_index, int *end_index, int *group_index)
1276 int i = 0, gidx = 0, len;
1278 MPLIST_DO (plist, plist)
1280 if (MPLIST_MTEXT_P (plist))
1281 len = mtext_nchars (MPLIST_MTEXT (plist));
1283 len = mplist_length (MPLIST_PLIST (plist));
1284 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
1290 *end_index = i + len;
1292 *group_index = gidx;
1302 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
1304 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1306 int nchars = mt ? mtext_nchars (mt) : 1;
1309 mtext_ins (ic->preedit, pos, mt);
1311 mtext_ins_char (ic->preedit, pos, c, 1);
1312 MPLIST_DO (markers, ic_info->markers)
1313 if (MPLIST_INTEGER (markers) > pos)
1314 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
1315 if (ic->cursor_pos >= pos)
1316 ic->cursor_pos += nchars;
1317 ic->preedit_changed = 1;
1322 preedit_delete (MInputContext *ic, int from, int to)
1324 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1327 mtext_del (ic->preedit, from, to);
1328 MPLIST_DO (markers, ic_info->markers)
1330 if (MPLIST_INTEGER (markers) > to)
1331 MPLIST_VAL (markers)
1332 = (void *) (MPLIST_INTEGER (markers) - (to - from));
1333 else if (MPLIST_INTEGER (markers) > from);
1334 MPLIST_VAL (markers) = (void *) from;
1336 if (ic->cursor_pos >= to)
1337 ic->cursor_pos -= to - from;
1338 else if (ic->cursor_pos > from)
1339 ic->cursor_pos = from;
1340 ic->preedit_changed = 1;
1344 preedit_commit (MInputContext *ic)
1346 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1347 int preedit_len = mtext_nchars (ic->preedit);
1349 if (preedit_len > 0)
1353 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1354 Mcandidate_list, NULL, 0);
1355 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1356 Mcandidate_index, NULL, 0);
1357 mtext_cat (ic->produced, ic->preedit);
1358 if ((mdebug__flag & mdebug_mask)
1359 && mtext_nchars (ic->produced) > 0)
1363 MDEBUG_PRINT (" (produced");
1364 for (i = 0; i < mtext_nchars (ic->produced); i++)
1365 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
1368 mtext_reset (ic->preedit);
1369 mtext_reset (ic_info->preedit_saved);
1370 MPLIST_DO (p, ic_info->markers)
1372 ic->cursor_pos = ic_info->state_pos = 0;
1373 ic->preedit_changed = 1;
1375 if (ic->candidate_list)
1377 M17N_OBJECT_UNREF (ic->candidate_list);
1378 ic->candidate_list = NULL;
1379 ic->candidate_show = 0;
1380 ic->candidates_changed = 1;
1383 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
1384 sizeof (int) * (ic_info->used - ic_info->key_head));
1385 ic_info->used -= ic_info->key_head;
1386 ic_info->state_key_head = ic_info->key_head = 0;
1390 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
1392 int code = marker_code (sym);
1394 if (mt && (code == '[' || code == ']'))
1398 if (code == '[' && current > 0)
1400 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
1404 else if (code == ']' && current < mtext_nchars (mt))
1406 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
1412 return (code == '<' ? 0
1413 : code == '>' ? limit
1414 : code == '-' ? current - 1
1415 : code == '+' ? current + 1
1416 : code == '=' ? current
1417 : code - '0' > limit ? limit
1421 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1425 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1427 int from = mtext_property_start (prop);
1428 int to = mtext_property_end (prop);
1430 MPlist *candidate_list = mtext_property_value (prop);
1431 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1433 int ingroup_index = idx - start;
1436 preedit_delete (ic, from, to);
1437 if (MPLIST_MTEXT_P (group))
1439 mt = MPLIST_MTEXT (group);
1440 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1448 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1449 i++, plist = MPLIST_NEXT (plist));
1450 mt = MPLIST_MTEXT (plist);
1451 preedit_insert (ic, from, mt, 0);
1452 to = from + mtext_nchars (mt);
1454 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1455 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1456 ic->cursor_pos = to;
1460 get_select_charset (MInputContextInfo * ic_info)
1462 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
1465 if (! MPLIST_VAL (plist))
1467 sym = MPLIST_SYMBOL (plist);
1470 return MCHARSET (sym);
1474 adjust_candidate_command (MInputContextInfo *ic_info, MPlist *args,
1479 /* args ::= ((MTEXT ...) ...) | ((PLIST ...) ...) */
1480 plist = mplist_copy (MPLIST_PLIST (args));
1481 if (MPLIST_MTEXT_P (plist))
1484 while (! MPLIST_TAIL_P (pl))
1486 /* pl ::= (MTEXT ...) */
1487 MText *mt = MPLIST_MTEXT (pl);
1491 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1493 c = mtext_ref_char (mt, i);
1494 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1498 mt = mtext_dup (mt);
1499 mplist_set (pl, Mtext, mt);
1500 M17N_OBJECT_UNREF (mt);
1503 mtext_del (mt, i, i + 1);
1506 if (mtext_len (mt) > 0)
1507 pl = MPLIST_NEXT (pl);
1511 M17N_OBJECT_UNREF (mt);
1515 else /* MPLIST_PLIST_P (plist) */
1518 while (! MPLIST_TAIL_P (pl))
1520 /* pl ::= ((MTEXT ...) ...) */
1521 MPlist *p = MPLIST_PLIST (pl);
1522 /* p ::= (MTEXT ...) */
1526 while (MPLIST_TAIL_P (p))
1528 MText *mt = MPLIST_MTEXT (p);
1531 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1533 c = mtext_ref_char (mt, i);
1534 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1541 p = mplist_copy (MPLIST_PLIST (pl));
1542 mplist_set (pl, Mplist, pl);
1543 M17N_OBJECT_UNREF (p);
1546 p = MPLIST_NEXT (p);
1549 M17N_OBJECT_UNREF (mt);
1552 if (MPLIST_TAIL_P (p))
1553 pl = MPLIST_NEXT (pl);
1556 p = mplist_pop (pl);
1557 M17N_OBJECT_UNREF (p);
1561 if (MPLIST_TAIL_P (plist))
1563 M17N_OBJECT_UNREF (plist);
1567 mplist_add (args, Mplist, plist);
1568 M17N_OBJECT_UNREF (plist);
1573 take_action_list (MInputContext *ic, MPlist *action_list)
1575 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1576 MPlist *candidate_list = ic->candidate_list;
1577 int candidate_index = ic->candidate_index;
1578 int candidate_show = ic->candidate_show;
1579 MTextProperty *prop;
1581 MPLIST_DO (action_list, action_list)
1587 if (MPLIST_PLIST_P (action_list)
1588 && MPLIST_SYMBOL_P (MPLIST_PLIST (action_list)))
1590 action = MPLIST_PLIST (action_list);
1591 name = MPLIST_SYMBOL (action);
1592 args = MPLIST_NEXT (action);
1594 && MPLIST_PLIST_P (args))
1596 name = M_candidates;
1597 mplist_set (action, Msymbol, name);
1600 else if (MPLIST_MTEXT_P (action_list)
1601 || MPLIST_INTEGER_P (action_list))
1604 mplist_push (action, MPLIST_KEY (action_list),
1605 MPLIST_VAL (action_list));
1606 mplist_push (action, Msymbol, Minsert);
1607 mplist_set (action_list, Mplist, action);
1608 M17N_OBJECT_UNREF (action);
1610 args = MPLIST_NEXT (action);
1614 /* (MPLIST_PLIST_P (action_list)
1615 && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list))
1616 || MPLIST_PLIST_P (MPLIST_PLIST (action_list)))) */
1618 mplist_push (action, Mplist, MPLIST_VAL (action_list));
1619 mplist_push (action, Msymbol, M_candidates);
1620 mplist_set (action_list, Mplist, action);
1621 M17N_OBJECT_UNREF (action);
1622 name = M_candidates;
1623 args = MPLIST_NEXT (action);
1626 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1627 if (name == Minsert)
1629 if (MPLIST_SYMBOL_P (args))
1631 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
1632 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
1635 if (MPLIST_MTEXT_P (args))
1636 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1637 else /* MPLIST_INTEGER_P (args)) */
1638 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1640 else if (name == M_candidates)
1642 MCharset *charset = get_select_charset (ic_info);
1643 MPlist *plist = resolve_variable (ic_info, Mcandidates_group_size);
1644 int column = MPLIST_INTEGER (plist);
1650 if (! (args = adjust_candidate_command (ic_info, args, charset)))
1654 /* Avoid freeing ARGS later. */
1655 M17N_OBJECT_REF (args);
1657 plist = MPLIST_PLIST (args);
1660 MPlist *next = MPLIST_NEXT (plist);
1662 if (MPLIST_MTEXT_P (plist))
1664 MText *mt = MPLIST_MTEXT (plist);
1666 if (MPLIST_TAIL_P (next))
1667 M17N_OBJECT_REF (mt);
1670 mt = mtext_dup (mt);
1671 while (! MPLIST_TAIL_P (next))
1673 mt = mtext_cat (mt, MPLIST_MTEXT (next));
1674 next = MPLIST_NEXT (next);
1677 len = mtext_nchars (mt);
1681 for (i = 0; i < len; i += column)
1683 int to = (i + column < len ? i + column : len);
1684 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
1686 mplist_add (plist, Mtext, sub);
1687 M17N_OBJECT_UNREF (sub);
1690 M17N_OBJECT_UNREF (mt);
1692 else /* MPLIST_PLIST_P (plist) */
1694 MPlist *pl = MPLIST_PLIST (plist), *p;
1697 if (MPLIST_TAIL_P (next))
1698 M17N_OBJECT_REF (pl);
1701 pl = mplist_copy (pl);
1702 while (! MPLIST_TAIL_P (next))
1704 pl = mplist__conc (pl, MPLIST_PLIST (next));
1705 next = MPLIST_NEXT (next);
1708 len = mplist_length (pl);
1714 for (i = 0; i < len; i += column)
1717 mplist_add (plist, Mplist, p);
1718 M17N_OBJECT_UNREF (p);
1719 for (j = 0; j < column && i + j < len; j++)
1721 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
1722 p0 = MPLIST_NEXT (p0);
1726 M17N_OBJECT_UNREF (pl);
1730 if (plist == MPLIST_PLIST (args))
1731 M17N_OBJECT_REF (plist);
1732 if (MPLIST_MTEXT_P (plist))
1734 preedit_insert (ic, ic->cursor_pos, NULL,
1735 mtext_ref_char (MPLIST_MTEXT (plist), 0));
1740 mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
1741 preedit_insert (ic, ic->cursor_pos, mt, 0);
1742 len = mtext_nchars (mt);
1744 mtext_put_prop (ic->preedit,
1745 ic->cursor_pos - len, ic->cursor_pos,
1746 Mcandidate_list, plist);
1747 mtext_put_prop (ic->preedit,
1748 ic->cursor_pos - len, ic->cursor_pos,
1749 Mcandidate_index, (void *) 0);
1750 M17N_OBJECT_UNREF (plist);
1751 M17N_OBJECT_UNREF (args);
1753 else if (name == Mselect)
1756 int code, idx, gindex;
1757 int pos = ic->cursor_pos;
1761 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1764 if (MPLIST_SYMBOL_P (args))
1766 code = marker_code (MPLIST_SYMBOL (args));
1772 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1773 group = find_candidates_group (mtext_property_value (prop), idx,
1774 &start, &end, &gindex);
1776 if (code != '[' && code != ']')
1780 ? new_index (NULL, ic->candidate_index - start,
1781 end - start - 1, MPLIST_SYMBOL (args),
1783 : MPLIST_INTEGER (args)));
1786 find_candidates_group (mtext_property_value (prop), -1,
1791 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1796 int ingroup_index = idx - start;
1799 group = mtext_property_value (prop);
1800 len = mplist_length (group);
1813 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1814 idx += (MPLIST_MTEXT_P (group)
1815 ? mtext_nchars (MPLIST_MTEXT (group))
1816 : mplist_length (MPLIST_PLIST (group)));
1817 len = (MPLIST_MTEXT_P (group)
1818 ? mtext_nchars (MPLIST_MTEXT (group))
1819 : mplist_length (MPLIST_PLIST (group)));
1820 if (ingroup_index >= len)
1821 ingroup_index = len - 1;
1822 idx += ingroup_index;
1824 update_candidate (ic, prop, idx);
1826 else if (name == Mshow)
1827 ic->candidate_show = 1;
1828 else if (name == Mhide)
1829 ic->candidate_show = 0;
1830 else if (name == Mdelete)
1832 int len = mtext_nchars (ic->preedit);
1833 int to = (MPLIST_SYMBOL_P (args)
1834 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1836 : MPLIST_INTEGER (args));
1842 if (to < ic->cursor_pos)
1843 preedit_delete (ic, to, ic->cursor_pos);
1844 else if (to > ic->cursor_pos)
1845 preedit_delete (ic, ic->cursor_pos, to);
1847 else if (name == Mmove)
1849 int len = mtext_nchars (ic->preedit);
1851 = (MPLIST_SYMBOL_P (args)
1852 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1854 : MPLIST_INTEGER (args));
1860 if (pos != ic->cursor_pos)
1862 ic->cursor_pos = pos;
1863 ic->preedit_changed = 1;
1866 else if (name == Mmark)
1868 int code = marker_code (MPLIST_SYMBOL (args));
1871 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1872 (void *) ic->cursor_pos);
1874 else if (name == Mpushback)
1876 if (MPLIST_INTEGER_P (args))
1878 int num = MPLIST_INTEGER (args);
1881 ic_info->key_head -= num;
1883 ic_info->key_head = num;
1884 if (ic_info->key_head > ic_info->used)
1885 ic_info->key_head = ic_info->used;
1887 else if (MPLIST_MTEXT_P (args))
1889 MText *mt = MPLIST_MTEXT (args);
1890 int i, len = mtext_nchars (mt);
1893 ic_info->key_head--;
1894 for (i = 0; i < len; i++)
1896 key = one_char_symbol[MTEXT_DATA (mt)[i]];
1897 if (ic_info->key_head + i < ic_info->used)
1898 ic_info->keys[ic_info->key_head + i] = key;
1900 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1905 MPlist *plist = MPLIST_PLIST (args), *pl;
1909 ic_info->key_head--;
1911 MPLIST_DO (pl, plist)
1913 key = MPLIST_SYMBOL (pl);
1914 if (ic_info->key_head < ic_info->used)
1915 ic_info->keys[ic_info->key_head + i] = key;
1917 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1922 else if (name == Mcall)
1924 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1925 MIMExternalFunc func = NULL;
1926 MSymbol module, func_name;
1927 MPlist *func_args, *val;
1930 module = MPLIST_SYMBOL (args);
1931 args = MPLIST_NEXT (args);
1932 func_name = MPLIST_SYMBOL (args);
1934 if (im_info->externals)
1936 MIMExternalModule *external
1937 = (MIMExternalModule *) mplist_get (im_info->externals,
1940 func = (MIMExternalFunc) mplist_get (external->func_list,
1945 func_args = mplist ();
1946 mplist_add (func_args, Mt, ic);
1947 MPLIST_DO (args, MPLIST_NEXT (args))
1951 if (MPLIST_KEY (args) == Msymbol
1952 && MPLIST_KEY (args) != Mnil
1953 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1955 code = new_index (ic, ic->cursor_pos,
1956 mtext_nchars (ic->preedit),
1957 MPLIST_SYMBOL (args), ic->preedit);
1958 mplist_add (func_args, Minteger, (void *) code);
1961 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1963 val = (func) (func_args);
1964 M17N_OBJECT_UNREF (func_args);
1965 if (val && ! MPLIST_TAIL_P (val))
1966 ret = take_action_list (ic, val);
1967 M17N_OBJECT_UNREF (val);
1971 else if (name == Mshift)
1973 shift_state (ic, MPLIST_SYMBOL (args));
1975 else if (name == Mundo)
1977 int intarg = MPLIST_TAIL_P (args) ? 2 : MPLIST_INTEGER (args);
1980 mtext_reset (ic->preedit);
1981 mtext_reset (ic_info->preedit_saved);
1982 ic->cursor_pos = ic_info->state_pos = 0;
1983 ic_info->state_key_head = ic_info->key_head = 0;
1984 ic_info->used -= intarg;
1985 if (ic_info->used < 0)
1986 ic_info->used = 0, unhandled = 1;
1987 shift_state (ic, Mnil);
1992 else if (name == Mset || name == Madd || name == Msub
1993 || name == Mmul || name == Mdiv)
1995 MSymbol sym = MPLIST_SYMBOL (args);
2000 val1 = integer_value (ic, args, &value);
2001 args = MPLIST_NEXT (args);
2002 val2 = integer_value (ic, args, NULL);
2004 val1 = val2, op = "=";
2005 else if (name == Madd)
2006 val1 += val2, op = "+=";
2007 else if (name == Msub)
2008 val1 -= val2, op = "-=";
2009 else if (name == Mmul)
2010 val1 *= val2, op = "*=";
2012 val1 /= val2, op = "/=";
2013 mplist_set (value, Minteger, (void *) val1);
2014 MDEBUG_PRINT3 ("(%s %s %d)", MSYMBOL_NAME (sym), op, val1);
2016 else if (name == Mequal || name == Mless || name == Mgreater)
2019 MPlist *actions1, *actions2;
2022 val1 = integer_value (ic, args, NULL);
2023 args = MPLIST_NEXT (args);
2024 val2 = integer_value (ic, args, NULL);
2025 args = MPLIST_NEXT (args);
2026 actions1 = MPLIST_PLIST (args);
2027 args = MPLIST_NEXT (args);
2028 if (MPLIST_TAIL_P (args))
2031 actions2 = MPLIST_PLIST (args);
2032 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
2033 if (name == Mequal ? val1 == val2
2034 : name == Mless ? val1 < val2
2037 MDEBUG_PRINT ("ok");
2038 ret = take_action_list (ic, actions1);
2042 MDEBUG_PRINT ("no");
2044 ret = take_action_list (ic, actions2);
2049 else if (name == Mcommit)
2051 preedit_commit (ic);
2053 else if (name == Munhandle)
2055 preedit_commit (ic);
2061 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2065 && (actions = mplist_get (im_info->macros, name)))
2067 if (take_action_list (ic, actions) < 0)
2074 if (ic->candidate_list)
2076 M17N_OBJECT_UNREF (ic->candidate_list);
2077 ic->candidate_list = NULL;
2079 if (ic->cursor_pos > 0
2080 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
2083 ic->candidate_list = mtext_property_value (prop);
2084 M17N_OBJECT_REF (ic->candidate_list);
2086 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
2088 ic->candidate_from = mtext_property_start (prop);
2089 ic->candidate_to = mtext_property_end (prop);
2092 ic->candidates_changed |= (candidate_list != ic->candidate_list
2093 || candidate_index != ic->candidate_index
2094 || candidate_show != ic->candidate_show);
2099 /* Handle the input key KEY in the current state and map specified in
2100 the input context IC. If KEY is handled correctly, return 0.
2101 Otherwise, return -1. */
2104 handle_key (MInputContext *ic)
2106 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2107 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2108 MIMMap *map = ic_info->map;
2109 MIMMap *submap = NULL;
2110 MSymbol key = ic_info->keys[ic_info->key_head];
2113 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
2114 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
2120 submap = mplist_get (map->submaps, key);
2121 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
2122 submap = mplist_get (map->submaps, alias);
2127 MDEBUG_PRINT (" submap-found");
2128 mtext_cpy (ic->preedit, ic_info->preedit_saved);
2129 ic->preedit_changed = 1;
2130 ic->cursor_pos = ic_info->state_pos;
2131 ic_info->key_head++;
2132 ic_info->map = map = submap;
2133 if (map->map_actions)
2135 MDEBUG_PRINT (" map-actions:");
2136 if (take_action_list (ic, map->map_actions) < 0)
2138 MDEBUG_PRINT ("\n");
2142 else if (map->submaps)
2144 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
2146 MSymbol key = ic_info->keys[i];
2147 char *name = msymbol_name (key);
2149 if (! name[0] || ! name[1])
2150 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
2154 /* If this is the terminal map or we have shifted to another
2155 state, perform branch actions (if any). */
2156 if (! map->submaps || map != ic_info->map)
2158 if (map->branch_actions)
2160 MDEBUG_PRINT (" branch-actions:");
2161 if (take_action_list (ic, map->branch_actions) < 0)
2163 MDEBUG_PRINT ("\n");
2167 /* If MAP is still not the root map, shift to the current
2169 if (ic_info->map != ic_info->state->map)
2170 shift_state (ic, ic_info->state->name);
2175 /* MAP can not handle KEY. */
2177 /* If MAP is the root map of the initial state, it means that
2178 the current input method can not handle KEY. */
2179 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
2181 MDEBUG_PRINT (" unhandled\n");
2185 if (map != ic_info->state->map)
2187 /* If MAP is not the root map... */
2188 /* If MAP has branch actions, perform them. */
2189 if (map->branch_actions)
2191 MDEBUG_PRINT (" branch-actions:");
2192 if (take_action_list (ic, map->branch_actions) < 0)
2194 MDEBUG_PRINT ("\n");
2198 /* If MAP is still not the root map, shift to the current
2200 if (ic_info->map != ic_info->state->map)
2202 shift_state (ic, ic_info->state->name);
2204 /* If MAP has branch_actions, perform them. */
2205 if (ic_info->map->branch_actions)
2207 MDEBUG_PRINT (" brank-actions:");
2208 take_action_list (ic, ic_info->map->branch_actions);
2215 /* MAP is the root map, perform branch actions (if any) or
2216 shift to the initial state. */
2217 if (map->branch_actions)
2219 MDEBUG_PRINT (" branch-actions:");
2220 if (take_action_list (ic, map->branch_actions) < 0)
2222 MDEBUG_PRINT ("\n");
2227 shift_state (ic, Mnil);
2230 MDEBUG_PRINT ("\n");
2235 reset_ic (MInputContext *ic, MSymbol ignore)
2237 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2238 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2241 MDEBUG_PRINT ("\n [IM] reset\n");
2243 ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
2244 ic_info->prev_state = NULL;
2245 ic_info->map = ic_info->state->map;
2246 ic_info->state_key_head = ic_info->key_head;
2247 MLIST_RESET (ic_info);
2248 ic_info->key_unhandled = 0;
2250 if (mtext_nchars (ic->produced) > 0)
2251 mtext_reset (ic->produced);
2252 if (mtext_nchars (ic->preedit) > 0)
2256 mtext_reset (ic->preedit);
2257 MPLIST_DO (plist, ic_info->markers)
2258 MPLIST_VAL (plist) = 0;
2259 ic->preedit_changed = 1;
2261 if (ic->candidate_show)
2263 ic->candidate_show = 0;
2264 if (ic->candidate_list)
2266 M17N_OBJECT_UNREF (ic->candidate_list);
2267 ic->candidate_list = NULL;
2268 ic->candidates_changed = 1;
2271 mtext_reset (ic_info->preedit_saved);
2272 ic_info->state_pos = ic->cursor_pos = 0;
2274 status = ic_info->state->title ? ic_info->state->title : im_info->title;
2275 if (ic->status != status)
2277 ic->status = status;
2278 ic->status_changed = 1;
2283 open_im (MInputMethod *im)
2285 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil);
2288 MERROR (MERROR_IM, -1);
2295 close_im (MInputMethod *im)
2301 create_ic (MInputContext *ic)
2303 MInputMethod *im = ic->im;
2304 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
2305 MInputContextInfo *ic_info;
2309 ic_info = (MInputContextInfo *) ic->info;
2312 MSTRUCT_CALLOC (ic_info, MERROR_IM);
2315 MLIST_INIT1 (ic_info, keys, 8);
2316 ic_info->markers = mplist ();
2317 ic_info->vars = mplist ();
2318 plist = get_nested_list (im->language, im->name, Mnil, M_variable);
2319 MPLIST_DO (plist, plist)
2321 MSymbol var = MPLIST_SYMBOL (plist);
2324 plist = MPLIST_NEXT (plist);
2325 pl = MPLIST_PLIST (plist);
2326 pl = MPLIST_NEXT (pl); /* Skip description. */
2327 mplist_push (ic_info->vars, MPLIST_KEY (pl), MPLIST_VAL (pl));
2328 mplist_push (ic_info->vars, Msymbol, var);
2330 plist = resolve_variable (ic_info, Mcandidates_group_size);
2331 if (! MPLIST_INTEGER_P (plist))
2332 mplist_set (plist, Minteger, (void *) 10);
2333 plist = resolve_variable (ic_info, Mcandidates_charset);
2335 ic_info->preedit_saved = mtext ();
2336 if (im_info->externals)
2338 MPlist *func_args = mplist (), *plist;
2340 mplist_add (func_args, Mt, ic);
2341 MPLIST_DO (plist, im_info->externals)
2343 MIMExternalModule *external = MPLIST_VAL (plist);
2344 MIMExternalFunc func
2345 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
2350 M17N_OBJECT_UNREF (func_args);
2352 reset_ic (ic, Mnil);
2357 destroy_ic (MInputContext *ic)
2359 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2360 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2362 if (im_info->externals)
2364 MPlist *func_args = mplist (), *plist;
2366 mplist_add (func_args, Mt, ic);
2367 MPLIST_DO (plist, im_info->externals)
2369 MIMExternalModule *external = MPLIST_VAL (plist);
2370 MIMExternalFunc func
2371 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
2376 M17N_OBJECT_UNREF (func_args);
2378 MLIST_FREE1 (ic_info, keys);
2379 M17N_OBJECT_UNREF (ic_info->preedit_saved);
2380 M17N_OBJECT_UNREF (ic_info->markers);
2381 M17N_OBJECT_UNREF (ic_info->vars);
2386 /** Handle the input key KEY in the current state and map of IC->info.
2387 If KEY is handled but no text is produced, return 0, otherwise
2393 filter (MInputContext *ic, MSymbol key, void *arg)
2395 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2396 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2399 if (! ic_info->state)
2401 ic_info->key_unhandled = 1;
2404 mtext_reset (ic->produced);
2405 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
2406 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2407 ic_info->key_unhandled = 0;
2409 if (handle_key (ic) < 0)
2411 /* KEY was not handled. Delete it from the current key sequence. */
2412 if (ic_info->used > 0)
2414 memmove (ic_info->keys, ic_info->keys + 1,
2415 sizeof (int) * (ic_info->used - 1));
2418 /* This forces returning 1. */
2419 ic_info->key_unhandled = 1;
2425 reset_ic (ic, Mnil);
2426 ic_info->key_unhandled = 1;
2429 /* Break the loop if all keys were handled. */
2430 } while (ic_info->key_head < ic_info->used);
2432 /* If the current map is the root of the initial state, we should
2433 produce any preedit text in ic->produced. */
2434 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2435 && mtext_nchars (ic->preedit) > 0)
2436 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2438 if (mtext_nchars (ic->produced) > 0)
2440 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2443 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2444 Mlanguage, ic->im->language);
2447 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2451 /** Return 1 if the last event or key was not handled, otherwise
2454 There is no need of looking up because ic->produced should already
2455 contain the produced text (if any).
2460 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2462 mtext_cat (mt, ic->produced);
2463 mtext_reset (ic->produced);
2464 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2467 static MPlist *load_im_info_keys;
2470 load_partial_im_info (MSymbol language, MSymbol name,
2471 MSymbol extra, MSymbol key)
2476 if (language == Mnil || name == Mnil)
2477 MERROR (MERROR_IM, NULL);
2478 mdb = mdatabase_find (Minput_method, language, name, Mnil);
2480 MERROR (MERROR_IM, NULL);
2482 mplist_push (load_im_info_keys, key, Mt);
2483 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2484 mplist_pop (load_im_info_keys);
2489 static MInputMethodInfo *
2490 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2494 MInputMethodInfo *im_info = NULL;
2496 if (language == Mnil)
2497 MERROR (MERROR_IM, NULL);
2498 mdb = mdatabase_find (Minput_method, language, name, extra);
2500 MERROR (MERROR_IM, NULL);
2503 im_info_list = mplist ();
2504 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2506 if (mdatabase__check (mdb))
2508 plist = MPLIST_NEXT (plist);
2509 im_info = MPLIST_VAL (plist);
2513 free_im_info (MPLIST_VAL (plist));
2517 plist = mdatabase_load (mdb);
2519 MERROR (MERROR_IM, NULL);
2520 im_info = load_im_info (language, name, plist);
2521 M17N_OBJECT_UNREF (plist);
2523 MERROR (MERROR_IM, NULL);
2524 mplist_push (im_info_list, Mt, im_info);
2525 mplist_push (im_info_list, Mt, mdb);
2530 /* Input method command handler. */
2532 /* List of all (global and local) commands.
2533 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2534 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2535 Global commands are storead as (t (t COMMAND ...)) */
2537 /* Check if PLIST is a valid command key sequence.
2538 PLIST must be NULL or:
2539 [ symbol:KEY | integer:KEY ] ... */
2542 check_command_keyseq (MPlist *plist)
2546 MPLIST_DO (plist, plist)
2548 if (MPLIST_SYMBOL_P (plist))
2550 else if (MPLIST_INTEGER_P (plist))
2552 int n = MPLIST_INTEGER (plist);
2556 MPLIST_KEY (plist) = Msymbol;
2557 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2565 /* Check if PLIST has this form:
2566 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2568 If the form of PLIST matches, return 0, otherwise return -1. */
2571 check_command_list (MPlist *plist)
2573 MPLIST_DO (plist, plist)
2575 if (MPLIST_PLIST_P (plist))
2577 MPlist *pl = MPLIST_PLIST (plist);
2580 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2583 else if (! MPLIST_MTEXT_P (plist))
2591 /* Input method variable handler. */
2593 /* Check if PLIST has this form:
2594 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2597 If the form of PLIST matches, return 0, otherwise return -1. */
2600 check_variable_list (MPlist *plist)
2602 MSymbol type = MPLIST_KEY (plist);
2605 if (type != Minteger && type != Mtext && type != Msymbol)
2607 MPLIST_DO (plist, MPLIST_NEXT (plist))
2609 if (type == Minteger && MPLIST_PLIST_P (plist))
2611 MPLIST_DO (p, MPLIST_PLIST (plist))
2612 if (! MPLIST_INTEGER_P (p))
2615 else if (type != MPLIST_KEY (plist))
2621 /* Support functions for mdebug_dump_im. */
2624 dump_im_map (MPlist *map_list, int indent)
2627 MSymbol key = MPLIST_KEY (map_list);
2628 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2630 prefix = (char *) alloca (indent + 1);
2631 memset (prefix, 32, indent);
2632 prefix[indent] = '\0';
2634 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2635 if (map->map_actions)
2636 mdebug_dump_plist (map->map_actions, indent + 2);
2639 MPLIST_DO (map_list, map->submaps)
2641 fprintf (stderr, "\n%s ", prefix);
2642 dump_im_map (map_list, indent + 2);
2645 if (map->branch_actions)
2647 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2648 mdebug_dump_plist (map->branch_actions, indent + 4);
2649 fprintf (stderr, ")");
2651 fprintf (stderr, ")");
2656 dump_im_state (MIMState *state, int indent)
2661 prefix = (char *) alloca (indent + 1);
2662 memset (prefix, 32, indent);
2663 prefix[indent] = '\0';
2665 fprintf (stderr, "(%s", msymbol_name (state->name));
2666 if (state->map->submaps)
2668 MPLIST_DO (map_list, state->map->submaps)
2670 fprintf (stderr, "\n%s ", prefix);
2671 dump_im_map (map_list, indent + 2);
2674 fprintf (stderr, ")");
2683 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2684 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2685 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2686 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2687 char buf[6], buf2[256];
2691 Minput_method = msymbol ("input-method");
2692 Minput_driver = msymbol ("input-driver");
2693 Mtitle = msymbol ("title");
2694 Mmacro = msymbol ("macro");
2695 Mmodule = msymbol ("module");
2696 Mmap = msymbol ("map");
2697 Mstate = msymbol ("state");
2698 Minclude = msymbol ("include");
2699 Minsert = msymbol ("insert");
2700 M_candidates = msymbol (" candidates");
2701 Mdelete = msymbol ("delete");
2702 Mmove = msymbol ("move");
2703 Mmark = msymbol ("mark");
2704 Mpushback = msymbol ("pushback");
2705 Mundo = msymbol ("undo");
2706 Mcall = msymbol ("call");
2707 Mshift = msymbol ("shift");
2708 Mselect = msymbol ("select");
2709 Mshow = msymbol ("show");
2710 Mhide = msymbol ("hide");
2711 Mcommit = msymbol ("commit");
2712 Munhandle = msymbol ("unhandle");
2713 Mset = msymbol ("set");
2714 Madd = msymbol ("add");
2715 Msub = msymbol ("sub");
2716 Mmul = msymbol ("mul");
2717 Mdiv = msymbol ("div");
2718 Mequal = msymbol ("=");
2719 Mless = msymbol ("<");
2720 Mgreater = msymbol (">");
2722 Mcandidates_group_size = msymbol ("candidates-group-size");
2723 Mcandidates_charset = msymbol ("candidates-charset");
2725 Minput_preedit_start = msymbol ("input-preedit-start");
2726 Minput_preedit_done = msymbol ("input-preedit-done");
2727 Minput_preedit_draw = msymbol ("input-preedit-draw");
2728 Minput_status_start = msymbol ("input-status-start");
2729 Minput_status_done = msymbol ("input-status-done");
2730 Minput_status_draw = msymbol ("input-status-draw");
2731 Minput_candidates_start = msymbol ("input-candidates-start");
2732 Minput_candidates_done = msymbol ("input-candidates-done");
2733 Minput_candidates_draw = msymbol ("input-candidates-draw");
2734 Minput_set_spot = msymbol ("input-set-spot");
2735 Minput_focus_move = msymbol ("input-focus-move");
2736 Minput_focus_in = msymbol ("input-focus-in");
2737 Minput_focus_out = msymbol ("input-focus-out");
2738 Minput_toggle = msymbol ("input-toggle");
2739 Minput_reset = msymbol ("input-reset");
2741 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2742 Mcandidate_index = msymbol (" candidate-index");
2744 Minit = msymbol ("init");
2745 Mfini = msymbol ("fini");
2747 M_key_alias = msymbol (" key-alias");
2748 M_description = msymbol ("description");
2749 M_command = msymbol ("command");
2750 M_variable = msymbol ("variable");
2752 load_im_info_keys = mplist ();
2753 plist = mplist_add (load_im_info_keys, Mstate, Mnil);
2758 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2762 one_char_symbol[i] = msymbol (buf);
2765 alias = msymbol (key_names[i]);
2766 msymbol_put (one_char_symbol[i], M_key_alias, alias);
2769 alias = one_char_symbol[i];
2770 buf[2] += (i == 0) ? -32 : 32;
2771 msymbol_put (alias, M_key_alias, msymbol (buf));
2772 buf[2] -= (i == 0) ? -32 : 32;
2774 for (buf[2] = i; i < 127; i++, buf[2]++)
2775 one_char_symbol[i] = msymbol (buf + 2);
2776 one_char_symbol[i++] = msymbol ("Delete");
2782 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2784 one_char_symbol[i] = msymbol (buf);
2785 if (key_names[i - 128])
2787 strcpy (buf2 + 2, key_names[i - 128]);
2788 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2791 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2792 one_char_symbol[i] = msymbol (buf + 2);
2793 one_char_symbol[i] = msymbol ("M-Delete");
2795 command_list = variable_list = NULL;
2797 minput_default_driver.open_im = open_im;
2798 minput_default_driver.close_im = close_im;
2799 minput_default_driver.create_ic = create_ic;
2800 minput_default_driver.destroy_ic = destroy_ic;
2801 minput_default_driver.filter = filter;
2802 minput_default_driver.lookup = lookup;
2803 minput_default_driver.callback_list = mplist ();
2804 mplist_put (minput_default_driver.callback_list, Minput_reset,
2806 minput_driver = &minput_default_driver;
2815 M17N_OBJECT_UNREF (command_list);
2816 command_list = NULL;
2820 M17N_OBJECT_UNREF (variable_list);
2821 variable_list = NULL;
2824 if (minput_default_driver.callback_list)
2826 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2827 minput_default_driver.callback_list = NULL;
2829 if (minput_driver->callback_list)
2831 M17N_OBJECT_UNREF (minput_driver->callback_list);
2832 minput_driver->callback_list = NULL;
2837 while (! MPLIST_TAIL_P (im_info_list))
2840 mplist_pop (im_info_list);
2841 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
2842 /* Pop (t . im_info) */
2843 mplist_pop (im_info_list);
2845 M17N_OBJECT_UNREF (im_info_list);
2846 im_info_list = NULL;
2849 M17N_OBJECT_UNREF (load_im_info_keys);
2853 minput__callback (MInputContext *ic, MSymbol command)
2855 if (ic->im->driver.callback_list)
2857 MInputCallbackFunc func
2858 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2862 (func) (ic, command);
2867 minput__char_to_key (int c)
2869 if (c < 0 || c >= 0x100)
2872 return one_char_symbol[c];
2876 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2881 /*** @addtogroup m17nInputMethod */
2886 @name Variables: Predefined symbols for callback commands.
2888 These are the predefined symbols that are used as the @c COMMAND
2889 argument of callback functions of an input method driver (see
2890 #MInputDriver::callback_list ). */
2892 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2894 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2895 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2900 MSymbol Minput_preedit_start;
2901 MSymbol Minput_preedit_done;
2902 MSymbol Minput_preedit_draw;
2903 MSymbol Minput_status_start;
2904 MSymbol Minput_status_done;
2905 MSymbol Minput_status_draw;
2906 MSymbol Minput_candidates_start;
2907 MSymbol Minput_candidates_done;
2908 MSymbol Minput_candidates_draw;
2909 MSymbol Minput_set_spot;
2910 MSymbol Minput_toggle;
2911 MSymbol Minput_reset;
2917 @name Variables: Predefined symbols for special input events.
2919 These are the predefined symbols that are used as the @c KEY
2920 argument of minput_filter (). */
2925 MSymbol Minput_focus_out;
2926 MSymbol Minput_focus_in;
2927 MSymbol Minput_focus_move;
2934 @brief The default driver for internal input methods.
2936 The variable #minput_default_driver is the default driver for
2937 internal input methods.
2939 The member MInputDriver::open_im () searches the m17n database for
2940 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2941 $NAME\> and loads it.
2943 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2944 programmers responsibility to set it to a plist of proper callback
2945 functions. Otherwise, no feedback information (e.g. preedit text)
2946 can be shown to users.
2948 The macro M17N_INIT () sets the variable #minput_driver to the
2949 pointer to this driver so that all internal input methods use it.
2951 Therefore, unless @c minput_driver is set differently, the driver
2952 dependent arguments $ARG of the functions whose name begin with
2953 "minput_" are all ignored. */
2956 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2958 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2960 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2961 \< #Minput_method, $LANGUAGE, $NAME\>
2962 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2964 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2965 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2966 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2967 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2969 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2970 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2972 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2973 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2975 MInputDriver minput_default_driver;
2979 @brief The driver for internal input methods.
2981 The variable #minput_driver is a pointer to the input method
2982 driver that is used by internal input methods. The macro
2983 M17N_INIT () initializes it to a pointer to #minput_default_driver
2984 if <m17n<EM></EM>.h> is included. */
2986 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
2988 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
2989 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
2990 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
2991 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
2993 MInputDriver *minput_driver;
2995 MSymbol Minput_driver;
3000 @brief Open an input method.
3002 The minput_open_im () function opens an input method that matches
3003 language $LANGUAGE and name $NAME, and returns a pointer to the
3004 input method object newly allocated.
3006 This function at first decides an driver for the input method as
3009 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3010 #minput_driver is used.
3012 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
3013 driver pointed to by the property value is used to open the input
3014 method. If $NAME has no such property, @c NULL is returned.
3016 Then, the member MInputDriver::open_im () of the driver is
3019 $ARG is set in the member @c arg of the structure MInputMethod so
3020 that the driver can refer to it. */
3023 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3025 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3026 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3028 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3030 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3031 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3033 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3034 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3035 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3037 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3039 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3041 @latexonly \IPAlabel{minput_open} @endlatexonly
3046 minput_open_im (MSymbol language, MSymbol name, void *arg)
3049 MInputDriver *driver;
3051 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3052 msymbol_name (language), msymbol_name (name));
3054 driver = minput_driver;
3057 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3059 MERROR (MERROR_IM, NULL);
3062 MSTRUCT_CALLOC (im, MERROR_IM);
3063 im->language = language;
3066 im->driver = *driver;
3067 if ((*im->driver.open_im) (im) < 0)
3069 MDEBUG_PRINT (" failed\n");
3073 MDEBUG_PRINT (" ok\n");
3080 @brief Close an input method.
3082 The minput_close_im () function closes the input method $IM, which
3083 must have been created by minput_open_im (). */
3086 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3088 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3089 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3092 minput_close_im (MInputMethod *im)
3094 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3095 msymbol_name (im->name), msymbol_name (im->language));
3096 (*im->driver.close_im) (im);
3098 MDEBUG_PRINT (" done\n");
3104 @brief Create an input context.
3106 The minput_create_ic () function creates an input context object
3107 associated with input method $IM, and calls callback functions
3108 corresponding to #Minput_preedit_start, #Minput_status_start, and
3109 #Minput_status_draw in this order.
3113 If an input context is successfully created, minput_create_ic ()
3114 returns a pointer to it. Otherwise it returns @c NULL. */
3117 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3119 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3120 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3121 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3122 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3126 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3127 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3131 minput_create_ic (MInputMethod *im, void *arg)
3135 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3136 msymbol_name (im->name), msymbol_name (im->language));
3137 MSTRUCT_CALLOC (ic, MERROR_IM);
3140 ic->preedit = mtext ();
3141 ic->candidate_list = NULL;
3142 ic->produced = mtext ();
3143 ic->spot.x = ic->spot.y = 0;
3145 ic->plist = mplist ();
3146 if ((*im->driver.create_ic) (ic) < 0)
3148 MDEBUG_PRINT (" failed\n");
3149 M17N_OBJECT_UNREF (ic->preedit);
3150 M17N_OBJECT_UNREF (ic->produced);
3151 M17N_OBJECT_UNREF (ic->plist);
3156 if (im->driver.callback_list)
3158 minput__callback (ic, Minput_preedit_start);
3159 minput__callback (ic, Minput_status_start);
3160 minput__callback (ic, Minput_status_draw);
3163 MDEBUG_PRINT (" ok\n");
3170 @brief Destroy an input context.
3172 The minput_destroy_ic () function destroys the input context $IC,
3173 which must have been created by minput_create_ic (). It calls
3174 callback functions corresponding to #Minput_preedit_done,
3175 #Minput_status_done, and #Minput_candidates_done in this order. */
3178 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3180 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3181 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3182 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3183 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3184 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3188 minput_destroy_ic (MInputContext *ic)
3190 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3191 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3192 if (ic->im->driver.callback_list)
3194 minput__callback (ic, Minput_preedit_done);
3195 minput__callback (ic, Minput_status_done);
3196 minput__callback (ic, Minput_candidates_done);
3198 (*ic->im->driver.destroy_ic) (ic);
3199 M17N_OBJECT_UNREF (ic->preedit);
3200 M17N_OBJECT_UNREF (ic->produced);
3201 M17N_OBJECT_UNREF (ic->plist);
3202 MDEBUG_PRINT (" done\n");
3209 @brief Filter an input key.
3211 The minput_filter () function filters input key $KEY according to
3212 input context $IC, and calls callback functions corresponding to
3213 #Minput_preedit_draw, #Minput_status_draw, and
3214 #Minput_candidates_draw if the preedit text, the status, and the
3215 current candidate are changed respectively.
3217 To make the input method commit the current preedit text (if any)
3218 and shift to the initial state, call this function with #Mnil as
3221 To inform the input method about the focus-out event, call this
3222 function with #Minput_focus_out as $KEY.
3224 To inform the input method about the focus-in event, call this
3225 function with #Minput_focus_in as $KEY.
3227 To inform the input method about the focus-move event (i.e. input
3228 spot change within the same input context), call this function
3229 with #Minput_focus_move as $KEY.
3232 If $KEY is filtered out, this function returns 1. In that case,
3233 the caller should discard the key. Otherwise, it returns 0, and
3234 the caller should handle the key, for instance, by calling the
3235 function minput_lookup () with the same key. */
3238 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3240 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3241 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3242 #Minput_preedit_draw, #Minput_status_draw,
3243 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3246 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3247 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3248 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3249 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3251 @latexonly \IPAlabel{minput_filter} @endlatexonly
3255 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3262 ret = (*ic->im->driver.filter) (ic, key, arg);
3264 if (ic->im->driver.callback_list)
3266 if (ic->preedit_changed)
3267 minput__callback (ic, Minput_preedit_draw);
3268 if (ic->status_changed)
3269 minput__callback (ic, Minput_status_draw);
3270 if (ic->candidates_changed)
3271 minput__callback (ic, Minput_candidates_draw);
3280 @brief Look up a text produced in the input context.
3282 The minput_lookup () function looks up a text in the input context
3283 $IC. $KEY must be the same one provided to the previous call of
3286 If a text was produced by the input method, it is concatenated
3289 This function calls #MInputDriver::lookup .
3292 If $KEY was correctly handled by the input method, this function
3293 returns 0. Otherwise, returns -1, even in that case, some text
3294 may be produced in $MT. */
3297 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3299 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3300 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3302 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3305 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3308 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3309 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3310 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3312 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3315 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3317 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3322 @brief Set the spot of the input context.
3324 The minput_set_spot () function set the spot of input context $IC
3325 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3326 The semantics of these values depend on the input method driver.
3328 For instance, a driver designed to work in a CUI environment may
3329 use $X and $Y as column and row numbers, and ignore $ASCENT and
3330 $DESCENT . A driver designed to work in a window system may
3331 interpret $X and $Y as pixel offsets relative to the origin of the
3332 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3333 descent pixels of the line at ($X . $Y ).
3335 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3337 $MT and $POS is the M-text and the character position at the spot.
3338 $MT may be @c NULL, in which case, the input method cannot get
3339 information about the text around the spot. */
3342 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3344 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3345 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3346 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3348 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3349 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3350 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3351 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3352 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3353 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3355 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3357 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3358 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3362 minput_set_spot (MInputContext *ic, int x, int y,
3363 int ascent, int descent, int fontsize,
3368 ic->spot.ascent = ascent;
3369 ic->spot.descent = descent;
3370 ic->spot.fontsize = fontsize;
3373 if (ic->im->driver.callback_list)
3374 minput__callback (ic, Minput_set_spot);
3379 @brief Toggle input method.
3381 The minput_toggle () function toggles the input method associated
3382 with input context $IC. */
3384 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3386 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3387 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3391 minput_toggle (MInputContext *ic)
3393 if (ic->im->driver.callback_list)
3394 minput__callback (ic, Minput_toggle);
3395 ic->active = ! ic->active;
3399 @brief Reset an input context.
3401 The minput_reset_ic () function resets input context $IC by
3402 calling a callback function corresponding to #Minput_reset. It
3403 resets the status of $IC to the one of just after created. As the
3404 current preedit text is deleted without commitment, if necessary,
3405 call minput_filter () with the arg @r key #Mnil to force the input
3406 method to commit the preedit in advance. */
3409 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3411 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3412 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3413 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3414 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3415 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3416 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3419 minput_reset_ic (MInputContext *ic)
3421 if (ic->im->driver.callback_list)
3422 minput__callback (ic, Minput_reset);
3426 @brief Get description text of an input method.
3428 The minput_get_description () function returns an M-text that
3429 describes the input method specified by $LANGUAGE and $NAME.
3432 If the specified input method has a description text, a pointer to
3433 #MText is returned. A caller have to free it by m17n_object_unref ().
3434 If the input method does not have a description text, @c NULL is
3437 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3439 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3440 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3442 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3443 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3444 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3445 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3448 minput_get_description (MSymbol language, MSymbol name)
3450 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3456 pl = MPLIST_PLIST (plist);
3457 pl = MPLIST_NEXT (pl);
3458 if (MPLIST_MTEXT_P (pl))
3460 mt = MPLIST_MTEXT (pl);
3461 M17N_OBJECT_REF (mt);
3463 M17N_OBJECT_UNREF (plist);
3468 @brief Get information about input method commands.
3470 The minput_get_commands () function returns information about
3471 input method commands of the input method specified by $LANGUAGE
3472 and $NAME. An input method command is a pseudo key event to which
3473 one or more actual input key sequences are assigned.
3475 There are two kinds of commands, global and local. Global
3476 commands are used by multiple input methods for the same purpose,
3477 and have global key assignments. Local commands are used only in
3478 a specific input method, and have only local key assignments.
3480 Each input method may locally change key assignments for global
3481 commands. A global key assignment for a global command are
3482 effective only when the current input method does not have local
3483 key assignments for that command.
3485 If $NAME is #Mnil, information about global commands is returned.
3486 In this case $LANGUAGE is ignored.
3488 If $NAME is not #Mnil, information about those commands that have
3489 local key assignments in the input method specified by $LANGUAGE
3490 and $NAME is returned.
3493 If no input method commands are found, this function returns @c NULL.
3495 Otherwise, a pointer to a plist is returned. The key of each
3496 element in the plist is a symbol representing a command, and the
3497 value is a plist of the form COMMAND-INFO described below.
3499 The first element of COMMAND-INFO has the key #Mtext, and the
3500 value is an M-text describing the command.
3502 If there are no more elements, that means no key sequences are
3503 assigned to the command. Otherwise, each of the remaining
3504 elements has the key #Mplist, and the value is a plist whose keys are
3505 #Msymbol and values are symbols representing input keys, which are
3506 currently assigned to the command.
3508 As the returned plist is kept in the library, the caller must not
3509 modify nor free it. */
3511 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3513 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3514 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3515 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3516 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3518 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3519 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3520 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3521 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3523 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3524 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3525 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3528 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3529 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3531 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3532 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3536 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3538 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3539 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3540 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3542 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3543 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3544 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3547 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3548 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3549 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3550 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3551 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3553 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3554 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3557 minput_get_commands (MSymbol language, MSymbol name)
3559 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
3561 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3565 @brief Assign a key sequence to an input method command.
3567 The minput_assign_command_keys () function assigns input key
3568 sequence $KEYSEQ to input method command $COMMAND for the input
3569 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3570 key sequence is assigned globally no matter what $LANGUAGE is.
3571 Otherwise the key sequence is assigned locally.
3573 Each element of $KEYSEQ must have the key $Msymbol and the value
3574 must be a symbol representing an input key.
3576 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3577 globally or locally.
3579 This assignment gets effective in a newly opened input method.
3582 If the operation was successful, 0 is returned. Otherwise -1 is
3583 returned, and #merror_code is set to #MERROR_IM. */
3585 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3587 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
3588 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
3589 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
3590 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
3591 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3593 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
3594 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3596 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
3597 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3599 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
3602 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3603 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3606 minput_assign_command_keys (MSymbol language, MSymbol name,
3607 MSymbol command, MPlist *keyseq)
3609 MPlist *plist, *pl, *p;
3611 if (check_command_keyseq (keyseq) < 0
3612 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
3613 MERROR (MERROR_IM, -1);
3614 pl = mplist_get (plist, command);
3617 pl = MPLIST_NEXT (pl);
3619 while ((p = mplist_pop (pl)))
3620 M17N_OBJECT_UNREF (p);
3623 keyseq = mplist_copy (keyseq);
3624 mplist_push (pl, Mplist, keyseq);
3625 M17N_OBJECT_UNREF (keyseq);
3631 MERROR (MERROR_IM, -1);
3634 /* Get global commands. */
3635 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
3636 pl = mplist_get (pl, command);
3638 MERROR (MERROR_IM, -1);
3640 mplist_add (p, Mtext, mplist_value (pl));
3641 keyseq = mplist_copy (keyseq);
3642 mplist_add (p, Mplist, keyseq);
3643 M17N_OBJECT_UNREF (keyseq);
3644 mplist_push (plist, command, p);
3650 @brief Get a list of variables of an input method.
3652 The minput_get_variables () function returns a plist (#MPlist) of
3653 variables used to control the behavior of the input method
3654 specified by $LANGUAGE and $NAME. The key of an element of the
3655 plist is a symbol representing a variable, and the value is a
3656 plist of the form VAR-INFO (described below) that carries the
3657 information about the variable.
3659 The first element of VAR-INFO has the key #Mtext or #Msymbol. If
3660 the key is #Mtext, the value is an M-text describing the variable.
3661 If the key is #Msymbol, that value is #Mnil which means the
3662 variable has no description text.
3664 The second element of VAR-INFO is for the value of the variable.
3665 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3666 integer, a symbol, or an M-text, respectively. The variable is
3667 set to this value when an input context is created for the input
3670 If there are no more elements, the variable can take any value
3671 that matches with the above type. Otherwise, the remaining
3672 elements of VAR-INFO are to specify valid values of the variable.
3674 If the type of the variable is integer, the following elements
3675 have the key #Minteger or #Mplist. If it is #Minteger, the value
3676 is a valid integer value. If it is #Mplist, the value is a plist
3677 of two of elements. Both of them have the key #Minteger, and
3678 values are the minimum and maximum bounds of the valid value
3681 If the type of the variable is symbol or M-text, the following
3682 elements of the plist have the key #Msymbol or #Mtext,
3683 respectively, and the value must be a valid one.
3685 For instance, suppose an input method has the variables:
3687 @li name:intvar, description:"value is an integer",
3688 initial value:0, value-range:0..3,10,20
3690 @li name:symvar, description:"value is a symbol",
3691 initial value:nil, value-range:a, b, c, nil
3693 @li name:txtvar, description:"value is an M-text",
3694 initial value:empty text, no value-range (i.e. any text)
3696 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3697 a value, and '(...)' means a plist):
3700 plist:(intvar:(mtext:"value is an integer"
3702 plist:(integer:0 integer:3)
3705 symvar:(mtext:"value is a symbol"
3711 txtvar:(mtext:"value is an M-text"
3716 If the input method uses any variables, a pointer to #MPlist is
3717 returned. As the plist is kept in the library, a caller must not
3718 modify nor free it. If the input method does not use any
3719 variable, @c NULL is returned. */
3721 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3723 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3724 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3725 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3726 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3727 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3729 VAR-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼¤¬
3730 #Mtext ¤Ê¤é¡¢ÃͤϤ½¤ÎÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬ #Msymbol
3731 ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤ÎÊÑ¿ô¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê¤¤¤³¤È¤Ë¤Ê¤ë¡£
3733 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3734 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3735 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3737 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3738 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3740 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3741 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3742 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3743 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3745 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3746 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3748 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3750 @li name:intvar, ÀâÌÀ:"value is an integer",
3751 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3753 @li name:symvar, ÀâÌÀ:"value is a symbol",
3754 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3756 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3757 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3759 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3760 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3763 plist:(intvar:(mtext:"value is an integer"
3765 plist:(integer:0 integer:3)
3768 symvar:(mtext:"value is a symbol"
3774 txtvar:(mtext:"value is an M-text"
3779 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3780 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3781 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3784 minput_get_variables (MSymbol language, MSymbol name)
3786 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
3788 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3792 @brief Set the initial value of an input method variable.
3794 The minput_set_variable () function sets the initial value of
3795 input method variable $VARIABLE to $VALUE for the input method
3796 specified by $LANGUAGE and $NAME.
3798 By default, the initial value is 0.
3800 This setting gets effective in a newly opened input method.
3803 If the operation was successful, 0 is returned. Otherwise -1 is
3804 returned, and #merror_code is set to #MERROR_IM. */
3806 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3808 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3809 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3810 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3812 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3814 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3817 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3818 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3821 minput_set_variable (MSymbol language, MSymbol name,
3822 MSymbol variable, void *value)
3824 MPlist *plist, *val_element, *range_element;
3827 if (language == Mnil || name == Mnil)
3828 MERROR (MERROR_IM, -1);
3829 plist = get_nested_list (language, name, Mnil, M_variable);
3831 MERROR (MERROR_IM, -1);
3832 plist = (MPlist *) mplist_get (plist, variable);
3834 MERROR (MERROR_IM, -1);
3835 val_element = MPLIST_NEXT (plist);
3836 type = MPLIST_KEY (val_element);
3837 range_element = MPLIST_NEXT (val_element);
3839 if (! MPLIST_TAIL_P (range_element))
3841 if (type == Minteger)
3843 int val = (int) value, this_val;
3845 MPLIST_DO (plist, range_element)
3847 this_val = (int) MPLIST_VAL (plist);
3848 if (MPLIST_PLIST_P (plist))
3850 int min_bound, max_bound;
3851 MPlist *pl = MPLIST_PLIST (plist);
3853 min_bound = (int) MPLIST_VAL (pl);
3854 pl = MPLIST_NEXT (pl);
3855 max_bound = (int) MPLIST_VAL (pl);
3856 if (val >= min_bound && val <= max_bound)
3859 else if (val == this_val)
3862 if (MPLIST_TAIL_P (plist))
3863 MERROR (MERROR_IM, -1);
3865 else if (type == Msymbol)
3867 MPLIST_DO (plist, range_element)
3868 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3870 if (MPLIST_TAIL_P (plist))
3871 MERROR (MERROR_IM, -1);
3873 else /* type == Mtext */
3875 MPLIST_DO (plist, range_element)
3876 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3878 if (MPLIST_TAIL_P (plist))
3879 MERROR (MERROR_IM, -1);
3880 M17N_OBJECT_REF (value);
3884 mplist_set (val_element, type, value);
3890 /*** @addtogroup m17nDebug */
3896 @brief Dump an input method.
3898 The mdebug_dump_im () function prints the input method $IM in a
3899 human readable way to the stderr. $INDENT specifies how many
3900 columns to indent the lines but the first one.
3903 This function returns $IM. */
3905 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3907 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3908 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3911 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3914 mdebug_dump_im (MInputMethod *im, int indent)
3916 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3919 prefix = (char *) alloca (indent + 1);
3920 memset (prefix, 32, indent);
3921 prefix[indent] = '\0';
3923 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3924 msymbol_name (im->name));
3925 mdebug_dump_mtext (im_info->title, 0, 0);
3926 if (im->name != Mnil)
3930 MPLIST_DO (state, im_info->states)
3932 fprintf (stderr, "\n%s ", prefix);
3933 dump_im_state (MPLIST_VAL (state), indent + 2);
3936 fprintf (stderr, ")");