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);
815 else if ((plist = (MPlist *) mplist_get (maps, map_name)))
817 MPLIST_DO (plist, plist)
819 MPlist *keylist, *map_actions;
821 if (! MPLIST_PLIST_P (plist))
822 MERROR (MERROR_IM, -1);
823 keylist = MPLIST_PLIST (plist);
824 map_actions = MPLIST_NEXT (keylist);
825 if (MPLIST_SYMBOL_P (keylist))
827 MSymbol command = MPLIST_SYMBOL (keylist);
828 MPlist *pl = resolve_command (language, name, command);
833 if (load_translation (map, pl, map_actions, branch_actions,
835 MERROR (MERROR_IM, -1);
838 if (load_translation (map, keylist, map_actions, branch_actions,
840 MERROR (MERROR_IM, -1);
847 /* Load a macro from PLIST into MACROS.
849 PLIST ::= ( MACRO-NAME ACTION * )
850 MACROS is a plist of macro names vs action list. */
852 load_macros (MPlist *plist, MPlist *macros)
856 if (! MPLIST_SYMBOL_P (plist))
857 MERROR (MERROR_IM, -1);
858 name = MPLIST_SYMBOL (plist);
859 plist = MPLIST_NEXT (plist);
860 if (MPLIST_TAIL_P (plist)
861 || parse_action_list (plist, macros) < 0)
862 MERROR (MERROR_IM, -1);
863 mplist_put (macros, name, plist);
864 M17N_OBJECT_REF (plist);
868 /* Load an external module from PLIST into EXTERNALS.
870 PLIST ::= ( MODULE-NAME FUNCTION * )
871 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
874 load_external_module (MPlist *plist, MPlist *externals)
879 MIMExternalModule *external;
883 if (MPLIST_MTEXT_P (plist))
884 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
885 else if (MPLIST_SYMBOL_P (plist))
886 module = MPLIST_SYMBOL (plist);
887 module_file = alloca (strlen (MSYMBOL_NAME (module))
888 + strlen (DLOPEN_SHLIB_EXT) + 1);
889 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
891 handle = dlopen (module_file, RTLD_NOW);
894 fprintf (stderr, "%s\n", dlerror ());
895 MERROR (MERROR_IM, -1);
897 func_list = mplist ();
898 MPLIST_DO (plist, MPLIST_NEXT (plist))
900 if (! MPLIST_SYMBOL_P (plist))
901 MERROR_GOTO (MERROR_IM, err_label);
902 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
904 MERROR_GOTO (MERROR_IM, err_label);
905 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
908 MSTRUCT_MALLOC (external, MERROR_IM);
909 external->handle = handle;
910 external->func_list = func_list;
911 mplist_add (externals, module, external);
916 M17N_OBJECT_UNREF (func_list);
921 free_map (MIMMap *map, int top)
926 M17N_OBJECT_UNREF (map->map_actions);
929 MPLIST_DO (plist, map->submaps)
930 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
931 M17N_OBJECT_UNREF (map->submaps);
933 M17N_OBJECT_UNREF (map->branch_actions);
938 free_state (void *object)
940 MIMState *state = object;
943 M17N_OBJECT_UNREF (state->title);
945 free_map (state->map, 1);
949 /** Load a state from PLIST into a newly allocated state object.
951 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
952 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
953 MAPS is a plist of defined maps.
954 Return the state object. */
957 load_state (MPlist *plist, MPlist *maps, MSymbol language, MSymbol name,
962 if (! MPLIST_SYMBOL_P (plist))
963 MERROR (MERROR_IM, NULL);
964 M17N_OBJECT (state, free_state, MERROR_IM);
965 state->name = MPLIST_SYMBOL (plist);
966 plist = MPLIST_NEXT (plist);
967 if (MPLIST_MTEXT_P (plist))
969 state->title = MPLIST_MTEXT (plist);
970 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
971 Mlanguage, language);
972 M17N_OBJECT_REF (state->title);
973 plist = MPLIST_NEXT (plist);
975 MSTRUCT_CALLOC (state->map, MERROR_IM);
976 MPLIST_DO (plist, plist)
977 if (! MPLIST_PLIST_P (plist)
978 || load_branch (MPLIST_PLIST (plist), maps, state->map, language, name,
980 MERROR (MERROR_IM, NULL);
985 static MPlist *im_info_list;
988 free_im_info (MInputMethodInfo *im_info)
993 M17N_OBJECT_UNREF (im_info->title);
996 MPLIST_DO (plist, im_info->states)
998 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1000 M17N_OBJECT_UNREF (state);
1002 M17N_OBJECT_UNREF (im_info->states);
1005 if (im_info->macros)
1007 MPLIST_DO (plist, im_info->macros)
1008 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1009 M17N_OBJECT_UNREF (im_info->macros);
1012 if (im_info->externals)
1014 MPLIST_DO (plist, im_info->externals)
1016 MIMExternalModule *external = MPLIST_VAL (plist);
1018 dlclose (external->handle);
1019 M17N_OBJECT_UNREF (external->func_list);
1021 MPLIST_KEY (plist) = Mt;
1023 M17N_OBJECT_UNREF (im_info->externals);
1027 MPLIST_DO (plist, im_info->maps)
1029 MPlist *p = MPLIST_PLIST (plist);
1031 M17N_OBJECT_UNREF (p);
1033 M17N_OBJECT_UNREF (im_info->maps);
1039 static MInputMethodInfo *get_im_info (MSymbol language, MSymbol name,
1042 static MInputMethodInfo *
1043 get_im_info_by_tags (MPlist *plist)
1048 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1049 i++, plist = MPLIST_NEXT (plist))
1050 tag[i] = MPLIST_SYMBOL (plist);
1055 return get_im_info (tag[0], tag[1], tag[2]);
1058 /* Load an input method from PLIST into IM_INTO, and return it. */
1060 static MInputMethodInfo *
1061 load_im_info (MSymbol language, MSymbol name, MPlist *plist)
1063 MInputMethodInfo *im_info;
1064 MText *title = NULL;
1065 MPlist *maps = NULL;
1066 MPlist *states = NULL;
1067 MPlist *externals = NULL;
1068 MPlist *macros = NULL;
1071 MSTRUCT_CALLOC (im_info, MERROR_IM);
1073 while (MPLIST_PLIST_P (plist))
1075 elt = MPLIST_PLIST (plist);
1076 if (! MPLIST_SYMBOL_P (elt))
1077 MERROR_GOTO (MERROR_IM, err);
1078 if (MPLIST_SYMBOL (elt) == Mtitle)
1080 elt = MPLIST_NEXT (elt);
1081 if (! MPLIST_MTEXT_P (elt))
1082 MERROR_GOTO (MERROR_IM, err);
1083 im_info->title = title = MPLIST_MTEXT (elt);
1084 M17N_OBJECT_REF (title);
1086 else if (MPLIST_SYMBOL (elt) == Mmap)
1088 MPlist *pl = mplist__from_alist (MPLIST_NEXT (elt));
1091 MERROR_GOTO (MERROR_IM, err);
1093 im_info->maps = maps = pl;
1095 maps = mplist__conc (maps, pl);
1097 else if (MPLIST_SYMBOL (elt) == Mmacro)
1100 im_info->macros = macros = mplist ();
1101 MPLIST_DO (elt, MPLIST_NEXT (elt))
1103 if (! MPLIST_PLIST_P (elt)
1104 || load_macros (MPLIST_PLIST (elt), macros) < 0)
1105 MERROR_GOTO (MERROR_IM, err);
1108 else if (MPLIST_SYMBOL (elt) == Mmodule)
1111 im_info->externals = externals = mplist ();
1112 MPLIST_DO (elt, MPLIST_NEXT (elt))
1114 if (! MPLIST_PLIST_P (elt)
1115 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
1116 MERROR_GOTO (MERROR_IM, err);
1119 else if (MPLIST_SYMBOL (elt) == Mstate)
1121 MPLIST_DO (elt, MPLIST_NEXT (elt))
1125 if (! MPLIST_PLIST_P (elt))
1126 MERROR_GOTO (MERROR_IM, err);
1127 state = load_state (MPLIST_PLIST (elt), maps, language, name,
1130 MERROR_GOTO (MERROR_IM, err);
1132 im_info->states = states = mplist ();
1133 mplist_put (states, state->name, state);
1136 else if (MPLIST_SYMBOL (elt) == Minclude)
1138 /* elt ::= include (tag1 tag2 ...) key item ... */
1140 MInputMethodInfo *temp;
1143 elt = MPLIST_NEXT (elt);
1144 if (! MPLIST_PLIST_P (elt))
1145 MERROR_GOTO (MERROR_IM, err);
1146 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
1148 MERROR_GOTO (MERROR_IM, err);
1149 elt = MPLIST_NEXT (elt);
1150 if (! MPLIST_SYMBOL_P (elt))
1151 MERROR_GOTO (MERROR_IM, err);
1152 key = MPLIST_SYMBOL (elt);
1153 elt = MPLIST_NEXT (elt);
1157 im_info->maps = maps = mplist ();
1158 MPLIST_DO (pl, temp->maps)
1160 p = MPLIST_VAL (pl);
1161 MPLIST_ADD_PLIST (maps, MPLIST_KEY (pl), p);
1162 M17N_OBJECT_REF (p);
1165 else if (key == Mmacro)
1168 im_info->macros = macros = mplist ();
1169 MPLIST_DO (pl, temp->macros)
1171 p = MPLIST_VAL (pl);
1172 MPLIST_ADD_PLIST (macros, MPLIST_KEY (pl), p);
1173 M17N_OBJECT_REF (p);
1176 else if (key == Mstate)
1179 im_info->states = states = mplist ();
1180 MPLIST_DO (pl, temp->states)
1182 MIMState *state = MPLIST_VAL (pl);
1184 mplist_add (states, MPLIST_KEY (pl), state);
1185 M17N_OBJECT_REF (state);
1189 MERROR_GOTO (MERROR_IM, err);
1191 plist = MPLIST_NEXT (plist);
1196 if (! title && name)
1198 = title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
1199 MTEXT_FORMAT_US_ASCII);
1203 free_im_info (im_info);
1209 static int take_action_list (MInputContext *ic, MPlist *action_list);
1210 static void preedit_commit (MInputContext *ic);
1213 shift_state (MInputContext *ic, MSymbol state_name)
1215 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1216 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1217 MIMState *orig_state = ic_info->state, *state;
1219 /* Find a state to shift to. If not found, shift to the initial
1221 if (state_name == Mt)
1223 if (! ic_info->prev_state)
1225 state = ic_info->prev_state;
1229 state = (MIMState *) mplist_get (im_info->states, state_name);
1231 state = (MIMState *) MPLIST_VAL (im_info->states);
1234 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
1236 /* Enter the new state. */
1237 ic_info->state = state;
1238 ic_info->map = state->map;
1239 ic_info->state_key_head = ic_info->key_head;
1240 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1241 /* We have shifted to the initial state. */
1242 preedit_commit (ic);
1243 mtext_cpy (ic_info->preedit_saved, ic->preedit);
1244 ic_info->state_pos = ic->cursor_pos;
1245 if (state != orig_state )
1247 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1248 ic_info->prev_state = NULL;
1250 ic_info->prev_state = orig_state;
1253 ic->status = state->title;
1255 ic->status = im_info->title;
1256 ic->status_changed = 1;
1257 if (ic_info->map == ic_info->state->map
1258 && ic_info->map->map_actions)
1260 MDEBUG_PRINT (" init-actions:");
1261 take_action_list (ic, ic_info->map->map_actions);
1266 /* Find a candidate group that contains a candidate number INDEX from
1267 PLIST. Set START_INDEX to the first candidate number of the group,
1268 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
1269 candidate group number if they are non-NULL. If INDEX is -1, find
1270 the last candidate group. */
1273 find_candidates_group (MPlist *plist, int index,
1274 int *start_index, int *end_index, int *group_index)
1276 int i = 0, gidx = 0, len;
1278 MPLIST_DO (plist, plist)
1280 if (MPLIST_MTEXT_P (plist))
1281 len = mtext_nchars (MPLIST_MTEXT (plist));
1283 len = mplist_length (MPLIST_PLIST (plist));
1284 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
1290 *end_index = i + len;
1292 *group_index = gidx;
1302 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
1304 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1306 int nchars = mt ? mtext_nchars (mt) : 1;
1309 mtext_ins (ic->preedit, pos, mt);
1311 mtext_ins_char (ic->preedit, pos, c, 1);
1312 MPLIST_DO (markers, ic_info->markers)
1313 if (MPLIST_INTEGER (markers) > pos)
1314 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
1315 if (ic->cursor_pos >= pos)
1316 ic->cursor_pos += nchars;
1317 ic->preedit_changed = 1;
1322 preedit_delete (MInputContext *ic, int from, int to)
1324 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1327 mtext_del (ic->preedit, from, to);
1328 MPLIST_DO (markers, ic_info->markers)
1330 if (MPLIST_INTEGER (markers) > to)
1331 MPLIST_VAL (markers)
1332 = (void *) (MPLIST_INTEGER (markers) - (to - from));
1333 else if (MPLIST_INTEGER (markers) > from);
1334 MPLIST_VAL (markers) = (void *) from;
1336 if (ic->cursor_pos >= to)
1337 ic->cursor_pos -= to - from;
1338 else if (ic->cursor_pos > from)
1339 ic->cursor_pos = from;
1340 ic->preedit_changed = 1;
1344 preedit_commit (MInputContext *ic)
1346 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1347 int preedit_len = mtext_nchars (ic->preedit);
1349 if (preedit_len > 0)
1353 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1354 Mcandidate_list, NULL, 0);
1355 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1356 Mcandidate_index, NULL, 0);
1357 mtext_cat (ic->produced, ic->preedit);
1358 if ((mdebug__flag & mdebug_mask)
1359 && mtext_nchars (ic->produced) > 0)
1363 MDEBUG_PRINT (" (produced");
1364 for (i = 0; i < mtext_nchars (ic->produced); i++)
1365 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
1368 mtext_reset (ic->preedit);
1369 mtext_reset (ic_info->preedit_saved);
1370 MPLIST_DO (p, ic_info->markers)
1372 ic->cursor_pos = ic_info->state_pos = 0;
1373 ic->preedit_changed = 1;
1375 if (ic->candidate_list)
1377 M17N_OBJECT_UNREF (ic->candidate_list);
1378 ic->candidate_list = NULL;
1379 ic->candidate_show = 0;
1380 ic->candidates_changed = 1;
1383 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
1384 sizeof (int) * (ic_info->used - ic_info->key_head));
1385 ic_info->used -= ic_info->key_head;
1386 ic_info->state_key_head = ic_info->key_head = 0;
1390 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
1392 int code = marker_code (sym);
1394 if (mt && (code == '[' || code == ']'))
1398 if (code == '[' && current > 0)
1400 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
1404 else if (code == ']' && current < mtext_nchars (mt))
1406 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
1412 return (code == '<' ? 0
1413 : code == '>' ? limit
1414 : code == '-' ? current - 1
1415 : code == '+' ? current + 1
1416 : code == '=' ? current
1417 : code - '0' > limit ? limit
1421 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1425 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1427 int from = mtext_property_start (prop);
1428 int to = mtext_property_end (prop);
1430 MPlist *candidate_list = mtext_property_value (prop);
1431 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1433 int ingroup_index = idx - start;
1436 preedit_delete (ic, from, to);
1437 if (MPLIST_MTEXT_P (group))
1439 mt = MPLIST_MTEXT (group);
1440 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1448 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1449 i++, plist = MPLIST_NEXT (plist));
1450 mt = MPLIST_MTEXT (plist);
1451 preedit_insert (ic, from, mt, 0);
1452 to = from + mtext_nchars (mt);
1454 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1455 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1456 ic->cursor_pos = to;
1460 get_select_charset (MInputContextInfo * ic_info)
1462 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
1465 if (! MPLIST_VAL (plist))
1467 sym = MPLIST_SYMBOL (plist);
1470 return MCHARSET (sym);
1474 adjust_candidates (MPlist *plist, MCharset *charset)
1478 /* plist ::= MTEXT ... | PLIST ... */
1479 plist = mplist_copy (plist);
1480 if (MPLIST_MTEXT_P (plist))
1483 while (! MPLIST_TAIL_P (pl))
1485 /* pl ::= MTEXT ... */
1486 MText *mt = MPLIST_MTEXT (pl);
1490 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1492 c = mtext_ref_char (mt, i);
1493 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1497 mt = mtext_dup (mt);
1498 mplist_set (pl, Mtext, mt);
1499 M17N_OBJECT_UNREF (mt);
1502 mtext_del (mt, i, i + 1);
1505 if (mtext_len (mt) > 0)
1506 pl = MPLIST_NEXT (pl);
1510 M17N_OBJECT_UNREF (mt);
1514 else /* MPLIST_PLIST_P (plist) */
1517 while (! MPLIST_TAIL_P (pl))
1519 /* pl ::= (MTEXT ...) ... */
1520 MPlist *p = MPLIST_PLIST (pl);
1522 /* p ::= MTEXT ... */
1526 while (! MPLIST_TAIL_P (p0))
1528 MText *mt = MPLIST_MTEXT (p0);
1531 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1533 c = mtext_ref_char (mt, i);
1534 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1539 p0 = MPLIST_NEXT (p0);
1546 p = mplist_copy (p);
1547 mplist_set (pl, Mplist, p);
1548 M17N_OBJECT_UNREF (p);
1552 p0 = MPLIST_NEXT (p0);
1555 M17N_OBJECT_UNREF (mt);
1558 if (! MPLIST_TAIL_P (p))
1559 pl = MPLIST_NEXT (pl);
1563 M17N_OBJECT_UNREF (p);
1567 if (MPLIST_TAIL_P (plist))
1569 M17N_OBJECT_UNREF (plist);
1576 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
1578 MCharset *charset = get_select_charset (ic_info);
1583 plist = resolve_variable (ic_info, Mcandidates_group_size);
1584 column = MPLIST_INTEGER (plist);
1586 plist = MPLIST_PLIST (args);
1589 if (! (plist = adjust_candidates (plist, charset)))
1593 M17N_OBJECT_REF (plist);
1597 if (MPLIST_MTEXT_P (plist))
1599 MText *mt = MPLIST_MTEXT (plist);
1600 MPlist *next = MPLIST_NEXT (plist);
1602 if (MPLIST_TAIL_P (next))
1603 M17N_OBJECT_REF (mt);
1606 mt = mtext_dup (mt);
1607 while (! MPLIST_TAIL_P (next))
1609 mt = mtext_cat (mt, MPLIST_MTEXT (next));
1610 next = MPLIST_NEXT (next);
1613 M17N_OBJECT_UNREF (plist);
1615 len = mtext_nchars (mt);
1617 mplist_add (plist, Mtext, mt);
1620 for (i = 0; i < len; i += column)
1622 int to = (i + column < len ? i + column : len);
1623 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
1625 mplist_add (plist, Mtext, sub);
1626 M17N_OBJECT_UNREF (sub);
1629 M17N_OBJECT_UNREF (mt);
1631 else /* MPLIST_PLIST_P (plist) */
1633 MPlist *pl = MPLIST_PLIST (plist), *p;
1634 MPlist *next = MPLIST_NEXT (plist);
1637 if (MPLIST_TAIL_P (next))
1638 M17N_OBJECT_REF (pl);
1641 pl = mplist_copy (pl);
1642 while (! MPLIST_TAIL_P (next))
1644 p = mplist_copy (MPLIST_PLIST (next));
1645 pl = mplist__conc (pl, p);
1646 M17N_OBJECT_UNREF (p);
1647 next = MPLIST_NEXT (next);
1650 M17N_OBJECT_UNREF (plist);
1652 len = mplist_length (pl);
1654 mplist_add (plist, Mplist, pl);
1659 for (i = 0; i < len; i += column)
1662 mplist_add (plist, Mplist, p);
1663 M17N_OBJECT_UNREF (p);
1664 for (j = 0; j < column && i + j < len; j++)
1666 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
1667 p0 = MPLIST_NEXT (p0);
1671 M17N_OBJECT_UNREF (pl);
1680 regularize_action (MPlist *action_list)
1682 MPlist *action = NULL;
1686 if (MPLIST_PLIST_P (action_list))
1688 action = MPLIST_PLIST (action_list);
1689 if (MPLIST_SYMBOL_P (action))
1691 name = MPLIST_SYMBOL (action);
1692 args = MPLIST_NEXT (action);
1694 && MPLIST_PLIST_P (args))
1695 mplist_set (action, Msymbol, M_candidates);
1697 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
1700 mplist_push (action, Mplist, MPLIST_VAL (action_list));
1701 mplist_push (action, Msymbol, M_candidates);
1702 mplist_set (action_list, Mplist, action);
1703 M17N_OBJECT_UNREF (action);
1706 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
1709 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
1710 mplist_push (action, Msymbol, Minsert);
1711 mplist_set (action_list, Mplist, action);
1712 M17N_OBJECT_UNREF (action);
1718 take_action_list (MInputContext *ic, MPlist *action_list)
1720 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1721 MPlist *candidate_list = ic->candidate_list;
1722 int candidate_index = ic->candidate_index;
1723 int candidate_show = ic->candidate_show;
1724 MTextProperty *prop;
1726 MPLIST_DO (action_list, action_list)
1728 MPlist *action = regularize_action (action_list);
1734 name = MPLIST_SYMBOL (action);
1735 args = MPLIST_NEXT (action);
1737 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1738 if (name == Minsert)
1740 if (MPLIST_SYMBOL_P (args))
1742 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
1743 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
1746 if (MPLIST_MTEXT_P (args))
1747 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1748 else /* MPLIST_INTEGER_P (args)) */
1749 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1751 else if (name == M_candidates)
1753 MPlist *plist = get_candidate_list (ic_info, args);
1758 if (MPLIST_MTEXT_P (plist))
1760 preedit_insert (ic, ic->cursor_pos, NULL,
1761 mtext_ref_char (MPLIST_MTEXT (plist), 0));
1766 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
1768 preedit_insert (ic, ic->cursor_pos, mt, 0);
1769 len = mtext_nchars (mt);
1771 mtext_put_prop (ic->preedit,
1772 ic->cursor_pos - len, ic->cursor_pos,
1773 Mcandidate_list, plist);
1774 mtext_put_prop (ic->preedit,
1775 ic->cursor_pos - len, ic->cursor_pos,
1776 Mcandidate_index, (void *) 0);
1777 M17N_OBJECT_UNREF (plist);
1779 else if (name == Mselect)
1782 int code, idx, gindex;
1783 int pos = ic->cursor_pos;
1787 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1790 if (MPLIST_SYMBOL_P (args))
1792 code = marker_code (MPLIST_SYMBOL (args));
1798 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1799 group = find_candidates_group (mtext_property_value (prop), idx,
1800 &start, &end, &gindex);
1802 if (code != '[' && code != ']')
1806 ? new_index (NULL, ic->candidate_index - start,
1807 end - start - 1, MPLIST_SYMBOL (args),
1809 : MPLIST_INTEGER (args)));
1812 find_candidates_group (mtext_property_value (prop), -1,
1817 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1822 int ingroup_index = idx - start;
1825 group = mtext_property_value (prop);
1826 len = mplist_length (group);
1839 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1840 idx += (MPLIST_MTEXT_P (group)
1841 ? mtext_nchars (MPLIST_MTEXT (group))
1842 : mplist_length (MPLIST_PLIST (group)));
1843 len = (MPLIST_MTEXT_P (group)
1844 ? mtext_nchars (MPLIST_MTEXT (group))
1845 : mplist_length (MPLIST_PLIST (group)));
1846 if (ingroup_index >= len)
1847 ingroup_index = len - 1;
1848 idx += ingroup_index;
1850 update_candidate (ic, prop, idx);
1852 else if (name == Mshow)
1853 ic->candidate_show = 1;
1854 else if (name == Mhide)
1855 ic->candidate_show = 0;
1856 else if (name == Mdelete)
1858 int len = mtext_nchars (ic->preedit);
1859 int to = (MPLIST_SYMBOL_P (args)
1860 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1862 : MPLIST_INTEGER (args));
1868 if (to < ic->cursor_pos)
1869 preedit_delete (ic, to, ic->cursor_pos);
1870 else if (to > ic->cursor_pos)
1871 preedit_delete (ic, ic->cursor_pos, to);
1873 else if (name == Mmove)
1875 int len = mtext_nchars (ic->preedit);
1877 = (MPLIST_SYMBOL_P (args)
1878 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1880 : MPLIST_INTEGER (args));
1886 if (pos != ic->cursor_pos)
1888 ic->cursor_pos = pos;
1889 ic->preedit_changed = 1;
1892 else if (name == Mmark)
1894 int code = marker_code (MPLIST_SYMBOL (args));
1897 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1898 (void *) ic->cursor_pos);
1900 else if (name == Mpushback)
1902 if (MPLIST_INTEGER_P (args))
1904 int num = MPLIST_INTEGER (args);
1907 ic_info->key_head -= num;
1909 ic_info->key_head = num;
1910 if (ic_info->key_head > ic_info->used)
1911 ic_info->key_head = ic_info->used;
1913 else if (MPLIST_MTEXT_P (args))
1915 MText *mt = MPLIST_MTEXT (args);
1916 int i, len = mtext_nchars (mt);
1919 ic_info->key_head--;
1920 for (i = 0; i < len; i++)
1922 key = one_char_symbol[MTEXT_DATA (mt)[i]];
1923 if (ic_info->key_head + i < ic_info->used)
1924 ic_info->keys[ic_info->key_head + i] = key;
1926 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1931 MPlist *plist = MPLIST_PLIST (args), *pl;
1935 ic_info->key_head--;
1937 MPLIST_DO (pl, plist)
1939 key = MPLIST_SYMBOL (pl);
1940 if (ic_info->key_head < ic_info->used)
1941 ic_info->keys[ic_info->key_head + i] = key;
1943 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1948 else if (name == Mcall)
1950 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1951 MIMExternalFunc func = NULL;
1952 MSymbol module, func_name;
1953 MPlist *func_args, *val;
1956 module = MPLIST_SYMBOL (args);
1957 args = MPLIST_NEXT (args);
1958 func_name = MPLIST_SYMBOL (args);
1960 if (im_info->externals)
1962 MIMExternalModule *external
1963 = (MIMExternalModule *) mplist_get (im_info->externals,
1966 func = (MIMExternalFunc) mplist_get (external->func_list,
1971 func_args = mplist ();
1972 mplist_add (func_args, Mt, ic);
1973 MPLIST_DO (args, MPLIST_NEXT (args))
1977 if (MPLIST_KEY (args) == Msymbol
1978 && MPLIST_KEY (args) != Mnil
1979 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1981 code = new_index (ic, ic->cursor_pos,
1982 mtext_nchars (ic->preedit),
1983 MPLIST_SYMBOL (args), ic->preedit);
1984 mplist_add (func_args, Minteger, (void *) code);
1987 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1989 val = (func) (func_args);
1990 M17N_OBJECT_UNREF (func_args);
1991 if (val && ! MPLIST_TAIL_P (val))
1992 ret = take_action_list (ic, val);
1993 M17N_OBJECT_UNREF (val);
1997 else if (name == Mshift)
1999 shift_state (ic, MPLIST_SYMBOL (args));
2001 else if (name == Mundo)
2003 int intarg = (MPLIST_TAIL_P (args)
2004 ? ic_info->used - 2 : integer_value (ic, args, NULL));
2006 mtext_reset (ic->preedit);
2007 mtext_reset (ic_info->preedit_saved);
2008 ic->cursor_pos = ic_info->state_pos = 0;
2009 ic_info->state_key_head = ic_info->key_head = 0;
2012 ic_info->used += intarg;
2014 ic_info->used = intarg;
2015 shift_state (ic, Mnil);
2018 else if (name == Mset || name == Madd || name == Msub
2019 || name == Mmul || name == Mdiv)
2021 MSymbol sym = MPLIST_SYMBOL (args);
2026 val1 = integer_value (ic, args, &value);
2027 args = MPLIST_NEXT (args);
2028 val2 = integer_value (ic, args, NULL);
2030 val1 = val2, op = "=";
2031 else if (name == Madd)
2032 val1 += val2, op = "+=";
2033 else if (name == Msub)
2034 val1 -= val2, op = "-=";
2035 else if (name == Mmul)
2036 val1 *= val2, op = "*=";
2038 val1 /= val2, op = "/=";
2039 mplist_set (value, Minteger, (void *) val1);
2040 MDEBUG_PRINT3 ("(%s %s %d)", MSYMBOL_NAME (sym), op, val1);
2042 else if (name == Mequal || name == Mless || name == Mgreater)
2045 MPlist *actions1, *actions2;
2048 val1 = integer_value (ic, args, NULL);
2049 args = MPLIST_NEXT (args);
2050 val2 = integer_value (ic, args, NULL);
2051 args = MPLIST_NEXT (args);
2052 actions1 = MPLIST_PLIST (args);
2053 args = MPLIST_NEXT (args);
2054 if (MPLIST_TAIL_P (args))
2057 actions2 = MPLIST_PLIST (args);
2058 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
2059 if (name == Mequal ? val1 == val2
2060 : name == Mless ? val1 < val2
2063 MDEBUG_PRINT ("ok");
2064 ret = take_action_list (ic, actions1);
2068 MDEBUG_PRINT ("no");
2070 ret = take_action_list (ic, actions2);
2075 else if (name == Mcommit)
2077 preedit_commit (ic);
2079 else if (name == Munhandle)
2081 preedit_commit (ic);
2086 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2090 && (actions = mplist_get (im_info->macros, name)))
2092 if (take_action_list (ic, actions) < 0)
2099 if (ic->candidate_list)
2101 M17N_OBJECT_UNREF (ic->candidate_list);
2102 ic->candidate_list = NULL;
2104 if (ic->cursor_pos > 0
2105 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
2108 ic->candidate_list = mtext_property_value (prop);
2109 M17N_OBJECT_REF (ic->candidate_list);
2111 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
2113 ic->candidate_from = mtext_property_start (prop);
2114 ic->candidate_to = mtext_property_end (prop);
2117 ic->candidates_changed |= (candidate_list != ic->candidate_list
2118 || candidate_index != ic->candidate_index
2119 || candidate_show != ic->candidate_show);
2124 /* Handle the input key KEY in the current state and map specified in
2125 the input context IC. If KEY is handled correctly, return 0.
2126 Otherwise, return -1. */
2129 handle_key (MInputContext *ic)
2131 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2132 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2133 MIMMap *map = ic_info->map;
2134 MIMMap *submap = NULL;
2135 MSymbol key = ic_info->keys[ic_info->key_head];
2138 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
2139 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
2145 submap = mplist_get (map->submaps, key);
2146 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
2147 submap = mplist_get (map->submaps, alias);
2152 MDEBUG_PRINT (" submap-found");
2153 mtext_cpy (ic->preedit, ic_info->preedit_saved);
2154 ic->preedit_changed = 1;
2155 ic->cursor_pos = ic_info->state_pos;
2156 ic_info->key_head++;
2157 ic_info->map = map = submap;
2158 if (map->map_actions)
2160 MDEBUG_PRINT (" map-actions:");
2161 if (take_action_list (ic, map->map_actions) < 0)
2163 MDEBUG_PRINT ("\n");
2167 else if (map->submaps)
2169 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
2171 MSymbol key = ic_info->keys[i];
2172 char *name = msymbol_name (key);
2174 if (! name[0] || ! name[1])
2175 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
2179 /* If this is the terminal map or we have shifted to another
2180 state, perform branch actions (if any). */
2181 if (! map->submaps || map != ic_info->map)
2183 if (map->branch_actions)
2185 MDEBUG_PRINT (" branch-actions:");
2186 if (take_action_list (ic, map->branch_actions) < 0)
2188 MDEBUG_PRINT ("\n");
2192 /* If MAP is still not the root map, shift to the current
2194 if (ic_info->map != ic_info->state->map)
2195 shift_state (ic, ic_info->state->name);
2200 /* MAP can not handle KEY. */
2202 /* If MAP is the root map of the initial state, it means that
2203 the current input method can not handle KEY. */
2204 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
2206 MDEBUG_PRINT (" unhandled\n");
2210 if (map != ic_info->state->map)
2212 /* If MAP is not the root map... */
2213 /* If MAP has branch actions, perform them. */
2214 if (map->branch_actions)
2216 MDEBUG_PRINT (" branch-actions:");
2217 if (take_action_list (ic, map->branch_actions) < 0)
2219 MDEBUG_PRINT ("\n");
2223 /* If MAP is still not the root map, shift to the current
2225 if (ic_info->map != ic_info->state->map)
2227 shift_state (ic, ic_info->state->name);
2228 /* If MAP has branch_actions, perform them. */
2229 if (ic_info->map->branch_actions)
2231 MDEBUG_PRINT (" brank-actions:");
2232 take_action_list (ic, ic_info->map->branch_actions);
2238 /* MAP is the root map, perform branch actions (if any) or
2239 shift to the initial state. */
2240 if (map->branch_actions)
2242 MDEBUG_PRINT (" branch-actions:");
2243 if (take_action_list (ic, map->branch_actions) < 0)
2245 MDEBUG_PRINT ("\n");
2250 shift_state (ic, Mnil);
2253 MDEBUG_PRINT ("\n");
2258 reset_ic (MInputContext *ic, MSymbol ignore)
2260 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2261 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2264 MDEBUG_PRINT ("\n [IM] reset\n");
2266 ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
2267 ic_info->prev_state = NULL;
2268 ic_info->map = ic_info->state->map;
2269 ic_info->state_key_head = ic_info->key_head;
2270 MLIST_RESET (ic_info);
2271 ic_info->key_unhandled = 0;
2273 if (mtext_nchars (ic->produced) > 0)
2274 mtext_reset (ic->produced);
2275 if (mtext_nchars (ic->preedit) > 0)
2279 mtext_reset (ic->preedit);
2280 MPLIST_DO (plist, ic_info->markers)
2281 MPLIST_VAL (plist) = 0;
2282 ic->preedit_changed = 1;
2284 if (ic->candidate_show)
2286 ic->candidate_show = 0;
2287 if (ic->candidate_list)
2289 M17N_OBJECT_UNREF (ic->candidate_list);
2290 ic->candidate_list = NULL;
2291 ic->candidates_changed = 1;
2294 mtext_reset (ic_info->preedit_saved);
2295 ic_info->state_pos = ic->cursor_pos = 0;
2297 status = ic_info->state->title ? ic_info->state->title : im_info->title;
2298 if (ic->status != status)
2300 ic->status = status;
2301 ic->status_changed = 1;
2306 open_im (MInputMethod *im)
2308 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil);
2311 MERROR (MERROR_IM, -1);
2318 close_im (MInputMethod *im)
2324 create_ic (MInputContext *ic)
2326 MInputMethod *im = ic->im;
2327 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
2328 MInputContextInfo *ic_info;
2332 ic_info = (MInputContextInfo *) ic->info;
2335 MSTRUCT_CALLOC (ic_info, MERROR_IM);
2338 MLIST_INIT1 (ic_info, keys, 8);
2339 ic_info->markers = mplist ();
2340 ic_info->vars = mplist ();
2341 plist = get_nested_list (im->language, im->name, Mnil, M_variable);
2342 MPLIST_DO (plist, plist)
2344 MSymbol var = MPLIST_SYMBOL (plist);
2347 plist = MPLIST_NEXT (plist);
2348 pl = MPLIST_PLIST (plist);
2349 pl = MPLIST_NEXT (pl); /* Skip description. */
2350 mplist_push (ic_info->vars, MPLIST_KEY (pl), MPLIST_VAL (pl));
2351 mplist_push (ic_info->vars, Msymbol, var);
2353 plist = resolve_variable (ic_info, Mcandidates_group_size);
2354 if (! MPLIST_INTEGER_P (plist))
2355 mplist_set (plist, Minteger, (void *) 10);
2356 plist = resolve_variable (ic_info, Mcandidates_charset);
2358 ic_info->preedit_saved = mtext ();
2359 if (im_info->externals)
2361 MPlist *func_args = mplist (), *plist;
2363 mplist_add (func_args, Mt, ic);
2364 MPLIST_DO (plist, im_info->externals)
2366 MIMExternalModule *external = MPLIST_VAL (plist);
2367 MIMExternalFunc func
2368 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
2373 M17N_OBJECT_UNREF (func_args);
2375 reset_ic (ic, Mnil);
2380 destroy_ic (MInputContext *ic)
2382 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2383 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2385 if (im_info->externals)
2387 MPlist *func_args = mplist (), *plist;
2389 mplist_add (func_args, Mt, ic);
2390 MPLIST_DO (plist, im_info->externals)
2392 MIMExternalModule *external = MPLIST_VAL (plist);
2393 MIMExternalFunc func
2394 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
2399 M17N_OBJECT_UNREF (func_args);
2401 MLIST_FREE1 (ic_info, keys);
2402 M17N_OBJECT_UNREF (ic_info->preedit_saved);
2403 M17N_OBJECT_UNREF (ic_info->markers);
2404 M17N_OBJECT_UNREF (ic_info->vars);
2409 /** Handle the input key KEY in the current state and map of IC->info.
2410 If KEY is handled but no text is produced, return 0, otherwise
2416 filter (MInputContext *ic, MSymbol key, void *arg)
2418 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2419 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2422 if (! ic_info->state)
2424 ic_info->key_unhandled = 1;
2427 mtext_reset (ic->produced);
2428 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
2429 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2430 ic_info->key_unhandled = 0;
2432 if (handle_key (ic) < 0)
2434 /* KEY was not handled. Delete it from the current key sequence. */
2435 if (ic_info->used > 0)
2437 memmove (ic_info->keys, ic_info->keys + 1,
2438 sizeof (int) * (ic_info->used - 1));
2441 /* This forces returning 1. */
2442 ic_info->key_unhandled = 1;
2448 reset_ic (ic, Mnil);
2449 ic_info->key_unhandled = 1;
2452 /* Break the loop if all keys were handled. */
2453 } while (ic_info->key_head < ic_info->used);
2455 /* If the current map is the root of the initial state, we should
2456 produce any preedit text in ic->produced. */
2457 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2458 && mtext_nchars (ic->preedit) > 0)
2459 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2461 if (mtext_nchars (ic->produced) > 0)
2463 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2466 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2467 Mlanguage, ic->im->language);
2470 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2474 /** Return 1 if the last event or key was not handled, otherwise
2477 There is no need of looking up because ic->produced should already
2478 contain the produced text (if any).
2483 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2485 mtext_cat (mt, ic->produced);
2486 mtext_reset (ic->produced);
2487 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2490 static MPlist *load_im_info_keys;
2493 load_partial_im_info (MSymbol language, MSymbol name,
2494 MSymbol extra, MSymbol key)
2499 if (language == Mnil || name == Mnil)
2500 MERROR (MERROR_IM, NULL);
2501 mdb = mdatabase_find (Minput_method, language, name, Mnil);
2503 MERROR (MERROR_IM, NULL);
2505 mplist_push (load_im_info_keys, key, Mt);
2506 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2507 mplist_pop (load_im_info_keys);
2512 static MInputMethodInfo *
2513 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2517 MInputMethodInfo *im_info = NULL;
2519 if (language == Mnil)
2520 MERROR (MERROR_IM, NULL);
2521 mdb = mdatabase_find (Minput_method, language, name, extra);
2523 MERROR (MERROR_IM, NULL);
2526 im_info_list = mplist ();
2527 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2529 if (mdatabase__check (mdb))
2531 plist = MPLIST_NEXT (plist);
2532 im_info = MPLIST_VAL (plist);
2536 free_im_info (MPLIST_VAL (plist));
2540 plist = mdatabase_load (mdb);
2542 MERROR (MERROR_IM, NULL);
2543 im_info = load_im_info (language, name, plist);
2544 M17N_OBJECT_UNREF (plist);
2546 MERROR (MERROR_IM, NULL);
2547 mplist_push (im_info_list, Mt, im_info);
2548 mplist_push (im_info_list, Mt, mdb);
2553 /* Input method command handler. */
2555 /* List of all (global and local) commands.
2556 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2557 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2558 Global commands are storead as (t (t COMMAND ...)) */
2560 /* Check if PLIST is a valid command key sequence.
2561 PLIST must be NULL or:
2562 [ symbol:KEY | integer:KEY ] ... */
2565 check_command_keyseq (MPlist *plist)
2569 MPLIST_DO (plist, plist)
2571 if (MPLIST_SYMBOL_P (plist))
2573 else if (MPLIST_INTEGER_P (plist))
2575 int n = MPLIST_INTEGER (plist);
2579 MPLIST_KEY (plist) = Msymbol;
2580 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2588 /* Check if PLIST has this form:
2589 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2591 If the form of PLIST matches, return 0, otherwise return -1. */
2594 check_command_list (MPlist *plist)
2596 MPLIST_DO (plist, plist)
2598 if (MPLIST_PLIST_P (plist))
2600 MPlist *pl = MPLIST_PLIST (plist);
2603 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2606 else if (! MPLIST_MTEXT_P (plist))
2614 /* Input method variable handler. */
2616 /* Check if PLIST has this form:
2617 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2620 If the form of PLIST matches, return 0, otherwise return -1. */
2623 check_variable_list (MPlist *plist)
2625 MSymbol type = MPLIST_KEY (plist);
2628 if (type != Minteger && type != Mtext && type != Msymbol)
2630 MPLIST_DO (plist, MPLIST_NEXT (plist))
2632 if (type == Minteger && MPLIST_PLIST_P (plist))
2634 MPLIST_DO (p, MPLIST_PLIST (plist))
2635 if (! MPLIST_INTEGER_P (p))
2638 else if (type != MPLIST_KEY (plist))
2644 /* Support functions for mdebug_dump_im. */
2647 dump_im_map (MPlist *map_list, int indent)
2650 MSymbol key = MPLIST_KEY (map_list);
2651 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2653 prefix = (char *) alloca (indent + 1);
2654 memset (prefix, 32, indent);
2655 prefix[indent] = '\0';
2657 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2658 if (map->map_actions)
2659 mdebug_dump_plist (map->map_actions, indent + 2);
2662 MPLIST_DO (map_list, map->submaps)
2664 fprintf (stderr, "\n%s ", prefix);
2665 dump_im_map (map_list, indent + 2);
2668 if (map->branch_actions)
2670 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2671 mdebug_dump_plist (map->branch_actions, indent + 4);
2672 fprintf (stderr, ")");
2674 fprintf (stderr, ")");
2679 dump_im_state (MIMState *state, int indent)
2684 prefix = (char *) alloca (indent + 1);
2685 memset (prefix, 32, indent);
2686 prefix[indent] = '\0';
2688 fprintf (stderr, "(%s", msymbol_name (state->name));
2689 if (state->map->submaps)
2691 MPLIST_DO (map_list, state->map->submaps)
2693 fprintf (stderr, "\n%s ", prefix);
2694 dump_im_map (map_list, indent + 2);
2697 fprintf (stderr, ")");
2706 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2707 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2708 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2709 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2710 char buf[6], buf2[256];
2714 Minput_method = msymbol ("input-method");
2715 Minput_driver = msymbol ("input-driver");
2716 Mtitle = msymbol ("title");
2717 Mmacro = msymbol ("macro");
2718 Mmodule = msymbol ("module");
2719 Mmap = msymbol ("map");
2720 Mstate = msymbol ("state");
2721 Minclude = msymbol ("include");
2722 Minsert = msymbol ("insert");
2723 M_candidates = msymbol (" candidates");
2724 Mdelete = msymbol ("delete");
2725 Mmove = msymbol ("move");
2726 Mmark = msymbol ("mark");
2727 Mpushback = msymbol ("pushback");
2728 Mundo = msymbol ("undo");
2729 Mcall = msymbol ("call");
2730 Mshift = msymbol ("shift");
2731 Mselect = msymbol ("select");
2732 Mshow = msymbol ("show");
2733 Mhide = msymbol ("hide");
2734 Mcommit = msymbol ("commit");
2735 Munhandle = msymbol ("unhandle");
2736 Mset = msymbol ("set");
2737 Madd = msymbol ("add");
2738 Msub = msymbol ("sub");
2739 Mmul = msymbol ("mul");
2740 Mdiv = msymbol ("div");
2741 Mequal = msymbol ("=");
2742 Mless = msymbol ("<");
2743 Mgreater = msymbol (">");
2745 Mcandidates_group_size = msymbol ("candidates-group-size");
2746 Mcandidates_charset = msymbol ("candidates-charset");
2748 Minput_preedit_start = msymbol ("input-preedit-start");
2749 Minput_preedit_done = msymbol ("input-preedit-done");
2750 Minput_preedit_draw = msymbol ("input-preedit-draw");
2751 Minput_status_start = msymbol ("input-status-start");
2752 Minput_status_done = msymbol ("input-status-done");
2753 Minput_status_draw = msymbol ("input-status-draw");
2754 Minput_candidates_start = msymbol ("input-candidates-start");
2755 Minput_candidates_done = msymbol ("input-candidates-done");
2756 Minput_candidates_draw = msymbol ("input-candidates-draw");
2757 Minput_set_spot = msymbol ("input-set-spot");
2758 Minput_focus_move = msymbol ("input-focus-move");
2759 Minput_focus_in = msymbol ("input-focus-in");
2760 Minput_focus_out = msymbol ("input-focus-out");
2761 Minput_toggle = msymbol ("input-toggle");
2762 Minput_reset = msymbol ("input-reset");
2764 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2765 Mcandidate_index = msymbol (" candidate-index");
2767 Minit = msymbol ("init");
2768 Mfini = msymbol ("fini");
2770 M_key_alias = msymbol (" key-alias");
2771 M_description = msymbol ("description");
2772 M_command = msymbol ("command");
2773 M_variable = msymbol ("variable");
2775 load_im_info_keys = mplist ();
2776 plist = mplist_add (load_im_info_keys, Mstate, Mnil);
2781 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2785 one_char_symbol[i] = msymbol (buf);
2788 alias = msymbol (key_names[i]);
2789 msymbol_put (one_char_symbol[i], M_key_alias, alias);
2792 alias = one_char_symbol[i];
2793 buf[2] += (i == 0) ? -32 : 32;
2794 msymbol_put (alias, M_key_alias, msymbol (buf));
2795 buf[2] -= (i == 0) ? -32 : 32;
2797 for (buf[2] = i; i < 127; i++, buf[2]++)
2798 one_char_symbol[i] = msymbol (buf + 2);
2799 one_char_symbol[i++] = msymbol ("Delete");
2805 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2807 one_char_symbol[i] = msymbol (buf);
2808 if (key_names[i - 128])
2810 strcpy (buf2 + 2, key_names[i - 128]);
2811 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2814 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2815 one_char_symbol[i] = msymbol (buf + 2);
2816 one_char_symbol[i] = msymbol ("M-Delete");
2818 command_list = variable_list = NULL;
2820 minput_default_driver.open_im = open_im;
2821 minput_default_driver.close_im = close_im;
2822 minput_default_driver.create_ic = create_ic;
2823 minput_default_driver.destroy_ic = destroy_ic;
2824 minput_default_driver.filter = filter;
2825 minput_default_driver.lookup = lookup;
2826 minput_default_driver.callback_list = mplist ();
2827 mplist_put (minput_default_driver.callback_list, Minput_reset,
2829 minput_driver = &minput_default_driver;
2838 M17N_OBJECT_UNREF (command_list);
2839 command_list = NULL;
2843 M17N_OBJECT_UNREF (variable_list);
2844 variable_list = NULL;
2847 if (minput_default_driver.callback_list)
2849 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2850 minput_default_driver.callback_list = NULL;
2852 if (minput_driver->callback_list)
2854 M17N_OBJECT_UNREF (minput_driver->callback_list);
2855 minput_driver->callback_list = NULL;
2860 while (! MPLIST_TAIL_P (im_info_list))
2863 mplist_pop (im_info_list);
2864 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
2865 /* Pop (t . im_info) */
2866 mplist_pop (im_info_list);
2868 M17N_OBJECT_UNREF (im_info_list);
2869 im_info_list = NULL;
2872 M17N_OBJECT_UNREF (load_im_info_keys);
2876 minput__callback (MInputContext *ic, MSymbol command)
2878 if (ic->im->driver.callback_list)
2880 MInputCallbackFunc func
2881 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2885 (func) (ic, command);
2890 minput__char_to_key (int c)
2892 if (c < 0 || c >= 0x100)
2895 return one_char_symbol[c];
2899 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2904 /*** @addtogroup m17nInputMethod */
2909 @name Variables: Predefined symbols for callback commands.
2911 These are the predefined symbols that are used as the @c COMMAND
2912 argument of callback functions of an input method driver (see
2913 #MInputDriver::callback_list ). */
2915 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2917 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2918 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2923 MSymbol Minput_preedit_start;
2924 MSymbol Minput_preedit_done;
2925 MSymbol Minput_preedit_draw;
2926 MSymbol Minput_status_start;
2927 MSymbol Minput_status_done;
2928 MSymbol Minput_status_draw;
2929 MSymbol Minput_candidates_start;
2930 MSymbol Minput_candidates_done;
2931 MSymbol Minput_candidates_draw;
2932 MSymbol Minput_set_spot;
2933 MSymbol Minput_toggle;
2934 MSymbol Minput_reset;
2940 @name Variables: Predefined symbols for special input events.
2942 These are the predefined symbols that are used as the @c KEY
2943 argument of minput_filter (). */
2948 MSymbol Minput_focus_out;
2949 MSymbol Minput_focus_in;
2950 MSymbol Minput_focus_move;
2957 @brief The default driver for internal input methods.
2959 The variable #minput_default_driver is the default driver for
2960 internal input methods.
2962 The member MInputDriver::open_im () searches the m17n database for
2963 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2964 $NAME\> and loads it.
2966 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2967 programmers responsibility to set it to a plist of proper callback
2968 functions. Otherwise, no feedback information (e.g. preedit text)
2969 can be shown to users.
2971 The macro M17N_INIT () sets the variable #minput_driver to the
2972 pointer to this driver so that all internal input methods use it.
2974 Therefore, unless @c minput_driver is set differently, the driver
2975 dependent arguments $ARG of the functions whose name begin with
2976 "minput_" are all ignored. */
2979 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2981 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2983 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2984 \< #Minput_method, $LANGUAGE, $NAME\>
2985 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2987 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2988 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2989 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2990 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2992 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2993 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2995 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2996 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2998 MInputDriver minput_default_driver;
3002 @brief The driver for internal input methods.
3004 The variable #minput_driver is a pointer to the input method
3005 driver that is used by internal input methods. The macro
3006 M17N_INIT () initializes it to a pointer to #minput_default_driver
3007 if <m17n<EM></EM>.h> is included. */
3009 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
3011 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
3012 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
3013 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
3014 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
3016 MInputDriver *minput_driver;
3018 MSymbol Minput_driver;
3023 @brief Open an input method.
3025 The minput_open_im () function opens an input method that matches
3026 language $LANGUAGE and name $NAME, and returns a pointer to the
3027 input method object newly allocated.
3029 This function at first decides an driver for the input method as
3032 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3033 #minput_driver is used.
3035 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
3036 driver pointed to by the property value is used to open the input
3037 method. If $NAME has no such property, @c NULL is returned.
3039 Then, the member MInputDriver::open_im () of the driver is
3042 $ARG is set in the member @c arg of the structure MInputMethod so
3043 that the driver can refer to it. */
3046 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3048 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3049 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3051 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3053 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3054 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3056 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3057 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3058 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3060 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3062 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3064 @latexonly \IPAlabel{minput_open} @endlatexonly
3069 minput_open_im (MSymbol language, MSymbol name, void *arg)
3072 MInputDriver *driver;
3074 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3075 msymbol_name (language), msymbol_name (name));
3077 driver = minput_driver;
3080 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3082 MERROR (MERROR_IM, NULL);
3085 MSTRUCT_CALLOC (im, MERROR_IM);
3086 im->language = language;
3089 im->driver = *driver;
3090 if ((*im->driver.open_im) (im) < 0)
3092 MDEBUG_PRINT (" failed\n");
3096 MDEBUG_PRINT (" ok\n");
3103 @brief Close an input method.
3105 The minput_close_im () function closes the input method $IM, which
3106 must have been created by minput_open_im (). */
3109 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3111 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3112 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3115 minput_close_im (MInputMethod *im)
3117 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3118 msymbol_name (im->name), msymbol_name (im->language));
3119 (*im->driver.close_im) (im);
3121 MDEBUG_PRINT (" done\n");
3127 @brief Create an input context.
3129 The minput_create_ic () function creates an input context object
3130 associated with input method $IM, and calls callback functions
3131 corresponding to #Minput_preedit_start, #Minput_status_start, and
3132 #Minput_status_draw in this order.
3136 If an input context is successfully created, minput_create_ic ()
3137 returns a pointer to it. Otherwise it returns @c NULL. */
3140 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3142 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3143 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3144 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3145 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3149 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3150 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3154 minput_create_ic (MInputMethod *im, void *arg)
3158 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3159 msymbol_name (im->name), msymbol_name (im->language));
3160 MSTRUCT_CALLOC (ic, MERROR_IM);
3163 ic->preedit = mtext ();
3164 ic->candidate_list = NULL;
3165 ic->produced = mtext ();
3166 ic->spot.x = ic->spot.y = 0;
3168 ic->plist = mplist ();
3169 if ((*im->driver.create_ic) (ic) < 0)
3171 MDEBUG_PRINT (" failed\n");
3172 M17N_OBJECT_UNREF (ic->preedit);
3173 M17N_OBJECT_UNREF (ic->produced);
3174 M17N_OBJECT_UNREF (ic->plist);
3179 if (im->driver.callback_list)
3181 minput__callback (ic, Minput_preedit_start);
3182 minput__callback (ic, Minput_status_start);
3183 minput__callback (ic, Minput_status_draw);
3186 MDEBUG_PRINT (" ok\n");
3193 @brief Destroy an input context.
3195 The minput_destroy_ic () function destroys the input context $IC,
3196 which must have been created by minput_create_ic (). It calls
3197 callback functions corresponding to #Minput_preedit_done,
3198 #Minput_status_done, and #Minput_candidates_done in this order. */
3201 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3203 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3204 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3205 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3206 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3207 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3211 minput_destroy_ic (MInputContext *ic)
3213 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3214 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3215 if (ic->im->driver.callback_list)
3217 minput__callback (ic, Minput_preedit_done);
3218 minput__callback (ic, Minput_status_done);
3219 minput__callback (ic, Minput_candidates_done);
3221 (*ic->im->driver.destroy_ic) (ic);
3222 M17N_OBJECT_UNREF (ic->preedit);
3223 M17N_OBJECT_UNREF (ic->produced);
3224 M17N_OBJECT_UNREF (ic->plist);
3225 MDEBUG_PRINT (" done\n");
3232 @brief Filter an input key.
3234 The minput_filter () function filters input key $KEY according to
3235 input context $IC, and calls callback functions corresponding to
3236 #Minput_preedit_draw, #Minput_status_draw, and
3237 #Minput_candidates_draw if the preedit text, the status, and the
3238 current candidate are changed respectively.
3240 To make the input method commit the current preedit text (if any)
3241 and shift to the initial state, call this function with #Mnil as
3244 To inform the input method about the focus-out event, call this
3245 function with #Minput_focus_out as $KEY.
3247 To inform the input method about the focus-in event, call this
3248 function with #Minput_focus_in as $KEY.
3250 To inform the input method about the focus-move event (i.e. input
3251 spot change within the same input context), call this function
3252 with #Minput_focus_move as $KEY.
3255 If $KEY is filtered out, this function returns 1. In that case,
3256 the caller should discard the key. Otherwise, it returns 0, and
3257 the caller should handle the key, for instance, by calling the
3258 function minput_lookup () with the same key. */
3261 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3263 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3264 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3265 #Minput_preedit_draw, #Minput_status_draw,
3266 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3269 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3270 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3271 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3272 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3274 @latexonly \IPAlabel{minput_filter} @endlatexonly
3278 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3285 ret = (*ic->im->driver.filter) (ic, key, arg);
3287 if (ic->im->driver.callback_list)
3289 if (ic->preedit_changed)
3290 minput__callback (ic, Minput_preedit_draw);
3291 if (ic->status_changed)
3292 minput__callback (ic, Minput_status_draw);
3293 if (ic->candidates_changed)
3294 minput__callback (ic, Minput_candidates_draw);
3303 @brief Look up a text produced in the input context.
3305 The minput_lookup () function looks up a text in the input context
3306 $IC. $KEY must be the same one provided to the previous call of
3309 If a text was produced by the input method, it is concatenated
3312 This function calls #MInputDriver::lookup .
3315 If $KEY was correctly handled by the input method, this function
3316 returns 0. Otherwise, returns -1, even in that case, some text
3317 may be produced in $MT. */
3320 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3322 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3323 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3325 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3328 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3331 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3332 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3333 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3335 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3338 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3340 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3345 @brief Set the spot of the input context.
3347 The minput_set_spot () function set the spot of input context $IC
3348 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3349 The semantics of these values depend on the input method driver.
3351 For instance, a driver designed to work in a CUI environment may
3352 use $X and $Y as column and row numbers, and ignore $ASCENT and
3353 $DESCENT . A driver designed to work in a window system may
3354 interpret $X and $Y as pixel offsets relative to the origin of the
3355 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3356 descent pixels of the line at ($X . $Y ).
3358 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3360 $MT and $POS is the M-text and the character position at the spot.
3361 $MT may be @c NULL, in which case, the input method cannot get
3362 information about the text around the spot. */
3365 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3367 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3368 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3369 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3371 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3372 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3373 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3374 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3375 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3376 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3378 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3380 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3381 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3385 minput_set_spot (MInputContext *ic, int x, int y,
3386 int ascent, int descent, int fontsize,
3391 ic->spot.ascent = ascent;
3392 ic->spot.descent = descent;
3393 ic->spot.fontsize = fontsize;
3396 if (ic->im->driver.callback_list)
3397 minput__callback (ic, Minput_set_spot);
3402 @brief Toggle input method.
3404 The minput_toggle () function toggles the input method associated
3405 with input context $IC. */
3407 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3409 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3410 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3414 minput_toggle (MInputContext *ic)
3416 if (ic->im->driver.callback_list)
3417 minput__callback (ic, Minput_toggle);
3418 ic->active = ! ic->active;
3422 @brief Reset an input context.
3424 The minput_reset_ic () function resets input context $IC by
3425 calling a callback function corresponding to #Minput_reset. It
3426 resets the status of $IC to the one of just after created. As the
3427 current preedit text is deleted without commitment, if necessary,
3428 call minput_filter () with the arg @r key #Mnil to force the input
3429 method to commit the preedit in advance. */
3432 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3434 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3435 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3436 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3437 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3438 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3439 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3442 minput_reset_ic (MInputContext *ic)
3444 if (ic->im->driver.callback_list)
3445 minput__callback (ic, Minput_reset);
3449 @brief Get description text of an input method.
3451 The minput_get_description () function returns an M-text that
3452 describes the input method specified by $LANGUAGE and $NAME.
3455 If the specified input method has a description text, a pointer to
3456 #MText is returned. A caller have to free it by m17n_object_unref ().
3457 If the input method does not have a description text, @c NULL is
3460 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3462 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3463 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3465 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3466 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3467 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3468 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3471 minput_get_description (MSymbol language, MSymbol name)
3473 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3479 pl = MPLIST_PLIST (plist);
3480 pl = MPLIST_NEXT (pl);
3481 if (MPLIST_MTEXT_P (pl))
3483 mt = MPLIST_MTEXT (pl);
3484 M17N_OBJECT_REF (mt);
3486 M17N_OBJECT_UNREF (plist);
3491 @brief Get information about input method commands.
3493 The minput_get_commands () function returns information about
3494 input method commands of the input method specified by $LANGUAGE
3495 and $NAME. An input method command is a pseudo key event to which
3496 one or more actual input key sequences are assigned.
3498 There are two kinds of commands, global and local. Global
3499 commands are used by multiple input methods for the same purpose,
3500 and have global key assignments. Local commands are used only in
3501 a specific input method, and have only local key assignments.
3503 Each input method may locally change key assignments for global
3504 commands. A global key assignment for a global command are
3505 effective only when the current input method does not have local
3506 key assignments for that command.
3508 If $NAME is #Mnil, information about global commands is returned.
3509 In this case $LANGUAGE is ignored.
3511 If $NAME is not #Mnil, information about those commands that have
3512 local key assignments in the input method specified by $LANGUAGE
3513 and $NAME is returned.
3516 If no input method commands are found, this function returns @c NULL.
3518 Otherwise, a pointer to a plist is returned. The key of each
3519 element in the plist is a symbol representing a command, and the
3520 value is a plist of the form COMMAND-INFO described below.
3522 The first element of COMMAND-INFO has the key #Mtext, and the
3523 value is an M-text describing the command.
3525 If there are no more elements, that means no key sequences are
3526 assigned to the command. Otherwise, each of the remaining
3527 elements has the key #Mplist, and the value is a plist whose keys are
3528 #Msymbol and values are symbols representing input keys, which are
3529 currently assigned to the command.
3531 As the returned plist is kept in the library, the caller must not
3532 modify nor free it. */
3534 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3536 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3537 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3538 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3539 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3541 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3542 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3543 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3544 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3546 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3547 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3548 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3551 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3552 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3554 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3555 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3559 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3561 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3562 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3563 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3565 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3566 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3567 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3570 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3571 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3572 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3573 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3574 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3576 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3577 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3580 minput_get_commands (MSymbol language, MSymbol name)
3582 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
3584 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3588 @brief Assign a key sequence to an input method command.
3590 The minput_assign_command_keys () function assigns input key
3591 sequence $KEYSEQ to input method command $COMMAND for the input
3592 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3593 key sequence is assigned globally no matter what $LANGUAGE is.
3594 Otherwise the key sequence is assigned locally.
3596 Each element of $KEYSEQ must have the key $Msymbol and the value
3597 must be a symbol representing an input key.
3599 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3600 globally or locally.
3602 This assignment gets effective in a newly opened input method.
3605 If the operation was successful, 0 is returned. Otherwise -1 is
3606 returned, and #merror_code is set to #MERROR_IM. */
3608 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3610 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
3611 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
3612 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
3613 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
3614 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3616 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
3617 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3619 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
3620 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3622 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
3625 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3626 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3629 minput_assign_command_keys (MSymbol language, MSymbol name,
3630 MSymbol command, MPlist *keyseq)
3632 MPlist *plist, *pl, *p;
3634 if (check_command_keyseq (keyseq) < 0
3635 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
3636 MERROR (MERROR_IM, -1);
3637 pl = mplist_get (plist, command);
3640 pl = MPLIST_NEXT (pl);
3642 while ((p = mplist_pop (pl)))
3643 M17N_OBJECT_UNREF (p);
3646 keyseq = mplist_copy (keyseq);
3647 mplist_push (pl, Mplist, keyseq);
3648 M17N_OBJECT_UNREF (keyseq);
3654 MERROR (MERROR_IM, -1);
3657 /* Get global commands. */
3658 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
3659 pl = mplist_get (pl, command);
3661 MERROR (MERROR_IM, -1);
3663 mplist_add (p, Mtext, mplist_value (pl));
3664 keyseq = mplist_copy (keyseq);
3665 mplist_add (p, Mplist, keyseq);
3666 M17N_OBJECT_UNREF (keyseq);
3667 mplist_push (plist, command, p);
3673 @brief Get a list of variables of an input method.
3675 The minput_get_variables () function returns a plist (#MPlist) of
3676 variables used to control the behavior of the input method
3677 specified by $LANGUAGE and $NAME. The key of an element of the
3678 plist is a symbol representing a variable, and the value is a
3679 plist of the form VAR-INFO (described below) that carries the
3680 information about the variable.
3682 The first element of VAR-INFO has the key #Mtext or #Msymbol. If
3683 the key is #Mtext, the value is an M-text describing the variable.
3684 If the key is #Msymbol, that value is #Mnil which means the
3685 variable has no description text.
3687 The second element of VAR-INFO is for the value of the variable.
3688 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3689 integer, a symbol, or an M-text, respectively. The variable is
3690 set to this value when an input context is created for the input
3693 If there are no more elements, the variable can take any value
3694 that matches with the above type. Otherwise, the remaining
3695 elements of VAR-INFO are to specify valid values of the variable.
3697 If the type of the variable is integer, the following elements
3698 have the key #Minteger or #Mplist. If it is #Minteger, the value
3699 is a valid integer value. If it is #Mplist, the value is a plist
3700 of two of elements. Both of them have the key #Minteger, and
3701 values are the minimum and maximum bounds of the valid value
3704 If the type of the variable is symbol or M-text, the following
3705 elements of the plist have the key #Msymbol or #Mtext,
3706 respectively, and the value must be a valid one.
3708 For instance, suppose an input method has the variables:
3710 @li name:intvar, description:"value is an integer",
3711 initial value:0, value-range:0..3,10,20
3713 @li name:symvar, description:"value is a symbol",
3714 initial value:nil, value-range:a, b, c, nil
3716 @li name:txtvar, description:"value is an M-text",
3717 initial value:empty text, no value-range (i.e. any text)
3719 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3720 a value, and '(...)' means a plist):
3723 plist:(intvar:(mtext:"value is an integer"
3725 plist:(integer:0 integer:3)
3728 symvar:(mtext:"value is a symbol"
3734 txtvar:(mtext:"value is an M-text"
3739 If the input method uses any variables, a pointer to #MPlist is
3740 returned. As the plist is kept in the library, a caller must not
3741 modify nor free it. If the input method does not use any
3742 variable, @c NULL is returned. */
3744 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3746 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3747 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3748 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3749 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3750 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3752 VAR-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼¤¬
3753 #Mtext ¤Ê¤é¡¢ÃͤϤ½¤ÎÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬ #Msymbol
3754 ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤ÎÊÑ¿ô¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê¤¤¤³¤È¤Ë¤Ê¤ë¡£
3756 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3757 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3758 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3760 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3761 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3763 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3764 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3765 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3766 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3768 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3769 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3771 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3773 @li name:intvar, ÀâÌÀ:"value is an integer",
3774 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3776 @li name:symvar, ÀâÌÀ:"value is a symbol",
3777 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3779 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3780 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3782 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3783 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3786 plist:(intvar:(mtext:"value is an integer"
3788 plist:(integer:0 integer:3)
3791 symvar:(mtext:"value is a symbol"
3797 txtvar:(mtext:"value is an M-text"
3802 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3803 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3804 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3807 minput_get_variables (MSymbol language, MSymbol name)
3809 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
3811 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3815 @brief Set the initial value of an input method variable.
3817 The minput_set_variable () function sets the initial value of
3818 input method variable $VARIABLE to $VALUE for the input method
3819 specified by $LANGUAGE and $NAME.
3821 By default, the initial value is 0.
3823 This setting gets effective in a newly opened input method.
3826 If the operation was successful, 0 is returned. Otherwise -1 is
3827 returned, and #merror_code is set to #MERROR_IM. */
3829 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3831 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3832 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3833 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3835 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3837 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3840 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3841 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3844 minput_set_variable (MSymbol language, MSymbol name,
3845 MSymbol variable, void *value)
3847 MPlist *plist, *val_element, *range_element;
3850 if (language == Mnil || name == Mnil)
3851 MERROR (MERROR_IM, -1);
3852 plist = get_nested_list (language, name, Mnil, M_variable);
3854 MERROR (MERROR_IM, -1);
3855 plist = (MPlist *) mplist_get (plist, variable);
3857 MERROR (MERROR_IM, -1);
3858 val_element = MPLIST_NEXT (plist);
3859 type = MPLIST_KEY (val_element);
3860 range_element = MPLIST_NEXT (val_element);
3862 if (! MPLIST_TAIL_P (range_element))
3864 if (type == Minteger)
3866 int val = (int) value, this_val;
3868 MPLIST_DO (plist, range_element)
3870 this_val = (int) MPLIST_VAL (plist);
3871 if (MPLIST_PLIST_P (plist))
3873 int min_bound, max_bound;
3874 MPlist *pl = MPLIST_PLIST (plist);
3876 min_bound = (int) MPLIST_VAL (pl);
3877 pl = MPLIST_NEXT (pl);
3878 max_bound = (int) MPLIST_VAL (pl);
3879 if (val >= min_bound && val <= max_bound)
3882 else if (val == this_val)
3885 if (MPLIST_TAIL_P (plist))
3886 MERROR (MERROR_IM, -1);
3888 else if (type == Msymbol)
3890 MPLIST_DO (plist, range_element)
3891 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3893 if (MPLIST_TAIL_P (plist))
3894 MERROR (MERROR_IM, -1);
3896 else /* type == Mtext */
3898 MPLIST_DO (plist, range_element)
3899 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3901 if (MPLIST_TAIL_P (plist))
3902 MERROR (MERROR_IM, -1);
3903 M17N_OBJECT_REF (value);
3907 mplist_set (val_element, type, value);
3913 /*** @addtogroup m17nDebug */
3919 @brief Dump an input method.
3921 The mdebug_dump_im () function prints the input method $IM in a
3922 human readable way to the stderr. $INDENT specifies how many
3923 columns to indent the lines but the first one.
3926 This function returns $IM. */
3928 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3930 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3931 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3934 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3937 mdebug_dump_im (MInputMethod *im, int indent)
3939 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3942 prefix = (char *) alloca (indent + 1);
3943 memset (prefix, 32, indent);
3944 prefix[indent] = '\0';
3946 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3947 msymbol_name (im->name));
3948 mdebug_dump_mtext (im_info->title, 0, 0);
3949 if (im->name != Mnil)
3953 MPLIST_DO (state, im_info->states)
3955 fprintf (stderr, "\n%s ", prefix);
3956 dump_im_state (MPLIST_VAL (state), indent + 2);
3959 fprintf (stderr, ")");