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] == ']'
448 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
452 MPLIST_DO (p, ic_info->vars)
454 if (MPLIST_SYMBOL (p) == var)
458 if (MPLIST_TAIL_P (p))
461 mplist_push (p, Minteger, (void *) 0);
462 mplist_push (p, Msymbol, var);
464 return (MPLIST_NEXT (p));
469 integer_value (MInputContext *ic, MPlist *arg, MPlist **value)
471 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
473 MText *preedit = ic->preedit;
474 int len = mtext_nchars (preedit);
478 if (MPLIST_INTEGER_P (arg))
479 return MPLIST_INTEGER (arg);
480 code = marker_code (MPLIST_SYMBOL (arg));
483 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
487 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
490 return ic_info->key_head;
491 if (code >= '0' && code <= '9')
493 else if (code == '=')
494 code = ic->cursor_pos;
495 else if (code == '-' || code == '[')
496 code = ic->cursor_pos - 1;
497 else if (code == '+' || code == ']')
498 code = ic->cursor_pos + 1;
499 else if (code == '<')
501 else if (code == '>')
503 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
507 /* Parse PLIST as an action list. PLIST should have this form:
508 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
509 Return 0 if successfully parsed, otherwise return -1. */
512 parse_action_list (MPlist *plist, MPlist *macros)
514 MPLIST_DO (plist, plist)
516 if (MPLIST_MTEXT_P (plist))
518 /* This is a short form of (insert MTEXT). */
519 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
520 MERROR (MERROR_IM, -1); */
522 else if (MPLIST_PLIST_P (plist)
523 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
524 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
528 /* This is a short form of (insert (GROUPS *)). */
529 MPLIST_DO (pl, MPLIST_PLIST (plist))
531 if (MPLIST_PLIST_P (pl))
535 MPLIST_DO (elt, MPLIST_PLIST (pl))
536 if (! MPLIST_MTEXT_P (elt)
537 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
538 MERROR (MERROR_IM, -1);
542 if (! MPLIST_MTEXT_P (pl)
543 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
544 MERROR (MERROR_IM, -1);
548 else if (MPLIST_INTEGER_P (plist))
550 int c = MPLIST_INTEGER (plist);
552 if (c < 0 || c > MCHAR_MAX)
553 MERROR (MERROR_IM, -1);
555 else if (MPLIST_PLIST_P (plist)
556 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
558 MPlist *pl = MPLIST_PLIST (plist);
559 MSymbol action_name = MPLIST_SYMBOL (pl);
561 pl = MPLIST_NEXT (pl);
563 if (action_name == Minsert)
565 if (MPLIST_MTEXT_P (pl))
567 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
568 MERROR (MERROR_IM, -1);
570 else if (MPLIST_PLIST_P (pl))
574 if (MPLIST_PLIST_P (pl))
578 MPLIST_DO (elt, MPLIST_PLIST (pl))
579 if (! MPLIST_MTEXT_P (elt)
580 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
581 MERROR (MERROR_IM, -1);
585 if (! MPLIST_MTEXT_P (pl)
586 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
587 MERROR (MERROR_IM, -1);
591 else if (! MPLIST_SYMBOL_P (pl))
592 MERROR (MERROR_IM, -1);
594 else if (action_name == Mselect
595 || action_name == Mdelete
596 || action_name == Mmove)
598 if (! MPLIST_SYMBOL_P (pl)
599 && ! MPLIST_INTEGER_P (pl))
600 MERROR (MERROR_IM, -1);
602 else if (action_name == Mmark
603 || action_name == Mcall
604 || action_name == Mshift)
606 if (! MPLIST_SYMBOL_P (pl))
607 MERROR (MERROR_IM, -1);
609 else if (action_name == Mundo)
611 if (! MPLIST_TAIL_P (pl))
613 if (! MPLIST_SYMBOL_P (pl)
614 && (! MPLIST_INTEGER_P (pl)
615 || MPLIST_INTEGER (pl) <= 0))
616 MERROR (MERROR_IM, -1);
619 else if (action_name == Mpushback)
621 if (MPLIST_MTEXT_P (pl))
623 MText *mt = MPLIST_MTEXT (pl);
625 if (mtext_nchars (mt) != mtext_nbytes (mt))
626 MERROR (MERROR_IM, -1);
628 else if (MPLIST_PLIST_P (pl))
632 MPLIST_DO (p, MPLIST_PLIST (pl))
633 if (! MPLIST_SYMBOL_P (p))
634 MERROR (MERROR_IM, -1);
636 else if (! MPLIST_INTEGER_P (pl))
637 MERROR (MERROR_IM, -1);
639 else if (action_name == Mset || action_name == Madd
640 || action_name == Msub || action_name == Mmul
641 || action_name == Mdiv)
643 if (! (MPLIST_SYMBOL_P (pl)
644 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
645 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
646 MERROR (MERROR_IM, -1);
648 else if (action_name == Mequal || action_name == Mless
649 || action_name == Mgreater)
651 if (! ((MPLIST_INTEGER_P (pl) || MPLIST_SYMBOL_P (pl))
652 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
653 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
654 MERROR (MERROR_IM, -1);
655 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
656 if (! MPLIST_PLIST_P (pl))
657 MERROR (MERROR_IM, -1);
658 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
659 MERROR (MERROR_IM, -1);
660 pl = MPLIST_NEXT (pl);
661 if (MPLIST_PLIST_P (pl)
662 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
663 MERROR (MERROR_IM, -1);
665 else if (action_name == Mshow || action_name == Mhide
666 || action_name == Mcommit || action_name == Munhandle)
668 else if (! macros || ! mplist_get (macros, action_name))
669 MERROR (MERROR_IM, -1);
672 MERROR (MERROR_IM, -1);
679 resolve_command (MSymbol language, MSymbol name, MSymbol command)
681 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
684 || ! (plist = mplist_get (plist, command)))
686 plist = MPLIST_NEXT (plist);
687 if (! MPLIST_PLIST_P (plist))
694 /* Load a translation into MAP from PLIST.
696 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
699 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
700 MPlist *branch_actions, MPlist *macros)
705 if (MPLIST_MTEXT_P (keylist))
707 MText *mt = MPLIST_MTEXT (keylist);
709 len = mtext_nchars (mt);
710 if (len == 0 || len != mtext_nbytes (mt))
711 MERROR (MERROR_IM, -1);
712 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
713 for (i = 0; i < len; i++)
714 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
716 else if (MPLIST_PLIST_P (keylist))
718 MPlist *elt = MPLIST_PLIST (keylist);
720 len = MPLIST_LENGTH (elt);
722 MERROR (MERROR_IM, -1);
723 keyseq = (MSymbol *) alloca (sizeof (int) * len);
724 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
726 if (MPLIST_INTEGER_P (elt))
728 int c = MPLIST_INTEGER (elt);
730 if (c < 0 || c >= 0x100)
731 MERROR (MERROR_IM, -1);
732 keyseq[i] = one_char_symbol[c];
734 else if (MPLIST_SYMBOL_P (elt))
735 keyseq[i] = MPLIST_SYMBOL (elt);
737 MERROR (MERROR_IM, -1);
741 MERROR (MERROR_IM, -1);
743 for (i = 0; i < len; i++)
745 MIMMap *deeper = NULL;
748 deeper = mplist_get (map->submaps, keyseq[i]);
750 map->submaps = mplist ();
753 /* Fixme: It is better to make all deeper maps at once. */
754 MSTRUCT_CALLOC (deeper, MERROR_IM);
755 mplist_put (map->submaps, keyseq[i], deeper);
760 /* We reach a terminal map. */
762 || map->branch_actions)
763 /* This map is already defined. We avoid overriding it. */
766 if (! MPLIST_TAIL_P (map_actions))
768 if (parse_action_list (map_actions, macros) < 0)
769 MERROR (MERROR_IM, -1);
770 map->map_actions = map_actions;
774 map->branch_actions = branch_actions;
775 M17N_OBJECT_REF (branch_actions);
781 /* Load a branch from PLIST into MAP. PLIST has this form:
782 PLIST ::= ( MAP-NAME BRANCH-ACTION * )
783 MAPS is a plist of raw maps.
784 STATE is the current state. */
787 load_branch (MPlist *plist, MPlist *maps, MIMMap *map,
788 MSymbol language, MSymbol name, MPlist *macros)
791 MPlist *branch_actions;
793 if (! MPLIST_SYMBOL_P (plist))
794 MERROR (MERROR_IM, -1);
795 map_name = MPLIST_SYMBOL (plist);
796 plist = MPLIST_NEXT (plist);
797 if (MPLIST_TAIL_P (plist))
798 branch_actions = NULL;
799 else if (parse_action_list (plist, macros) < 0)
800 MERROR (MERROR_IM, -1);
802 branch_actions = plist;
803 if (map_name == Mnil)
805 map->branch_actions = branch_actions;
807 M17N_OBJECT_REF (branch_actions);
809 else if (map_name == Mt)
811 map->map_actions = branch_actions;
813 M17N_OBJECT_REF (branch_actions);
817 plist = (MPlist *) mplist_get (maps, map_name);
818 if (! plist || ! MPLIST_PLIST_P (plist))
819 MERROR (MERROR_IM, -1);
820 MPLIST_DO (plist, plist)
822 MPlist *keylist, *map_actions;
824 if (! MPLIST_PLIST_P (plist))
825 MERROR (MERROR_IM, -1);
826 keylist = MPLIST_PLIST (plist);
827 map_actions = MPLIST_NEXT (keylist);
828 if (MPLIST_SYMBOL_P (keylist))
830 MSymbol command = MPLIST_SYMBOL (keylist);
831 MPlist *pl = resolve_command (language, name, command);
836 if (load_translation (map, pl, map_actions, branch_actions,
838 MERROR (MERROR_IM, -1);
841 if (load_translation (map, keylist, map_actions, branch_actions,
843 MERROR (MERROR_IM, -1);
850 /* Load a macro from PLIST into MACROS.
852 PLIST ::= ( MACRO-NAME ACTION * )
853 MACROS is a plist of macro names vs action list. */
855 load_macros (MPlist *plist, MPlist *macros)
859 if (! MPLIST_SYMBOL_P (plist))
860 MERROR (MERROR_IM, -1);
861 name = MPLIST_SYMBOL (plist);
862 plist = MPLIST_NEXT (plist);
863 if (MPLIST_TAIL_P (plist)
864 || parse_action_list (plist, macros) < 0)
865 MERROR (MERROR_IM, -1);
866 mplist_put (macros, name, plist);
867 M17N_OBJECT_REF (plist);
871 /* Load an external module from PLIST into EXTERNALS.
873 PLIST ::= ( MODULE-NAME FUNCTION * )
874 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
877 load_external_module (MPlist *plist, MPlist *externals)
882 MIMExternalModule *external;
886 if (MPLIST_MTEXT_P (plist))
887 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
888 else if (MPLIST_SYMBOL_P (plist))
889 module = MPLIST_SYMBOL (plist);
890 module_file = alloca (strlen (MSYMBOL_NAME (module))
891 + strlen (DLOPEN_SHLIB_EXT) + 1);
892 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
894 handle = dlopen (module_file, RTLD_NOW);
897 fprintf (stderr, "%s\n", dlerror ());
898 MERROR (MERROR_IM, -1);
900 func_list = mplist ();
901 MPLIST_DO (plist, MPLIST_NEXT (plist))
903 if (! MPLIST_SYMBOL_P (plist))
904 MERROR_GOTO (MERROR_IM, err_label);
905 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
907 MERROR_GOTO (MERROR_IM, err_label);
908 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
911 MSTRUCT_MALLOC (external, MERROR_IM);
912 external->handle = handle;
913 external->func_list = func_list;
914 mplist_add (externals, module, external);
919 M17N_OBJECT_UNREF (func_list);
924 free_map (MIMMap *map, int top)
929 M17N_OBJECT_UNREF (map->map_actions);
932 MPLIST_DO (plist, map->submaps)
933 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
934 M17N_OBJECT_UNREF (map->submaps);
936 M17N_OBJECT_UNREF (map->branch_actions);
941 free_state (void *object)
943 MIMState *state = object;
946 M17N_OBJECT_UNREF (state->title);
948 free_map (state->map, 1);
952 /** Load a state from PLIST into a newly allocated state object.
954 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
955 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
956 MAPS is a plist of defined maps.
957 Return the state object. */
960 load_state (MPlist *plist, MPlist *maps, MSymbol language, MSymbol name,
965 if (! MPLIST_SYMBOL_P (plist))
966 MERROR (MERROR_IM, NULL);
967 M17N_OBJECT (state, free_state, MERROR_IM);
968 state->name = MPLIST_SYMBOL (plist);
969 plist = MPLIST_NEXT (plist);
970 if (MPLIST_MTEXT_P (plist))
972 state->title = MPLIST_MTEXT (plist);
973 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
974 Mlanguage, language);
975 M17N_OBJECT_REF (state->title);
976 plist = MPLIST_NEXT (plist);
978 MSTRUCT_CALLOC (state->map, MERROR_IM);
979 MPLIST_DO (plist, plist)
980 if (! MPLIST_PLIST_P (plist)
981 || load_branch (MPLIST_PLIST (plist), maps, state->map, language, name,
983 MERROR (MERROR_IM, NULL);
988 static MPlist *im_info_list;
991 free_im_info (MInputMethodInfo *im_info)
996 M17N_OBJECT_UNREF (im_info->title);
999 MPLIST_DO (plist, im_info->states)
1001 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1003 M17N_OBJECT_UNREF (state);
1005 M17N_OBJECT_UNREF (im_info->states);
1008 if (im_info->macros)
1010 MPLIST_DO (plist, im_info->macros)
1011 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1012 M17N_OBJECT_UNREF (im_info->macros);
1015 if (im_info->externals)
1017 MPLIST_DO (plist, im_info->externals)
1019 MIMExternalModule *external = MPLIST_VAL (plist);
1021 dlclose (external->handle);
1022 M17N_OBJECT_UNREF (external->func_list);
1024 MPLIST_KEY (plist) = Mt;
1026 M17N_OBJECT_UNREF (im_info->externals);
1030 MPLIST_DO (plist, im_info->maps)
1032 MPlist *p = MPLIST_PLIST (plist);
1034 M17N_OBJECT_UNREF (p);
1036 M17N_OBJECT_UNREF (im_info->maps);
1042 static MInputMethodInfo *get_im_info (MSymbol language, MSymbol name,
1045 static MInputMethodInfo *
1046 get_im_info_by_tags (MPlist *plist)
1051 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1052 i++, plist = MPLIST_NEXT (plist))
1053 tag[i] = MPLIST_SYMBOL (plist);
1058 return get_im_info (tag[0], tag[1], tag[2]);
1061 /* Load an input method from PLIST into IM_INTO, and return it. */
1063 static MInputMethodInfo *
1064 load_im_info (MSymbol language, MSymbol name, MPlist *plist)
1066 MInputMethodInfo *im_info;
1067 MText *title = NULL;
1068 MPlist *maps = NULL;
1069 MPlist *states = NULL;
1070 MPlist *externals = NULL;
1071 MPlist *macros = NULL;
1074 MSTRUCT_CALLOC (im_info, MERROR_IM);
1076 while (MPLIST_PLIST_P (plist))
1078 elt = MPLIST_PLIST (plist);
1079 if (! MPLIST_SYMBOL_P (elt))
1080 MERROR_GOTO (MERROR_IM, err);
1081 if (MPLIST_SYMBOL (elt) == Mtitle)
1083 elt = MPLIST_NEXT (elt);
1084 if (! MPLIST_MTEXT_P (elt))
1085 MERROR_GOTO (MERROR_IM, err);
1086 im_info->title = title = MPLIST_MTEXT (elt);
1087 M17N_OBJECT_REF (title);
1089 else if (MPLIST_SYMBOL (elt) == Mmap)
1091 MPlist *pl = mplist__from_alist (MPLIST_NEXT (elt));
1094 MERROR_GOTO (MERROR_IM, err);
1096 im_info->maps = maps = pl;
1098 maps = mplist__conc (maps, pl);
1100 else if (MPLIST_SYMBOL (elt) == Mmacro)
1103 im_info->macros = macros = mplist ();
1104 MPLIST_DO (elt, MPLIST_NEXT (elt))
1106 if (! MPLIST_PLIST_P (elt)
1107 || load_macros (MPLIST_PLIST (elt), macros) < 0)
1108 MERROR_GOTO (MERROR_IM, err);
1111 else if (MPLIST_SYMBOL (elt) == Mmodule)
1114 im_info->externals = externals = mplist ();
1115 MPLIST_DO (elt, MPLIST_NEXT (elt))
1117 if (! MPLIST_PLIST_P (elt)
1118 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
1119 MERROR_GOTO (MERROR_IM, err);
1122 else if (MPLIST_SYMBOL (elt) == Mstate)
1124 MPLIST_DO (elt, MPLIST_NEXT (elt))
1128 if (! MPLIST_PLIST_P (elt))
1129 MERROR_GOTO (MERROR_IM, err);
1130 state = load_state (MPLIST_PLIST (elt), maps, language, name,
1133 MERROR_GOTO (MERROR_IM, err);
1135 im_info->states = states = mplist ();
1136 mplist_put (states, state->name, state);
1139 else if (MPLIST_SYMBOL (elt) == Minclude)
1141 /* elt ::= include (tag1 tag2 ...) key item ... */
1143 MInputMethodInfo *temp;
1146 elt = MPLIST_NEXT (elt);
1147 if (! MPLIST_PLIST_P (elt))
1148 MERROR_GOTO (MERROR_IM, err);
1149 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
1151 MERROR_GOTO (MERROR_IM, err);
1152 elt = MPLIST_NEXT (elt);
1153 if (! MPLIST_SYMBOL_P (elt))
1154 MERROR_GOTO (MERROR_IM, err);
1155 key = MPLIST_SYMBOL (elt);
1156 elt = MPLIST_NEXT (elt);
1160 im_info->maps = maps = mplist ();
1161 MPLIST_DO (pl, temp->maps)
1163 p = MPLIST_VAL (pl);
1164 MPLIST_ADD_PLIST (maps, MPLIST_KEY (pl), p);
1165 M17N_OBJECT_REF (p);
1168 else if (key == Mmacro)
1171 im_info->macros = macros = mplist ();
1172 MPLIST_DO (pl, temp->macros)
1174 p = MPLIST_VAL (pl);
1175 MPLIST_ADD_PLIST (macros, MPLIST_KEY (pl), p);
1176 M17N_OBJECT_REF (p);
1179 else if (key == Mstate)
1182 im_info->states = states = mplist ();
1183 MPLIST_DO (pl, temp->states)
1185 MIMState *state = MPLIST_VAL (pl);
1187 MPLIST_ADD_PLIST (states, MPLIST_KEY (pl), state);
1188 M17N_OBJECT_REF (state);
1192 MERROR_GOTO (MERROR_IM, err);
1194 plist = MPLIST_NEXT (plist);
1201 = title = mtext_from_data (MSYMBOL_NAME (im_info->im->name),
1202 MSYMBOL_NAMELEN (im_info->im->name),
1203 MTEXT_FORMAT_US_ASCII);
1207 free_im_info (im_info);
1213 static int take_action_list (MInputContext *ic, MPlist *action_list);
1214 static void preedit_commit (MInputContext *ic);
1217 shift_state (MInputContext *ic, MSymbol state_name)
1219 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1220 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1221 MIMState *orig_state = ic_info->state, *state;
1223 /* Find a state to shift to. If not found, shift to the initial
1225 if (state_name == Mt)
1227 if (! ic_info->prev_state)
1229 state = ic_info->prev_state;
1233 state = (MIMState *) mplist_get (im_info->states, state_name);
1235 state = (MIMState *) MPLIST_VAL (im_info->states);
1238 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
1240 /* Enter the new state. */
1241 ic_info->state = state;
1242 ic_info->map = state->map;
1243 ic_info->state_key_head = ic_info->key_head;
1244 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1245 /* We have shifted to the initial state. */
1246 preedit_commit (ic);
1247 mtext_cpy (ic_info->preedit_saved, ic->preedit);
1248 ic_info->state_pos = ic->cursor_pos;
1249 if (state != orig_state )
1251 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1252 ic_info->prev_state = NULL;
1254 ic_info->prev_state = orig_state;
1257 ic->status = state->title;
1258 else if (! ic->status)
1259 ic->status = im_info->title;
1260 ic->status_changed = 1;
1261 if (ic_info->map == ic_info->state->map
1262 && ic_info->map->map_actions)
1264 MDEBUG_PRINT (" init-actions:");
1265 take_action_list (ic, ic_info->map->map_actions);
1270 /* Find a candidate group that contains a candidate number INDEX from
1271 PLIST. Set START_INDEX to the first candidate number of the group,
1272 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
1273 candidate group number if they are non-NULL. If INDEX is -1, find
1274 the last candidate group. */
1277 find_candidates_group (MPlist *plist, int index,
1278 int *start_index, int *end_index, int *group_index)
1280 int i = 0, gidx = 0, len;
1282 MPLIST_DO (plist, plist)
1284 if (MPLIST_MTEXT_P (plist))
1285 len = mtext_nchars (MPLIST_MTEXT (plist));
1287 len = mplist_length (MPLIST_PLIST (plist));
1288 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
1294 *end_index = i + len;
1296 *group_index = gidx;
1306 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
1308 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1310 int nchars = mt ? mtext_nchars (mt) : 1;
1313 mtext_ins (ic->preedit, pos, mt);
1315 mtext_ins_char (ic->preedit, pos, c, 1);
1316 MPLIST_DO (markers, ic_info->markers)
1317 if (MPLIST_INTEGER (markers) > pos)
1318 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
1319 if (ic->cursor_pos >= pos)
1320 ic->cursor_pos += nchars;
1321 ic->preedit_changed = 1;
1326 preedit_delete (MInputContext *ic, int from, int to)
1328 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1331 mtext_del (ic->preedit, from, to);
1332 MPLIST_DO (markers, ic_info->markers)
1334 if (MPLIST_INTEGER (markers) > to)
1335 MPLIST_VAL (markers)
1336 = (void *) (MPLIST_INTEGER (markers) - (to - from));
1337 else if (MPLIST_INTEGER (markers) > from);
1338 MPLIST_VAL (markers) = (void *) from;
1340 if (ic->cursor_pos >= to)
1341 ic->cursor_pos -= to - from;
1342 else if (ic->cursor_pos > from)
1343 ic->cursor_pos = from;
1344 ic->preedit_changed = 1;
1348 preedit_commit (MInputContext *ic)
1350 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1351 int preedit_len = mtext_nchars (ic->preedit);
1353 if (preedit_len > 0)
1357 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1358 Mcandidate_list, NULL, 0);
1359 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1360 Mcandidate_index, NULL, 0);
1361 mtext_cat (ic->produced, ic->preedit);
1362 if ((mdebug__flag & mdebug_mask)
1363 && mtext_nchars (ic->produced) > 0)
1367 MDEBUG_PRINT (" (produced");
1368 for (i = 0; i < mtext_nchars (ic->produced); i++)
1369 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
1372 mtext_reset (ic->preedit);
1373 mtext_reset (ic_info->preedit_saved);
1374 MPLIST_DO (p, ic_info->markers)
1376 ic->cursor_pos = ic_info->state_pos = 0;
1377 ic->preedit_changed = 1;
1379 if (ic->candidate_list)
1381 M17N_OBJECT_UNREF (ic->candidate_list);
1382 ic->candidate_list = NULL;
1383 ic->candidate_show = 0;
1384 ic->candidates_changed = 1;
1387 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
1388 sizeof (int) * (ic_info->used - ic_info->key_head));
1389 ic_info->used -= ic_info->key_head;
1390 ic_info->state_key_head = ic_info->key_head = 0;
1394 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
1396 int code = marker_code (sym);
1398 if (mt && (code == '[' || code == ']'))
1402 if (code == '[' && current > 0)
1404 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
1408 else if (code == ']' && current < mtext_nchars (mt))
1410 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
1416 return (code == '<' ? 0
1417 : code == '>' ? limit
1418 : code == '-' ? current - 1
1419 : code == '+' ? current + 1
1420 : code == '=' ? current
1421 : code - '0' > limit ? limit
1425 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1429 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1431 int from = mtext_property_start (prop);
1432 int to = mtext_property_end (prop);
1434 MPlist *candidate_list = mtext_property_value (prop);
1435 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1437 int ingroup_index = idx - start;
1440 preedit_delete (ic, from, to);
1441 if (MPLIST_MTEXT_P (group))
1443 mt = MPLIST_MTEXT (group);
1444 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1452 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1453 i++, plist = MPLIST_NEXT (plist));
1454 mt = MPLIST_MTEXT (plist);
1455 preedit_insert (ic, from, mt, 0);
1456 to = from + mtext_nchars (mt);
1458 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1459 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1460 ic->cursor_pos = to;
1464 get_select_charset (MInputContextInfo * ic_info)
1466 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
1469 if (! MPLIST_VAL (plist))
1471 sym = MPLIST_SYMBOL (plist);
1474 return MCHARSET (sym);
1478 adjust_candidate_command (MInputContextInfo *ic_info, MPlist *args,
1483 /* args ::= ((MTEXT ...) ...) | ((PLIST ...) ...) */
1484 plist = mplist_copy (MPLIST_PLIST (args));
1485 if (MPLIST_MTEXT_P (plist))
1488 while (! MPLIST_TAIL_P (pl))
1490 /* pl ::= (MTEXT ...) */
1491 MText *mt = MPLIST_MTEXT (pl);
1495 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1497 c = mtext_ref_char (mt, i);
1498 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1502 mt = mtext_dup (mt);
1503 mplist_set (pl, Mtext, mt);
1504 M17N_OBJECT_UNREF (mt);
1507 mtext_del (mt, i, i + 1);
1510 if (mtext_len (mt) > 0)
1511 pl = MPLIST_NEXT (pl);
1515 M17N_OBJECT_UNREF (mt);
1519 else /* MPLIST_PLIST_P (plist) */
1522 while (! MPLIST_TAIL_P (pl))
1524 /* pl ::= ((MTEXT ...) ...) */
1525 MPlist *p = MPLIST_PLIST (pl);
1526 /* p ::= (MTEXT ...) */
1530 while (MPLIST_TAIL_P (p))
1532 MText *mt = MPLIST_MTEXT (p);
1535 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1537 c = mtext_ref_char (mt, i);
1538 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1545 p = mplist_copy (MPLIST_PLIST (pl));
1546 mplist_set (pl, Mplist, pl);
1547 M17N_OBJECT_UNREF (p);
1550 p = MPLIST_NEXT (p);
1553 M17N_OBJECT_UNREF (mt);
1556 if (MPLIST_TAIL_P (p))
1557 pl = MPLIST_NEXT (pl);
1560 p = mplist_pop (pl);
1561 M17N_OBJECT_UNREF (p);
1565 if (MPLIST_TAIL_P (plist))
1567 M17N_OBJECT_UNREF (plist);
1571 mplist_add (args, Mplist, plist);
1572 M17N_OBJECT_UNREF (plist);
1577 take_action_list (MInputContext *ic, MPlist *action_list)
1579 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1580 MPlist *candidate_list = ic->candidate_list;
1581 int candidate_index = ic->candidate_index;
1582 int candidate_show = ic->candidate_show;
1583 MTextProperty *prop;
1585 MPLIST_DO (action_list, action_list)
1591 if (MPLIST_PLIST_P (action_list)
1592 && MPLIST_SYMBOL_P (MPLIST_PLIST (action_list)))
1594 action = MPLIST_PLIST (action_list);
1595 name = MPLIST_SYMBOL (action);
1596 args = MPLIST_NEXT (action);
1598 && MPLIST_PLIST_P (args))
1600 name = M_candidates;
1601 mplist_set (action, Msymbol, name);
1604 else if (MPLIST_MTEXT_P (action_list)
1605 || MPLIST_INTEGER_P (action_list))
1608 mplist_push (action, MPLIST_KEY (action_list),
1609 MPLIST_VAL (action_list));
1610 mplist_push (action, Msymbol, Minsert);
1611 mplist_set (action_list, Mplist, action);
1612 M17N_OBJECT_UNREF (action);
1614 args = MPLIST_NEXT (action);
1618 /* (MPLIST_PLIST_P (action_list)
1619 && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list))
1620 || MPLIST_PLIST_P (MPLIST_PLIST (action_list)))) */
1622 mplist_push (action, Mplist, MPLIST_VAL (action_list));
1623 mplist_push (action, Msymbol, M_candidates);
1624 mplist_set (action_list, Mplist, action);
1625 M17N_OBJECT_UNREF (action);
1626 name = M_candidates;
1627 args = MPLIST_NEXT (action);
1630 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1631 if (name == Minsert)
1633 if (MPLIST_SYMBOL_P (args))
1635 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
1636 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
1639 if (MPLIST_MTEXT_P (args))
1640 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1641 else /* MPLIST_INTEGER_P (args)) */
1642 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1644 else if (name == M_candidates)
1646 MCharset *charset = get_select_charset (ic_info);
1647 MPlist *plist = resolve_variable (ic_info, Mcandidates_group_size);
1648 int column = MPLIST_INTEGER (plist);
1654 if (! (args = adjust_candidate_command (ic_info, args, charset)))
1658 /* Avoid freeing ARGS later. */
1659 M17N_OBJECT_REF (args);
1661 plist = MPLIST_PLIST (args);
1664 MPlist *next = MPLIST_NEXT (plist);
1666 if (MPLIST_MTEXT_P (plist))
1668 MText *mt = MPLIST_MTEXT (plist);
1670 if (MPLIST_TAIL_P (next))
1671 M17N_OBJECT_REF (mt);
1674 mt = mtext_dup (mt);
1675 while (! MPLIST_TAIL_P (next))
1677 mt = mtext_cat (mt, MPLIST_MTEXT (next));
1678 next = MPLIST_NEXT (next);
1681 len = mtext_nchars (mt);
1685 for (i = 0; i < len; i += column)
1687 int to = (i + column < len ? i + column : len);
1688 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
1690 mplist_add (plist, Mtext, sub);
1691 M17N_OBJECT_UNREF (sub);
1694 M17N_OBJECT_UNREF (mt);
1696 else /* MPLIST_PLIST_P (plist) */
1698 MPlist *pl = MPLIST_PLIST (plist), *p;
1701 if (MPLIST_TAIL_P (next))
1702 M17N_OBJECT_REF (pl);
1705 pl = mplist_copy (pl);
1706 while (! MPLIST_TAIL_P (next))
1708 pl = mplist__conc (pl, MPLIST_PLIST (next));
1709 next = MPLIST_NEXT (next);
1712 len = mplist_length (pl);
1718 for (i = 0; i < len; i += column)
1721 mplist_add (plist, Mplist, p);
1722 M17N_OBJECT_UNREF (p);
1723 for (j = 0; j < column && i + j < len; j++)
1725 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
1726 p0 = MPLIST_NEXT (p0);
1730 M17N_OBJECT_UNREF (pl);
1734 if (plist == MPLIST_PLIST (args))
1735 M17N_OBJECT_REF (plist);
1736 if (MPLIST_MTEXT_P (plist))
1738 preedit_insert (ic, ic->cursor_pos, NULL,
1739 mtext_ref_char (MPLIST_MTEXT (plist), 0));
1744 mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
1745 preedit_insert (ic, ic->cursor_pos, mt, 0);
1746 len = mtext_nchars (mt);
1748 mtext_put_prop (ic->preedit,
1749 ic->cursor_pos - len, ic->cursor_pos,
1750 Mcandidate_list, plist);
1751 mtext_put_prop (ic->preedit,
1752 ic->cursor_pos - len, ic->cursor_pos,
1753 Mcandidate_index, (void *) 0);
1754 M17N_OBJECT_UNREF (plist);
1755 M17N_OBJECT_UNREF (args);
1757 else if (name == Mselect)
1760 int code, idx, gindex;
1761 int pos = ic->cursor_pos;
1765 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1768 if (MPLIST_SYMBOL_P (args))
1770 code = marker_code (MPLIST_SYMBOL (args));
1776 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1777 group = find_candidates_group (mtext_property_value (prop), idx,
1778 &start, &end, &gindex);
1780 if (code != '[' && code != ']')
1784 ? new_index (NULL, ic->candidate_index - start,
1785 end - start - 1, MPLIST_SYMBOL (args),
1787 : MPLIST_INTEGER (args)));
1790 find_candidates_group (mtext_property_value (prop), -1,
1795 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1800 int ingroup_index = idx - start;
1803 group = mtext_property_value (prop);
1804 len = mplist_length (group);
1817 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1818 idx += (MPLIST_MTEXT_P (group)
1819 ? mtext_nchars (MPLIST_MTEXT (group))
1820 : mplist_length (MPLIST_PLIST (group)));
1821 len = (MPLIST_MTEXT_P (group)
1822 ? mtext_nchars (MPLIST_MTEXT (group))
1823 : mplist_length (MPLIST_PLIST (group)));
1824 if (ingroup_index >= len)
1825 ingroup_index = len - 1;
1826 idx += ingroup_index;
1828 update_candidate (ic, prop, idx);
1830 else if (name == Mshow)
1831 ic->candidate_show = 1;
1832 else if (name == Mhide)
1833 ic->candidate_show = 0;
1834 else if (name == Mdelete)
1836 int len = mtext_nchars (ic->preedit);
1837 int to = (MPLIST_SYMBOL_P (args)
1838 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1840 : MPLIST_INTEGER (args));
1846 if (to < ic->cursor_pos)
1847 preedit_delete (ic, to, ic->cursor_pos);
1848 else if (to > ic->cursor_pos)
1849 preedit_delete (ic, ic->cursor_pos, to);
1851 else if (name == Mmove)
1853 int len = mtext_nchars (ic->preedit);
1855 = (MPLIST_SYMBOL_P (args)
1856 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1858 : MPLIST_INTEGER (args));
1864 if (pos != ic->cursor_pos)
1866 ic->cursor_pos = pos;
1867 ic->preedit_changed = 1;
1870 else if (name == Mmark)
1872 int code = marker_code (MPLIST_SYMBOL (args));
1875 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1876 (void *) ic->cursor_pos);
1878 else if (name == Mpushback)
1880 if (MPLIST_INTEGER_P (args))
1882 int num = MPLIST_INTEGER (args);
1885 ic_info->key_head -= num;
1887 ic_info->key_head = num;
1888 if (ic_info->key_head > ic_info->used)
1889 ic_info->key_head = ic_info->used;
1891 else if (MPLIST_MTEXT_P (args))
1893 MText *mt = MPLIST_MTEXT (args);
1894 int i, len = mtext_nchars (mt);
1897 ic_info->key_head--;
1898 for (i = 0; i < len; i++)
1900 key = one_char_symbol[MTEXT_DATA (mt)[i]];
1901 if (ic_info->key_head + i < ic_info->used)
1902 ic_info->keys[ic_info->key_head + i] = key;
1904 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1909 MPlist *plist = MPLIST_PLIST (args), *pl;
1913 ic_info->key_head--;
1915 MPLIST_DO (pl, plist)
1917 key = MPLIST_SYMBOL (pl);
1918 if (ic_info->key_head < ic_info->used)
1919 ic_info->keys[ic_info->key_head + i] = key;
1921 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1926 else if (name == Mcall)
1928 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1929 MIMExternalFunc func = NULL;
1930 MSymbol module, func_name;
1931 MPlist *func_args, *val;
1934 module = MPLIST_SYMBOL (args);
1935 args = MPLIST_NEXT (args);
1936 func_name = MPLIST_SYMBOL (args);
1938 if (im_info->externals)
1940 MIMExternalModule *external
1941 = (MIMExternalModule *) mplist_get (im_info->externals,
1944 func = (MIMExternalFunc) mplist_get (external->func_list,
1949 func_args = mplist ();
1950 mplist_add (func_args, Mt, ic);
1951 MPLIST_DO (args, MPLIST_NEXT (args))
1955 if (MPLIST_KEY (args) == Msymbol
1956 && MPLIST_KEY (args) != Mnil
1957 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1959 code = new_index (ic, ic->cursor_pos,
1960 mtext_nchars (ic->preedit),
1961 MPLIST_SYMBOL (args), ic->preedit);
1962 mplist_add (func_args, Minteger, (void *) code);
1965 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1967 val = (func) (func_args);
1968 M17N_OBJECT_UNREF (func_args);
1969 if (val && ! MPLIST_TAIL_P (val))
1970 ret = take_action_list (ic, val);
1971 M17N_OBJECT_UNREF (val);
1975 else if (name == Mshift)
1977 shift_state (ic, MPLIST_SYMBOL (args));
1979 else if (name == Mundo)
1981 int intarg = (MPLIST_TAIL_P (args)
1982 ? ic_info->used - 2 : integer_value (ic, args, NULL));
1984 mtext_reset (ic->preedit);
1985 mtext_reset (ic_info->preedit_saved);
1986 ic->cursor_pos = ic_info->state_pos = 0;
1987 ic_info->state_key_head = ic_info->key_head = 0;
1990 ic_info->used = intarg;
1991 shift_state (ic, Mnil);
1994 else if (name == Mset || name == Madd || name == Msub
1995 || name == Mmul || name == Mdiv)
1997 MSymbol sym = MPLIST_SYMBOL (args);
2002 val1 = integer_value (ic, args, &value);
2003 args = MPLIST_NEXT (args);
2004 val2 = integer_value (ic, args, NULL);
2006 val1 = val2, op = "=";
2007 else if (name == Madd)
2008 val1 += val2, op = "+=";
2009 else if (name == Msub)
2010 val1 -= val2, op = "-=";
2011 else if (name == Mmul)
2012 val1 *= val2, op = "*=";
2014 val1 /= val2, op = "/=";
2015 mplist_set (value, Minteger, (void *) val1);
2016 MDEBUG_PRINT3 ("(%s %s %d)", MSYMBOL_NAME (sym), op, val1);
2018 else if (name == Mequal || name == Mless || name == Mgreater)
2021 MPlist *actions1, *actions2;
2024 val1 = integer_value (ic, args, NULL);
2025 args = MPLIST_NEXT (args);
2026 val2 = integer_value (ic, args, NULL);
2027 args = MPLIST_NEXT (args);
2028 actions1 = MPLIST_PLIST (args);
2029 args = MPLIST_NEXT (args);
2030 if (MPLIST_TAIL_P (args))
2033 actions2 = MPLIST_PLIST (args);
2034 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
2035 if (name == Mequal ? val1 == val2
2036 : name == Mless ? val1 < val2
2039 MDEBUG_PRINT ("ok");
2040 ret = take_action_list (ic, actions1);
2044 MDEBUG_PRINT ("no");
2046 ret = take_action_list (ic, actions2);
2051 else if (name == Mcommit)
2053 preedit_commit (ic);
2055 else if (name == Munhandle)
2057 preedit_commit (ic);
2063 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2067 && (actions = mplist_get (im_info->macros, name)))
2069 if (take_action_list (ic, actions) < 0)
2076 if (ic->candidate_list)
2078 M17N_OBJECT_UNREF (ic->candidate_list);
2079 ic->candidate_list = NULL;
2081 if (ic->cursor_pos > 0
2082 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
2085 ic->candidate_list = mtext_property_value (prop);
2086 M17N_OBJECT_REF (ic->candidate_list);
2088 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
2090 ic->candidate_from = mtext_property_start (prop);
2091 ic->candidate_to = mtext_property_end (prop);
2094 ic->candidates_changed |= (candidate_list != ic->candidate_list
2095 || candidate_index != ic->candidate_index
2096 || candidate_show != ic->candidate_show);
2101 /* Handle the input key KEY in the current state and map specified in
2102 the input context IC. If KEY is handled correctly, return 0.
2103 Otherwise, return -1. */
2106 handle_key (MInputContext *ic)
2108 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2109 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2110 MIMMap *map = ic_info->map;
2111 MIMMap *submap = NULL;
2112 MSymbol key = ic_info->keys[ic_info->key_head];
2115 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
2116 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
2122 submap = mplist_get (map->submaps, key);
2123 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
2124 submap = mplist_get (map->submaps, alias);
2129 MDEBUG_PRINT (" submap-found");
2130 mtext_cpy (ic->preedit, ic_info->preedit_saved);
2131 ic->preedit_changed = 1;
2132 ic->cursor_pos = ic_info->state_pos;
2133 ic_info->key_head++;
2134 ic_info->map = map = submap;
2135 if (map->map_actions)
2137 MDEBUG_PRINT (" map-actions:");
2138 if (take_action_list (ic, map->map_actions) < 0)
2140 MDEBUG_PRINT ("\n");
2144 else if (map->submaps)
2146 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
2148 MSymbol key = ic_info->keys[i];
2149 char *name = msymbol_name (key);
2151 if (! name[0] || ! name[1])
2152 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
2156 /* If this is the terminal map or we have shifted to another
2157 state, perform branch actions (if any). */
2158 if (! map->submaps || map != ic_info->map)
2160 if (map->branch_actions)
2162 MDEBUG_PRINT (" branch-actions:");
2163 if (take_action_list (ic, map->branch_actions) < 0)
2165 MDEBUG_PRINT ("\n");
2169 /* If MAP is still not the root map, shift to the current
2171 if (ic_info->map != ic_info->state->map)
2172 shift_state (ic, ic_info->state->name);
2177 /* MAP can not handle KEY. */
2179 /* If MAP is the root map of the initial state, it means that
2180 the current input method can not handle KEY. */
2181 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
2183 MDEBUG_PRINT (" unhandled\n");
2187 if (map != ic_info->state->map)
2189 /* If MAP is not the root map... */
2190 /* If MAP has branch actions, perform them. */
2191 if (map->branch_actions)
2193 MDEBUG_PRINT (" branch-actions:");
2194 if (take_action_list (ic, map->branch_actions) < 0)
2196 MDEBUG_PRINT ("\n");
2200 /* If MAP is still not the root map, shift to the current
2202 if (ic_info->map != ic_info->state->map)
2204 shift_state (ic, ic_info->state->name);
2206 /* If MAP has branch_actions, perform them. */
2207 if (ic_info->map->branch_actions)
2209 MDEBUG_PRINT (" brank-actions:");
2210 take_action_list (ic, ic_info->map->branch_actions);
2217 /* MAP is the root map, perform branch actions (if any) or
2218 shift to the initial state. */
2219 if (map->branch_actions)
2221 MDEBUG_PRINT (" branch-actions:");
2222 if (take_action_list (ic, map->branch_actions) < 0)
2224 MDEBUG_PRINT ("\n");
2229 shift_state (ic, Mnil);
2232 MDEBUG_PRINT ("\n");
2237 reset_ic (MInputContext *ic, MSymbol ignore)
2239 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2240 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2243 MDEBUG_PRINT ("\n [IM] reset\n");
2245 ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
2246 ic_info->prev_state = NULL;
2247 ic_info->map = ic_info->state->map;
2248 ic_info->state_key_head = ic_info->key_head;
2249 MLIST_RESET (ic_info);
2250 ic_info->key_unhandled = 0;
2252 if (mtext_nchars (ic->produced) > 0)
2253 mtext_reset (ic->produced);
2254 if (mtext_nchars (ic->preedit) > 0)
2258 mtext_reset (ic->preedit);
2259 MPLIST_DO (plist, ic_info->markers)
2260 MPLIST_VAL (plist) = 0;
2261 ic->preedit_changed = 1;
2263 if (ic->candidate_show)
2265 ic->candidate_show = 0;
2266 if (ic->candidate_list)
2268 M17N_OBJECT_UNREF (ic->candidate_list);
2269 ic->candidate_list = NULL;
2270 ic->candidates_changed = 1;
2273 mtext_reset (ic_info->preedit_saved);
2274 ic_info->state_pos = ic->cursor_pos = 0;
2276 status = ic_info->state->title ? ic_info->state->title : im_info->title;
2277 if (ic->status != status)
2279 ic->status = status;
2280 ic->status_changed = 1;
2285 open_im (MInputMethod *im)
2287 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil);
2290 MERROR (MERROR_IM, -1);
2297 close_im (MInputMethod *im)
2303 create_ic (MInputContext *ic)
2305 MInputMethod *im = ic->im;
2306 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
2307 MInputContextInfo *ic_info;
2311 ic_info = (MInputContextInfo *) ic->info;
2314 MSTRUCT_CALLOC (ic_info, MERROR_IM);
2317 MLIST_INIT1 (ic_info, keys, 8);
2318 ic_info->markers = mplist ();
2319 ic_info->vars = mplist ();
2320 plist = get_nested_list (im->language, im->name, Mnil, M_variable);
2321 MPLIST_DO (plist, plist)
2323 MSymbol var = MPLIST_SYMBOL (plist);
2326 plist = MPLIST_NEXT (plist);
2327 pl = MPLIST_PLIST (plist);
2328 pl = MPLIST_NEXT (pl); /* Skip description. */
2329 mplist_push (ic_info->vars, MPLIST_KEY (pl), MPLIST_VAL (pl));
2330 mplist_push (ic_info->vars, Msymbol, var);
2332 plist = resolve_variable (ic_info, Mcandidates_group_size);
2333 if (! MPLIST_INTEGER_P (plist))
2334 mplist_set (plist, Minteger, (void *) 10);
2335 plist = resolve_variable (ic_info, Mcandidates_charset);
2337 ic_info->preedit_saved = mtext ();
2338 if (im_info->externals)
2340 MPlist *func_args = mplist (), *plist;
2342 mplist_add (func_args, Mt, ic);
2343 MPLIST_DO (plist, im_info->externals)
2345 MIMExternalModule *external = MPLIST_VAL (plist);
2346 MIMExternalFunc func
2347 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
2352 M17N_OBJECT_UNREF (func_args);
2354 reset_ic (ic, Mnil);
2359 destroy_ic (MInputContext *ic)
2361 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2362 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2364 if (im_info->externals)
2366 MPlist *func_args = mplist (), *plist;
2368 mplist_add (func_args, Mt, ic);
2369 MPLIST_DO (plist, im_info->externals)
2371 MIMExternalModule *external = MPLIST_VAL (plist);
2372 MIMExternalFunc func
2373 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
2378 M17N_OBJECT_UNREF (func_args);
2380 MLIST_FREE1 (ic_info, keys);
2381 M17N_OBJECT_UNREF (ic_info->preedit_saved);
2382 M17N_OBJECT_UNREF (ic_info->markers);
2383 M17N_OBJECT_UNREF (ic_info->vars);
2388 /** Handle the input key KEY in the current state and map of IC->info.
2389 If KEY is handled but no text is produced, return 0, otherwise
2395 filter (MInputContext *ic, MSymbol key, void *arg)
2397 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2398 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2401 if (! ic_info->state)
2403 ic_info->key_unhandled = 1;
2406 mtext_reset (ic->produced);
2407 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
2408 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2409 ic_info->key_unhandled = 0;
2411 if (handle_key (ic) < 0)
2413 /* KEY was not handled. Delete it from the current key sequence. */
2414 if (ic_info->used > 0)
2416 memmove (ic_info->keys, ic_info->keys + 1,
2417 sizeof (int) * (ic_info->used - 1));
2420 /* This forces returning 1. */
2421 ic_info->key_unhandled = 1;
2427 reset_ic (ic, Mnil);
2428 ic_info->key_unhandled = 1;
2431 /* Break the loop if all keys were handled. */
2432 } while (ic_info->key_head < ic_info->used);
2434 /* If the current map is the root of the initial state, we should
2435 produce any preedit text in ic->produced. */
2436 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2437 && mtext_nchars (ic->preedit) > 0)
2438 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2440 if (mtext_nchars (ic->produced) > 0)
2442 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2445 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2446 Mlanguage, ic->im->language);
2449 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2453 /** Return 1 if the last event or key was not handled, otherwise
2456 There is no need of looking up because ic->produced should already
2457 contain the produced text (if any).
2462 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2464 mtext_cat (mt, ic->produced);
2465 mtext_reset (ic->produced);
2466 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2469 static MPlist *load_im_info_keys;
2472 load_partial_im_info (MSymbol language, MSymbol name,
2473 MSymbol extra, MSymbol key)
2478 if (language == Mnil || name == Mnil)
2479 MERROR (MERROR_IM, NULL);
2480 mdb = mdatabase_find (Minput_method, language, name, Mnil);
2482 MERROR (MERROR_IM, NULL);
2484 mplist_push (load_im_info_keys, key, Mt);
2485 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2486 mplist_pop (load_im_info_keys);
2491 static MInputMethodInfo *
2492 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2496 MInputMethodInfo *im_info = NULL;
2498 if (language == Mnil)
2499 MERROR (MERROR_IM, NULL);
2500 mdb = mdatabase_find (Minput_method, language, name, extra);
2502 MERROR (MERROR_IM, NULL);
2505 im_info_list = mplist ();
2506 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2508 if (mdatabase__check (mdb))
2510 plist = MPLIST_NEXT (plist);
2511 im_info = MPLIST_VAL (plist);
2515 free_im_info (MPLIST_VAL (plist));
2519 plist = mdatabase_load (mdb);
2521 MERROR (MERROR_IM, NULL);
2522 im_info = load_im_info (language, name, plist);
2523 M17N_OBJECT_UNREF (plist);
2525 MERROR (MERROR_IM, NULL);
2526 mplist_push (im_info_list, Mt, im_info);
2527 mplist_push (im_info_list, Mt, mdb);
2532 /* Input method command handler. */
2534 /* List of all (global and local) commands.
2535 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2536 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2537 Global commands are storead as (t (t COMMAND ...)) */
2539 /* Check if PLIST is a valid command key sequence.
2540 PLIST must be NULL or:
2541 [ symbol:KEY | integer:KEY ] ... */
2544 check_command_keyseq (MPlist *plist)
2548 MPLIST_DO (plist, plist)
2550 if (MPLIST_SYMBOL_P (plist))
2552 else if (MPLIST_INTEGER_P (plist))
2554 int n = MPLIST_INTEGER (plist);
2558 MPLIST_KEY (plist) = Msymbol;
2559 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2567 /* Check if PLIST has this form:
2568 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2570 If the form of PLIST matches, return 0, otherwise return -1. */
2573 check_command_list (MPlist *plist)
2575 MPLIST_DO (plist, plist)
2577 if (MPLIST_PLIST_P (plist))
2579 MPlist *pl = MPLIST_PLIST (plist);
2582 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2585 else if (! MPLIST_MTEXT_P (plist))
2593 /* Input method variable handler. */
2595 /* Check if PLIST has this form:
2596 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2599 If the form of PLIST matches, return 0, otherwise return -1. */
2602 check_variable_list (MPlist *plist)
2604 MSymbol type = MPLIST_KEY (plist);
2607 if (type != Minteger && type != Mtext && type != Msymbol)
2609 MPLIST_DO (plist, MPLIST_NEXT (plist))
2611 if (type == Minteger && MPLIST_PLIST_P (plist))
2613 MPLIST_DO (p, MPLIST_PLIST (plist))
2614 if (! MPLIST_INTEGER_P (p))
2617 else if (type != MPLIST_KEY (plist))
2623 /* Support functions for mdebug_dump_im. */
2626 dump_im_map (MPlist *map_list, int indent)
2629 MSymbol key = MPLIST_KEY (map_list);
2630 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2632 prefix = (char *) alloca (indent + 1);
2633 memset (prefix, 32, indent);
2634 prefix[indent] = '\0';
2636 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2637 if (map->map_actions)
2638 mdebug_dump_plist (map->map_actions, indent + 2);
2641 MPLIST_DO (map_list, map->submaps)
2643 fprintf (stderr, "\n%s ", prefix);
2644 dump_im_map (map_list, indent + 2);
2647 if (map->branch_actions)
2649 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2650 mdebug_dump_plist (map->branch_actions, indent + 4);
2651 fprintf (stderr, ")");
2653 fprintf (stderr, ")");
2658 dump_im_state (MIMState *state, int indent)
2663 prefix = (char *) alloca (indent + 1);
2664 memset (prefix, 32, indent);
2665 prefix[indent] = '\0';
2667 fprintf (stderr, "(%s", msymbol_name (state->name));
2668 if (state->map->submaps)
2670 MPLIST_DO (map_list, state->map->submaps)
2672 fprintf (stderr, "\n%s ", prefix);
2673 dump_im_map (map_list, indent + 2);
2676 fprintf (stderr, ")");
2685 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2686 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2687 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2688 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2689 char buf[6], buf2[256];
2693 Minput_method = msymbol ("input-method");
2694 Minput_driver = msymbol ("input-driver");
2695 Mtitle = msymbol ("title");
2696 Mmacro = msymbol ("macro");
2697 Mmodule = msymbol ("module");
2698 Mmap = msymbol ("map");
2699 Mstate = msymbol ("state");
2700 Minclude = msymbol ("include");
2701 Minsert = msymbol ("insert");
2702 M_candidates = msymbol (" candidates");
2703 Mdelete = msymbol ("delete");
2704 Mmove = msymbol ("move");
2705 Mmark = msymbol ("mark");
2706 Mpushback = msymbol ("pushback");
2707 Mundo = msymbol ("undo");
2708 Mcall = msymbol ("call");
2709 Mshift = msymbol ("shift");
2710 Mselect = msymbol ("select");
2711 Mshow = msymbol ("show");
2712 Mhide = msymbol ("hide");
2713 Mcommit = msymbol ("commit");
2714 Munhandle = msymbol ("unhandle");
2715 Mset = msymbol ("set");
2716 Madd = msymbol ("add");
2717 Msub = msymbol ("sub");
2718 Mmul = msymbol ("mul");
2719 Mdiv = msymbol ("div");
2720 Mequal = msymbol ("=");
2721 Mless = msymbol ("<");
2722 Mgreater = msymbol (">");
2724 Mcandidates_group_size = msymbol ("candidates-group-size");
2725 Mcandidates_charset = msymbol ("candidates-charset");
2727 Minput_preedit_start = msymbol ("input-preedit-start");
2728 Minput_preedit_done = msymbol ("input-preedit-done");
2729 Minput_preedit_draw = msymbol ("input-preedit-draw");
2730 Minput_status_start = msymbol ("input-status-start");
2731 Minput_status_done = msymbol ("input-status-done");
2732 Minput_status_draw = msymbol ("input-status-draw");
2733 Minput_candidates_start = msymbol ("input-candidates-start");
2734 Minput_candidates_done = msymbol ("input-candidates-done");
2735 Minput_candidates_draw = msymbol ("input-candidates-draw");
2736 Minput_set_spot = msymbol ("input-set-spot");
2737 Minput_focus_move = msymbol ("input-focus-move");
2738 Minput_focus_in = msymbol ("input-focus-in");
2739 Minput_focus_out = msymbol ("input-focus-out");
2740 Minput_toggle = msymbol ("input-toggle");
2741 Minput_reset = msymbol ("input-reset");
2743 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2744 Mcandidate_index = msymbol (" candidate-index");
2746 Minit = msymbol ("init");
2747 Mfini = msymbol ("fini");
2749 M_key_alias = msymbol (" key-alias");
2750 M_description = msymbol ("description");
2751 M_command = msymbol ("command");
2752 M_variable = msymbol ("variable");
2754 load_im_info_keys = mplist ();
2755 plist = mplist_add (load_im_info_keys, Mstate, Mnil);
2760 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2764 one_char_symbol[i] = msymbol (buf);
2767 alias = msymbol (key_names[i]);
2768 msymbol_put (one_char_symbol[i], M_key_alias, alias);
2771 alias = one_char_symbol[i];
2772 buf[2] += (i == 0) ? -32 : 32;
2773 msymbol_put (alias, M_key_alias, msymbol (buf));
2774 buf[2] -= (i == 0) ? -32 : 32;
2776 for (buf[2] = i; i < 127; i++, buf[2]++)
2777 one_char_symbol[i] = msymbol (buf + 2);
2778 one_char_symbol[i++] = msymbol ("Delete");
2784 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2786 one_char_symbol[i] = msymbol (buf);
2787 if (key_names[i - 128])
2789 strcpy (buf2 + 2, key_names[i - 128]);
2790 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2793 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2794 one_char_symbol[i] = msymbol (buf + 2);
2795 one_char_symbol[i] = msymbol ("M-Delete");
2797 command_list = variable_list = NULL;
2799 minput_default_driver.open_im = open_im;
2800 minput_default_driver.close_im = close_im;
2801 minput_default_driver.create_ic = create_ic;
2802 minput_default_driver.destroy_ic = destroy_ic;
2803 minput_default_driver.filter = filter;
2804 minput_default_driver.lookup = lookup;
2805 minput_default_driver.callback_list = mplist ();
2806 mplist_put (minput_default_driver.callback_list, Minput_reset,
2808 minput_driver = &minput_default_driver;
2817 M17N_OBJECT_UNREF (command_list);
2818 command_list = NULL;
2822 M17N_OBJECT_UNREF (variable_list);
2823 variable_list = NULL;
2826 if (minput_default_driver.callback_list)
2828 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2829 minput_default_driver.callback_list = NULL;
2831 if (minput_driver->callback_list)
2833 M17N_OBJECT_UNREF (minput_driver->callback_list);
2834 minput_driver->callback_list = NULL;
2839 while (! MPLIST_TAIL_P (im_info_list))
2842 mplist_pop (im_info_list);
2843 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
2844 /* Pop (t . im_info) */
2845 mplist_pop (im_info_list);
2847 M17N_OBJECT_UNREF (im_info_list);
2848 im_info_list = NULL;
2851 M17N_OBJECT_UNREF (load_im_info_keys);
2855 minput__callback (MInputContext *ic, MSymbol command)
2857 if (ic->im->driver.callback_list)
2859 MInputCallbackFunc func
2860 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2864 (func) (ic, command);
2869 minput__char_to_key (int c)
2871 if (c < 0 || c >= 0x100)
2874 return one_char_symbol[c];
2878 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2883 /*** @addtogroup m17nInputMethod */
2888 @name Variables: Predefined symbols for callback commands.
2890 These are the predefined symbols that are used as the @c COMMAND
2891 argument of callback functions of an input method driver (see
2892 #MInputDriver::callback_list ). */
2894 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2896 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2897 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2902 MSymbol Minput_preedit_start;
2903 MSymbol Minput_preedit_done;
2904 MSymbol Minput_preedit_draw;
2905 MSymbol Minput_status_start;
2906 MSymbol Minput_status_done;
2907 MSymbol Minput_status_draw;
2908 MSymbol Minput_candidates_start;
2909 MSymbol Minput_candidates_done;
2910 MSymbol Minput_candidates_draw;
2911 MSymbol Minput_set_spot;
2912 MSymbol Minput_toggle;
2913 MSymbol Minput_reset;
2919 @name Variables: Predefined symbols for special input events.
2921 These are the predefined symbols that are used as the @c KEY
2922 argument of minput_filter (). */
2927 MSymbol Minput_focus_out;
2928 MSymbol Minput_focus_in;
2929 MSymbol Minput_focus_move;
2936 @brief The default driver for internal input methods.
2938 The variable #minput_default_driver is the default driver for
2939 internal input methods.
2941 The member MInputDriver::open_im () searches the m17n database for
2942 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2943 $NAME\> and loads it.
2945 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2946 programmers responsibility to set it to a plist of proper callback
2947 functions. Otherwise, no feedback information (e.g. preedit text)
2948 can be shown to users.
2950 The macro M17N_INIT () sets the variable #minput_driver to the
2951 pointer to this driver so that all internal input methods use it.
2953 Therefore, unless @c minput_driver is set differently, the driver
2954 dependent arguments $ARG of the functions whose name begin with
2955 "minput_" are all ignored. */
2958 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2960 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2962 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2963 \< #Minput_method, $LANGUAGE, $NAME\>
2964 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2966 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2967 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2968 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2969 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2971 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2972 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2974 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2975 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2977 MInputDriver minput_default_driver;
2981 @brief The driver for internal input methods.
2983 The variable #minput_driver is a pointer to the input method
2984 driver that is used by internal input methods. The macro
2985 M17N_INIT () initializes it to a pointer to #minput_default_driver
2986 if <m17n<EM></EM>.h> is included. */
2988 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
2990 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
2991 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
2992 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
2993 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
2995 MInputDriver *minput_driver;
2997 MSymbol Minput_driver;
3002 @brief Open an input method.
3004 The minput_open_im () function opens an input method that matches
3005 language $LANGUAGE and name $NAME, and returns a pointer to the
3006 input method object newly allocated.
3008 This function at first decides an driver for the input method as
3011 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3012 #minput_driver is used.
3014 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
3015 driver pointed to by the property value is used to open the input
3016 method. If $NAME has no such property, @c NULL is returned.
3018 Then, the member MInputDriver::open_im () of the driver is
3021 $ARG is set in the member @c arg of the structure MInputMethod so
3022 that the driver can refer to it. */
3025 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3027 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3028 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3030 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3032 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3033 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3035 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3036 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3037 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3039 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3041 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3043 @latexonly \IPAlabel{minput_open} @endlatexonly
3048 minput_open_im (MSymbol language, MSymbol name, void *arg)
3051 MInputDriver *driver;
3053 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3054 msymbol_name (language), msymbol_name (name));
3056 driver = minput_driver;
3059 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3061 MERROR (MERROR_IM, NULL);
3064 MSTRUCT_CALLOC (im, MERROR_IM);
3065 im->language = language;
3068 im->driver = *driver;
3069 if ((*im->driver.open_im) (im) < 0)
3071 MDEBUG_PRINT (" failed\n");
3075 MDEBUG_PRINT (" ok\n");
3082 @brief Close an input method.
3084 The minput_close_im () function closes the input method $IM, which
3085 must have been created by minput_open_im (). */
3088 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3090 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3091 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3094 minput_close_im (MInputMethod *im)
3096 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3097 msymbol_name (im->name), msymbol_name (im->language));
3098 (*im->driver.close_im) (im);
3100 MDEBUG_PRINT (" done\n");
3106 @brief Create an input context.
3108 The minput_create_ic () function creates an input context object
3109 associated with input method $IM, and calls callback functions
3110 corresponding to #Minput_preedit_start, #Minput_status_start, and
3111 #Minput_status_draw in this order.
3115 If an input context is successfully created, minput_create_ic ()
3116 returns a pointer to it. Otherwise it returns @c NULL. */
3119 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3121 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3122 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3123 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3124 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3128 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3129 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3133 minput_create_ic (MInputMethod *im, void *arg)
3137 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3138 msymbol_name (im->name), msymbol_name (im->language));
3139 MSTRUCT_CALLOC (ic, MERROR_IM);
3142 ic->preedit = mtext ();
3143 ic->candidate_list = NULL;
3144 ic->produced = mtext ();
3145 ic->spot.x = ic->spot.y = 0;
3147 ic->plist = mplist ();
3148 if ((*im->driver.create_ic) (ic) < 0)
3150 MDEBUG_PRINT (" failed\n");
3151 M17N_OBJECT_UNREF (ic->preedit);
3152 M17N_OBJECT_UNREF (ic->produced);
3153 M17N_OBJECT_UNREF (ic->plist);
3158 if (im->driver.callback_list)
3160 minput__callback (ic, Minput_preedit_start);
3161 minput__callback (ic, Minput_status_start);
3162 minput__callback (ic, Minput_status_draw);
3165 MDEBUG_PRINT (" ok\n");
3172 @brief Destroy an input context.
3174 The minput_destroy_ic () function destroys the input context $IC,
3175 which must have been created by minput_create_ic (). It calls
3176 callback functions corresponding to #Minput_preedit_done,
3177 #Minput_status_done, and #Minput_candidates_done in this order. */
3180 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3182 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3183 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3184 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3185 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3186 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3190 minput_destroy_ic (MInputContext *ic)
3192 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3193 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3194 if (ic->im->driver.callback_list)
3196 minput__callback (ic, Minput_preedit_done);
3197 minput__callback (ic, Minput_status_done);
3198 minput__callback (ic, Minput_candidates_done);
3200 (*ic->im->driver.destroy_ic) (ic);
3201 M17N_OBJECT_UNREF (ic->preedit);
3202 M17N_OBJECT_UNREF (ic->produced);
3203 M17N_OBJECT_UNREF (ic->plist);
3204 MDEBUG_PRINT (" done\n");
3211 @brief Filter an input key.
3213 The minput_filter () function filters input key $KEY according to
3214 input context $IC, and calls callback functions corresponding to
3215 #Minput_preedit_draw, #Minput_status_draw, and
3216 #Minput_candidates_draw if the preedit text, the status, and the
3217 current candidate are changed respectively.
3219 To make the input method commit the current preedit text (if any)
3220 and shift to the initial state, call this function with #Mnil as
3223 To inform the input method about the focus-out event, call this
3224 function with #Minput_focus_out as $KEY.
3226 To inform the input method about the focus-in event, call this
3227 function with #Minput_focus_in as $KEY.
3229 To inform the input method about the focus-move event (i.e. input
3230 spot change within the same input context), call this function
3231 with #Minput_focus_move as $KEY.
3234 If $KEY is filtered out, this function returns 1. In that case,
3235 the caller should discard the key. Otherwise, it returns 0, and
3236 the caller should handle the key, for instance, by calling the
3237 function minput_lookup () with the same key. */
3240 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3242 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3243 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3244 #Minput_preedit_draw, #Minput_status_draw,
3245 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3248 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3249 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3250 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3251 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3253 @latexonly \IPAlabel{minput_filter} @endlatexonly
3257 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3264 ret = (*ic->im->driver.filter) (ic, key, arg);
3266 if (ic->im->driver.callback_list)
3268 if (ic->preedit_changed)
3269 minput__callback (ic, Minput_preedit_draw);
3270 if (ic->status_changed)
3271 minput__callback (ic, Minput_status_draw);
3272 if (ic->candidates_changed)
3273 minput__callback (ic, Minput_candidates_draw);
3282 @brief Look up a text produced in the input context.
3284 The minput_lookup () function looks up a text in the input context
3285 $IC. $KEY must be the same one provided to the previous call of
3288 If a text was produced by the input method, it is concatenated
3291 This function calls #MInputDriver::lookup .
3294 If $KEY was correctly handled by the input method, this function
3295 returns 0. Otherwise, returns -1, even in that case, some text
3296 may be produced in $MT. */
3299 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3301 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3302 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3304 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3307 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3310 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3311 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3312 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3314 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3317 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3319 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3324 @brief Set the spot of the input context.
3326 The minput_set_spot () function set the spot of input context $IC
3327 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3328 The semantics of these values depend on the input method driver.
3330 For instance, a driver designed to work in a CUI environment may
3331 use $X and $Y as column and row numbers, and ignore $ASCENT and
3332 $DESCENT . A driver designed to work in a window system may
3333 interpret $X and $Y as pixel offsets relative to the origin of the
3334 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3335 descent pixels of the line at ($X . $Y ).
3337 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3339 $MT and $POS is the M-text and the character position at the spot.
3340 $MT may be @c NULL, in which case, the input method cannot get
3341 information about the text around the spot. */
3344 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3346 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3347 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3348 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3350 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3351 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3352 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3353 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3354 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3355 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3357 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3359 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3360 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3364 minput_set_spot (MInputContext *ic, int x, int y,
3365 int ascent, int descent, int fontsize,
3370 ic->spot.ascent = ascent;
3371 ic->spot.descent = descent;
3372 ic->spot.fontsize = fontsize;
3375 if (ic->im->driver.callback_list)
3376 minput__callback (ic, Minput_set_spot);
3381 @brief Toggle input method.
3383 The minput_toggle () function toggles the input method associated
3384 with input context $IC. */
3386 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3388 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3389 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3393 minput_toggle (MInputContext *ic)
3395 if (ic->im->driver.callback_list)
3396 minput__callback (ic, Minput_toggle);
3397 ic->active = ! ic->active;
3401 @brief Reset an input context.
3403 The minput_reset_ic () function resets input context $IC by
3404 calling a callback function corresponding to #Minput_reset. It
3405 resets the status of $IC to the one of just after created. As the
3406 current preedit text is deleted without commitment, if necessary,
3407 call minput_filter () with the arg @r key #Mnil to force the input
3408 method to commit the preedit in advance. */
3411 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3413 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3414 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3415 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3416 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3417 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3418 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3421 minput_reset_ic (MInputContext *ic)
3423 if (ic->im->driver.callback_list)
3424 minput__callback (ic, Minput_reset);
3428 @brief Get description text of an input method.
3430 The minput_get_description () function returns an M-text that
3431 describes the input method specified by $LANGUAGE and $NAME.
3434 If the specified input method has a description text, a pointer to
3435 #MText is returned. A caller have to free it by m17n_object_unref ().
3436 If the input method does not have a description text, @c NULL is
3439 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3441 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3442 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3444 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3445 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3446 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3447 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3450 minput_get_description (MSymbol language, MSymbol name)
3452 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3458 pl = MPLIST_PLIST (plist);
3459 pl = MPLIST_NEXT (pl);
3460 if (MPLIST_MTEXT_P (pl))
3462 mt = MPLIST_MTEXT (pl);
3463 M17N_OBJECT_REF (mt);
3465 M17N_OBJECT_UNREF (plist);
3470 @brief Get information about input method commands.
3472 The minput_get_commands () function returns information about
3473 input method commands of the input method specified by $LANGUAGE
3474 and $NAME. An input method command is a pseudo key event to which
3475 one or more actual input key sequences are assigned.
3477 There are two kinds of commands, global and local. Global
3478 commands are used by multiple input methods for the same purpose,
3479 and have global key assignments. Local commands are used only in
3480 a specific input method, and have only local key assignments.
3482 Each input method may locally change key assignments for global
3483 commands. A global key assignment for a global command are
3484 effective only when the current input method does not have local
3485 key assignments for that command.
3487 If $NAME is #Mnil, information about global commands is returned.
3488 In this case $LANGUAGE is ignored.
3490 If $NAME is not #Mnil, information about those commands that have
3491 local key assignments in the input method specified by $LANGUAGE
3492 and $NAME is returned.
3495 If no input method commands are found, this function returns @c NULL.
3497 Otherwise, a pointer to a plist is returned. The key of each
3498 element in the plist is a symbol representing a command, and the
3499 value is a plist of the form COMMAND-INFO described below.
3501 The first element of COMMAND-INFO has the key #Mtext, and the
3502 value is an M-text describing the command.
3504 If there are no more elements, that means no key sequences are
3505 assigned to the command. Otherwise, each of the remaining
3506 elements has the key #Mplist, and the value is a plist whose keys are
3507 #Msymbol and values are symbols representing input keys, which are
3508 currently assigned to the command.
3510 As the returned plist is kept in the library, the caller must not
3511 modify nor free it. */
3513 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3515 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3516 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3517 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3518 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3520 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3521 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3522 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3523 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3525 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3526 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3527 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3530 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3531 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3533 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3534 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3538 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3540 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3541 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3542 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3544 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3545 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3546 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3549 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3550 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3551 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3552 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3553 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3555 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3556 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3559 minput_get_commands (MSymbol language, MSymbol name)
3561 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
3563 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3567 @brief Assign a key sequence to an input method command.
3569 The minput_assign_command_keys () function assigns input key
3570 sequence $KEYSEQ to input method command $COMMAND for the input
3571 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3572 key sequence is assigned globally no matter what $LANGUAGE is.
3573 Otherwise the key sequence is assigned locally.
3575 Each element of $KEYSEQ must have the key $Msymbol and the value
3576 must be a symbol representing an input key.
3578 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3579 globally or locally.
3581 This assignment gets effective in a newly opened input method.
3584 If the operation was successful, 0 is returned. Otherwise -1 is
3585 returned, and #merror_code is set to #MERROR_IM. */
3587 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3589 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
3590 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
3591 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
3592 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
3593 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3595 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
3596 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3598 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
3599 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3601 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
3604 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3605 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3608 minput_assign_command_keys (MSymbol language, MSymbol name,
3609 MSymbol command, MPlist *keyseq)
3611 MPlist *plist, *pl, *p;
3613 if (check_command_keyseq (keyseq) < 0
3614 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
3615 MERROR (MERROR_IM, -1);
3616 pl = mplist_get (plist, command);
3619 pl = MPLIST_NEXT (pl);
3621 while ((p = mplist_pop (pl)))
3622 M17N_OBJECT_UNREF (p);
3625 keyseq = mplist_copy (keyseq);
3626 mplist_push (pl, Mplist, keyseq);
3627 M17N_OBJECT_UNREF (keyseq);
3633 MERROR (MERROR_IM, -1);
3636 /* Get global commands. */
3637 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
3638 pl = mplist_get (pl, command);
3640 MERROR (MERROR_IM, -1);
3642 mplist_add (p, Mtext, mplist_value (pl));
3643 keyseq = mplist_copy (keyseq);
3644 mplist_add (p, Mplist, keyseq);
3645 M17N_OBJECT_UNREF (keyseq);
3646 mplist_push (plist, command, p);
3652 @brief Get a list of variables of an input method.
3654 The minput_get_variables () function returns a plist (#MPlist) of
3655 variables used to control the behavior of the input method
3656 specified by $LANGUAGE and $NAME. The key of an element of the
3657 plist is a symbol representing a variable, and the value is a
3658 plist of the form VAR-INFO (described below) that carries the
3659 information about the variable.
3661 The first element of VAR-INFO has the key #Mtext or #Msymbol. If
3662 the key is #Mtext, the value is an M-text describing the variable.
3663 If the key is #Msymbol, that value is #Mnil which means the
3664 variable has no description text.
3666 The second element of VAR-INFO is for the value of the variable.
3667 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3668 integer, a symbol, or an M-text, respectively. The variable is
3669 set to this value when an input context is created for the input
3672 If there are no more elements, the variable can take any value
3673 that matches with the above type. Otherwise, the remaining
3674 elements of VAR-INFO are to specify valid values of the variable.
3676 If the type of the variable is integer, the following elements
3677 have the key #Minteger or #Mplist. If it is #Minteger, the value
3678 is a valid integer value. If it is #Mplist, the value is a plist
3679 of two of elements. Both of them have the key #Minteger, and
3680 values are the minimum and maximum bounds of the valid value
3683 If the type of the variable is symbol or M-text, the following
3684 elements of the plist have the key #Msymbol or #Mtext,
3685 respectively, and the value must be a valid one.
3687 For instance, suppose an input method has the variables:
3689 @li name:intvar, description:"value is an integer",
3690 initial value:0, value-range:0..3,10,20
3692 @li name:symvar, description:"value is a symbol",
3693 initial value:nil, value-range:a, b, c, nil
3695 @li name:txtvar, description:"value is an M-text",
3696 initial value:empty text, no value-range (i.e. any text)
3698 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3699 a value, and '(...)' means a plist):
3702 plist:(intvar:(mtext:"value is an integer"
3704 plist:(integer:0 integer:3)
3707 symvar:(mtext:"value is a symbol"
3713 txtvar:(mtext:"value is an M-text"
3718 If the input method uses any variables, a pointer to #MPlist is
3719 returned. As the plist is kept in the library, a caller must not
3720 modify nor free it. If the input method does not use any
3721 variable, @c NULL is returned. */
3723 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3725 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3726 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3727 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3728 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3729 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3731 VAR-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼¤¬
3732 #Mtext ¤Ê¤é¡¢ÃͤϤ½¤ÎÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬ #Msymbol
3733 ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤ÎÊÑ¿ô¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê¤¤¤³¤È¤Ë¤Ê¤ë¡£
3735 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3736 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3737 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3739 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3740 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3742 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3743 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3744 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3745 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3747 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3748 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3750 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3752 @li name:intvar, ÀâÌÀ:"value is an integer",
3753 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3755 @li name:symvar, ÀâÌÀ:"value is a symbol",
3756 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3758 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3759 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3761 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3762 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3765 plist:(intvar:(mtext:"value is an integer"
3767 plist:(integer:0 integer:3)
3770 symvar:(mtext:"value is a symbol"
3776 txtvar:(mtext:"value is an M-text"
3781 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3782 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3783 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3786 minput_get_variables (MSymbol language, MSymbol name)
3788 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
3790 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3794 @brief Set the initial value of an input method variable.
3796 The minput_set_variable () function sets the initial value of
3797 input method variable $VARIABLE to $VALUE for the input method
3798 specified by $LANGUAGE and $NAME.
3800 By default, the initial value is 0.
3802 This setting gets effective in a newly opened input method.
3805 If the operation was successful, 0 is returned. Otherwise -1 is
3806 returned, and #merror_code is set to #MERROR_IM. */
3808 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3810 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3811 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3812 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3814 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3816 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3819 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3820 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3823 minput_set_variable (MSymbol language, MSymbol name,
3824 MSymbol variable, void *value)
3826 MPlist *plist, *val_element, *range_element;
3829 if (language == Mnil || name == Mnil)
3830 MERROR (MERROR_IM, -1);
3831 plist = get_nested_list (language, name, Mnil, M_variable);
3833 MERROR (MERROR_IM, -1);
3834 plist = (MPlist *) mplist_get (plist, variable);
3836 MERROR (MERROR_IM, -1);
3837 val_element = MPLIST_NEXT (plist);
3838 type = MPLIST_KEY (val_element);
3839 range_element = MPLIST_NEXT (val_element);
3841 if (! MPLIST_TAIL_P (range_element))
3843 if (type == Minteger)
3845 int val = (int) value, this_val;
3847 MPLIST_DO (plist, range_element)
3849 this_val = (int) MPLIST_VAL (plist);
3850 if (MPLIST_PLIST_P (plist))
3852 int min_bound, max_bound;
3853 MPlist *pl = MPLIST_PLIST (plist);
3855 min_bound = (int) MPLIST_VAL (pl);
3856 pl = MPLIST_NEXT (pl);
3857 max_bound = (int) MPLIST_VAL (pl);
3858 if (val >= min_bound && val <= max_bound)
3861 else if (val == this_val)
3864 if (MPLIST_TAIL_P (plist))
3865 MERROR (MERROR_IM, -1);
3867 else if (type == Msymbol)
3869 MPLIST_DO (plist, range_element)
3870 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3872 if (MPLIST_TAIL_P (plist))
3873 MERROR (MERROR_IM, -1);
3875 else /* type == Mtext */
3877 MPLIST_DO (plist, range_element)
3878 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3880 if (MPLIST_TAIL_P (plist))
3881 MERROR (MERROR_IM, -1);
3882 M17N_OBJECT_REF (value);
3886 mplist_set (val_element, type, value);
3892 /*** @addtogroup m17nDebug */
3898 @brief Dump an input method.
3900 The mdebug_dump_im () function prints the input method $IM in a
3901 human readable way to the stderr. $INDENT specifies how many
3902 columns to indent the lines but the first one.
3905 This function returns $IM. */
3907 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3909 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3910 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3913 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3916 mdebug_dump_im (MInputMethod *im, int indent)
3918 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3921 prefix = (char *) alloca (indent + 1);
3922 memset (prefix, 32, indent);
3923 prefix[indent] = '\0';
3925 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3926 msymbol_name (im->name));
3927 mdebug_dump_mtext (im_info->title, 0, 0);
3928 if (im->name != Mnil)
3932 MPLIST_DO (state, im_info->states)
3934 fprintf (stderr, "\n%s ", prefix);
3935 dump_im_state (MPLIST_VAL (state), indent + 2);
3938 fprintf (stderr, ")");