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_PLIST (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);
1588 && (! (plist = adjust_candidates (plist, charset))))
1593 if (MPLIST_MTEXT_P (plist))
1595 MText *mt = MPLIST_MTEXT (plist);
1596 MPlist *next = MPLIST_NEXT (plist);
1598 if (MPLIST_TAIL_P (next))
1599 M17N_OBJECT_REF (mt);
1602 mt = mtext_dup (mt);
1603 while (! MPLIST_TAIL_P (next))
1605 mt = mtext_cat (mt, MPLIST_MTEXT (next));
1606 next = MPLIST_NEXT (next);
1609 M17N_OBJECT_UNREF (plist);
1611 len = mtext_nchars (mt);
1613 mplist_add (plist, Mtext, mt);
1616 for (i = 0; i < len; i += column)
1618 int to = (i + column < len ? i + column : len);
1619 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
1621 mplist_add (plist, Mtext, sub);
1622 M17N_OBJECT_UNREF (sub);
1625 M17N_OBJECT_UNREF (mt);
1627 else /* MPLIST_PLIST_P (plist) */
1629 MPlist *pl = MPLIST_PLIST (plist), *p;
1630 MPlist *next = MPLIST_NEXT (plist);
1633 if (MPLIST_TAIL_P (next))
1634 M17N_OBJECT_REF (pl);
1637 pl = mplist_copy (pl);
1638 while (! MPLIST_TAIL_P (next))
1640 p = mplist_copy (MPLIST_PLIST (next));
1641 pl = mplist__conc (pl, p);
1642 M17N_OBJECT_UNREF (p);
1643 next = MPLIST_NEXT (next);
1646 M17N_OBJECT_UNREF (plist);
1648 len = mplist_length (pl);
1650 mplist_add (plist, Mplist, pl);
1655 for (i = 0; i < len; i += column)
1658 mplist_add (plist, Mplist, p);
1659 M17N_OBJECT_UNREF (p);
1660 for (j = 0; j < column && i + j < len; j++)
1662 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
1663 p0 = MPLIST_NEXT (p0);
1667 M17N_OBJECT_UNREF (pl);
1671 if (plist == MPLIST_PLIST (args))
1672 M17N_OBJECT_REF (plist);
1678 regularize_action (MPlist *action_list)
1680 MPlist *action = NULL;
1684 if (MPLIST_PLIST_P (action_list))
1686 action = MPLIST_PLIST (action_list);
1687 if (MPLIST_SYMBOL_P (action))
1689 name = MPLIST_SYMBOL (action);
1690 args = MPLIST_NEXT (action);
1692 && MPLIST_PLIST_P (args))
1693 mplist_set (action, Msymbol, M_candidates);
1695 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
1698 mplist_push (action, Mplist, MPLIST_VAL (action_list));
1699 mplist_push (action, Msymbol, M_candidates);
1700 mplist_set (action_list, Mplist, action);
1701 M17N_OBJECT_UNREF (action);
1704 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
1707 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
1708 mplist_push (action, Msymbol, Minsert);
1709 mplist_set (action_list, Mplist, action);
1710 M17N_OBJECT_UNREF (action);
1716 take_action_list (MInputContext *ic, MPlist *action_list)
1718 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1719 MPlist *candidate_list = ic->candidate_list;
1720 int candidate_index = ic->candidate_index;
1721 int candidate_show = ic->candidate_show;
1722 MTextProperty *prop;
1724 MPLIST_DO (action_list, action_list)
1726 MPlist *action = regularize_action (action_list);
1732 name = MPLIST_SYMBOL (action);
1733 args = MPLIST_NEXT (action);
1735 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1736 if (name == Minsert)
1738 if (MPLIST_SYMBOL_P (args))
1740 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
1741 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
1744 if (MPLIST_MTEXT_P (args))
1745 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1746 else /* MPLIST_INTEGER_P (args)) */
1747 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1749 else if (name == M_candidates)
1751 MPlist *plist = get_candidate_list (ic_info, args);
1756 if (MPLIST_MTEXT_P (plist))
1758 preedit_insert (ic, ic->cursor_pos, NULL,
1759 mtext_ref_char (MPLIST_MTEXT (plist), 0));
1764 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
1766 preedit_insert (ic, ic->cursor_pos, mt, 0);
1767 len = mtext_nchars (mt);
1769 mtext_put_prop (ic->preedit,
1770 ic->cursor_pos - len, ic->cursor_pos,
1771 Mcandidate_list, plist);
1772 mtext_put_prop (ic->preedit,
1773 ic->cursor_pos - len, ic->cursor_pos,
1774 Mcandidate_index, (void *) 0);
1775 M17N_OBJECT_UNREF (plist);
1777 else if (name == Mselect)
1780 int code, idx, gindex;
1781 int pos = ic->cursor_pos;
1785 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1788 if (MPLIST_SYMBOL_P (args))
1790 code = marker_code (MPLIST_SYMBOL (args));
1796 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1797 group = find_candidates_group (mtext_property_value (prop), idx,
1798 &start, &end, &gindex);
1800 if (code != '[' && code != ']')
1804 ? new_index (NULL, ic->candidate_index - start,
1805 end - start - 1, MPLIST_SYMBOL (args),
1807 : MPLIST_INTEGER (args)));
1810 find_candidates_group (mtext_property_value (prop), -1,
1815 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1820 int ingroup_index = idx - start;
1823 group = mtext_property_value (prop);
1824 len = mplist_length (group);
1837 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1838 idx += (MPLIST_MTEXT_P (group)
1839 ? mtext_nchars (MPLIST_MTEXT (group))
1840 : mplist_length (MPLIST_PLIST (group)));
1841 len = (MPLIST_MTEXT_P (group)
1842 ? mtext_nchars (MPLIST_MTEXT (group))
1843 : mplist_length (MPLIST_PLIST (group)));
1844 if (ingroup_index >= len)
1845 ingroup_index = len - 1;
1846 idx += ingroup_index;
1848 update_candidate (ic, prop, idx);
1850 else if (name == Mshow)
1851 ic->candidate_show = 1;
1852 else if (name == Mhide)
1853 ic->candidate_show = 0;
1854 else if (name == Mdelete)
1856 int len = mtext_nchars (ic->preedit);
1857 int to = (MPLIST_SYMBOL_P (args)
1858 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1860 : MPLIST_INTEGER (args));
1866 if (to < ic->cursor_pos)
1867 preedit_delete (ic, to, ic->cursor_pos);
1868 else if (to > ic->cursor_pos)
1869 preedit_delete (ic, ic->cursor_pos, to);
1871 else if (name == Mmove)
1873 int len = mtext_nchars (ic->preedit);
1875 = (MPLIST_SYMBOL_P (args)
1876 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1878 : MPLIST_INTEGER (args));
1884 if (pos != ic->cursor_pos)
1886 ic->cursor_pos = pos;
1887 ic->preedit_changed = 1;
1890 else if (name == Mmark)
1892 int code = marker_code (MPLIST_SYMBOL (args));
1895 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
1896 (void *) ic->cursor_pos);
1898 else if (name == Mpushback)
1900 if (MPLIST_INTEGER_P (args))
1902 int num = MPLIST_INTEGER (args);
1905 ic_info->key_head -= num;
1907 ic_info->key_head = num;
1908 if (ic_info->key_head > ic_info->used)
1909 ic_info->key_head = ic_info->used;
1911 else if (MPLIST_MTEXT_P (args))
1913 MText *mt = MPLIST_MTEXT (args);
1914 int i, len = mtext_nchars (mt);
1917 ic_info->key_head--;
1918 for (i = 0; i < len; i++)
1920 key = one_char_symbol[MTEXT_DATA (mt)[i]];
1921 if (ic_info->key_head + i < ic_info->used)
1922 ic_info->keys[ic_info->key_head + i] = key;
1924 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1929 MPlist *plist = MPLIST_PLIST (args), *pl;
1933 ic_info->key_head--;
1935 MPLIST_DO (pl, plist)
1937 key = MPLIST_SYMBOL (pl);
1938 if (ic_info->key_head < ic_info->used)
1939 ic_info->keys[ic_info->key_head + i] = key;
1941 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
1946 else if (name == Mcall)
1948 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1949 MIMExternalFunc func = NULL;
1950 MSymbol module, func_name;
1951 MPlist *func_args, *val;
1954 module = MPLIST_SYMBOL (args);
1955 args = MPLIST_NEXT (args);
1956 func_name = MPLIST_SYMBOL (args);
1958 if (im_info->externals)
1960 MIMExternalModule *external
1961 = (MIMExternalModule *) mplist_get (im_info->externals,
1964 func = (MIMExternalFunc) mplist_get (external->func_list,
1969 func_args = mplist ();
1970 mplist_add (func_args, Mt, ic);
1971 MPLIST_DO (args, MPLIST_NEXT (args))
1975 if (MPLIST_KEY (args) == Msymbol
1976 && MPLIST_KEY (args) != Mnil
1977 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
1979 code = new_index (ic, ic->cursor_pos,
1980 mtext_nchars (ic->preedit),
1981 MPLIST_SYMBOL (args), ic->preedit);
1982 mplist_add (func_args, Minteger, (void *) code);
1985 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
1987 val = (func) (func_args);
1988 M17N_OBJECT_UNREF (func_args);
1989 if (val && ! MPLIST_TAIL_P (val))
1990 ret = take_action_list (ic, val);
1991 M17N_OBJECT_UNREF (val);
1995 else if (name == Mshift)
1997 shift_state (ic, MPLIST_SYMBOL (args));
1999 else if (name == Mundo)
2001 int intarg = (MPLIST_TAIL_P (args)
2002 ? ic_info->used - 2 : integer_value (ic, args, NULL));
2004 mtext_reset (ic->preedit);
2005 mtext_reset (ic_info->preedit_saved);
2006 ic->cursor_pos = ic_info->state_pos = 0;
2007 ic_info->state_key_head = ic_info->key_head = 0;
2010 ic_info->used += intarg;
2012 ic_info->used = intarg;
2013 shift_state (ic, Mnil);
2016 else if (name == Mset || name == Madd || name == Msub
2017 || name == Mmul || name == Mdiv)
2019 MSymbol sym = MPLIST_SYMBOL (args);
2024 val1 = integer_value (ic, args, &value);
2025 args = MPLIST_NEXT (args);
2026 val2 = integer_value (ic, args, NULL);
2028 val1 = val2, op = "=";
2029 else if (name == Madd)
2030 val1 += val2, op = "+=";
2031 else if (name == Msub)
2032 val1 -= val2, op = "-=";
2033 else if (name == Mmul)
2034 val1 *= val2, op = "*=";
2036 val1 /= val2, op = "/=";
2037 mplist_set (value, Minteger, (void *) val1);
2038 MDEBUG_PRINT3 ("(%s %s %d)", MSYMBOL_NAME (sym), op, val1);
2040 else if (name == Mequal || name == Mless || name == Mgreater)
2043 MPlist *actions1, *actions2;
2046 val1 = integer_value (ic, args, NULL);
2047 args = MPLIST_NEXT (args);
2048 val2 = integer_value (ic, args, NULL);
2049 args = MPLIST_NEXT (args);
2050 actions1 = MPLIST_PLIST (args);
2051 args = MPLIST_NEXT (args);
2052 if (MPLIST_TAIL_P (args))
2055 actions2 = MPLIST_PLIST (args);
2056 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
2057 if (name == Mequal ? val1 == val2
2058 : name == Mless ? val1 < val2
2061 MDEBUG_PRINT ("ok");
2062 ret = take_action_list (ic, actions1);
2066 MDEBUG_PRINT ("no");
2068 ret = take_action_list (ic, actions2);
2073 else if (name == Mcommit)
2075 preedit_commit (ic);
2077 else if (name == Munhandle)
2079 preedit_commit (ic);
2084 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2088 && (actions = mplist_get (im_info->macros, name)))
2090 if (take_action_list (ic, actions) < 0)
2097 if (ic->candidate_list)
2099 M17N_OBJECT_UNREF (ic->candidate_list);
2100 ic->candidate_list = NULL;
2102 if (ic->cursor_pos > 0
2103 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
2106 ic->candidate_list = mtext_property_value (prop);
2107 M17N_OBJECT_REF (ic->candidate_list);
2109 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
2111 ic->candidate_from = mtext_property_start (prop);
2112 ic->candidate_to = mtext_property_end (prop);
2115 ic->candidates_changed |= (candidate_list != ic->candidate_list
2116 || candidate_index != ic->candidate_index
2117 || candidate_show != ic->candidate_show);
2122 /* Handle the input key KEY in the current state and map specified in
2123 the input context IC. If KEY is handled correctly, return 0.
2124 Otherwise, return -1. */
2127 handle_key (MInputContext *ic)
2129 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2130 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2131 MIMMap *map = ic_info->map;
2132 MIMMap *submap = NULL;
2133 MSymbol key = ic_info->keys[ic_info->key_head];
2136 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
2137 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
2143 submap = mplist_get (map->submaps, key);
2144 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
2145 submap = mplist_get (map->submaps, alias);
2150 MDEBUG_PRINT (" submap-found");
2151 mtext_cpy (ic->preedit, ic_info->preedit_saved);
2152 ic->preedit_changed = 1;
2153 ic->cursor_pos = ic_info->state_pos;
2154 ic_info->key_head++;
2155 ic_info->map = map = submap;
2156 if (map->map_actions)
2158 MDEBUG_PRINT (" map-actions:");
2159 if (take_action_list (ic, map->map_actions) < 0)
2161 MDEBUG_PRINT ("\n");
2165 else if (map->submaps)
2167 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
2169 MSymbol key = ic_info->keys[i];
2170 char *name = msymbol_name (key);
2172 if (! name[0] || ! name[1])
2173 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
2177 /* If this is the terminal map or we have shifted to another
2178 state, perform branch actions (if any). */
2179 if (! map->submaps || map != ic_info->map)
2181 if (map->branch_actions)
2183 MDEBUG_PRINT (" branch-actions:");
2184 if (take_action_list (ic, map->branch_actions) < 0)
2186 MDEBUG_PRINT ("\n");
2190 /* If MAP is still not the root map, shift to the current
2192 if (ic_info->map != ic_info->state->map)
2193 shift_state (ic, ic_info->state->name);
2198 /* MAP can not handle KEY. */
2200 /* If MAP is the root map of the initial state, it means that
2201 the current input method can not handle KEY. */
2202 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
2204 MDEBUG_PRINT (" unhandled\n");
2208 if (map != ic_info->state->map)
2210 /* If MAP is not the root map... */
2211 /* If MAP has branch actions, perform them. */
2212 if (map->branch_actions)
2214 MDEBUG_PRINT (" branch-actions:");
2215 if (take_action_list (ic, map->branch_actions) < 0)
2217 MDEBUG_PRINT ("\n");
2221 /* If MAP is still not the root map, shift to the current
2223 if (ic_info->map != ic_info->state->map)
2225 shift_state (ic, ic_info->state->name);
2226 /* If MAP has branch_actions, perform them. */
2227 if (ic_info->map->branch_actions)
2229 MDEBUG_PRINT (" brank-actions:");
2230 take_action_list (ic, ic_info->map->branch_actions);
2236 /* MAP is the root map, perform branch actions (if any) or
2237 shift to the initial state. */
2238 if (map->branch_actions)
2240 MDEBUG_PRINT (" branch-actions:");
2241 if (take_action_list (ic, map->branch_actions) < 0)
2243 MDEBUG_PRINT ("\n");
2248 shift_state (ic, Mnil);
2251 MDEBUG_PRINT ("\n");
2256 reset_ic (MInputContext *ic, MSymbol ignore)
2258 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2259 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2262 MDEBUG_PRINT ("\n [IM] reset\n");
2264 ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
2265 ic_info->prev_state = NULL;
2266 ic_info->map = ic_info->state->map;
2267 ic_info->state_key_head = ic_info->key_head;
2268 MLIST_RESET (ic_info);
2269 ic_info->key_unhandled = 0;
2271 if (mtext_nchars (ic->produced) > 0)
2272 mtext_reset (ic->produced);
2273 if (mtext_nchars (ic->preedit) > 0)
2277 mtext_reset (ic->preedit);
2278 MPLIST_DO (plist, ic_info->markers)
2279 MPLIST_VAL (plist) = 0;
2280 ic->preedit_changed = 1;
2282 if (ic->candidate_show)
2284 ic->candidate_show = 0;
2285 if (ic->candidate_list)
2287 M17N_OBJECT_UNREF (ic->candidate_list);
2288 ic->candidate_list = NULL;
2289 ic->candidates_changed = 1;
2292 mtext_reset (ic_info->preedit_saved);
2293 ic_info->state_pos = ic->cursor_pos = 0;
2295 status = ic_info->state->title ? ic_info->state->title : im_info->title;
2296 if (ic->status != status)
2298 ic->status = status;
2299 ic->status_changed = 1;
2304 open_im (MInputMethod *im)
2306 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil);
2309 MERROR (MERROR_IM, -1);
2316 close_im (MInputMethod *im)
2322 create_ic (MInputContext *ic)
2324 MInputMethod *im = ic->im;
2325 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
2326 MInputContextInfo *ic_info;
2330 ic_info = (MInputContextInfo *) ic->info;
2333 MSTRUCT_CALLOC (ic_info, MERROR_IM);
2336 MLIST_INIT1 (ic_info, keys, 8);
2337 ic_info->markers = mplist ();
2338 ic_info->vars = mplist ();
2339 plist = get_nested_list (im->language, im->name, Mnil, M_variable);
2340 MPLIST_DO (plist, plist)
2342 MSymbol var = MPLIST_SYMBOL (plist);
2345 plist = MPLIST_NEXT (plist);
2346 pl = MPLIST_PLIST (plist);
2347 pl = MPLIST_NEXT (pl); /* Skip description. */
2348 mplist_push (ic_info->vars, MPLIST_KEY (pl), MPLIST_VAL (pl));
2349 mplist_push (ic_info->vars, Msymbol, var);
2351 plist = resolve_variable (ic_info, Mcandidates_group_size);
2352 if (! MPLIST_INTEGER_P (plist))
2353 mplist_set (plist, Minteger, (void *) 10);
2354 plist = resolve_variable (ic_info, Mcandidates_charset);
2356 ic_info->preedit_saved = mtext ();
2357 if (im_info->externals)
2359 MPlist *func_args = mplist (), *plist;
2361 mplist_add (func_args, Mt, ic);
2362 MPLIST_DO (plist, im_info->externals)
2364 MIMExternalModule *external = MPLIST_VAL (plist);
2365 MIMExternalFunc func
2366 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
2371 M17N_OBJECT_UNREF (func_args);
2373 reset_ic (ic, Mnil);
2378 destroy_ic (MInputContext *ic)
2380 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2381 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2383 if (im_info->externals)
2385 MPlist *func_args = mplist (), *plist;
2387 mplist_add (func_args, Mt, ic);
2388 MPLIST_DO (plist, im_info->externals)
2390 MIMExternalModule *external = MPLIST_VAL (plist);
2391 MIMExternalFunc func
2392 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
2397 M17N_OBJECT_UNREF (func_args);
2399 MLIST_FREE1 (ic_info, keys);
2400 M17N_OBJECT_UNREF (ic_info->preedit_saved);
2401 M17N_OBJECT_UNREF (ic_info->markers);
2402 M17N_OBJECT_UNREF (ic_info->vars);
2407 /** Handle the input key KEY in the current state and map of IC->info.
2408 If KEY is handled but no text is produced, return 0, otherwise
2414 filter (MInputContext *ic, MSymbol key, void *arg)
2416 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2417 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2420 if (! ic_info->state)
2422 ic_info->key_unhandled = 1;
2425 mtext_reset (ic->produced);
2426 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
2427 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2428 ic_info->key_unhandled = 0;
2430 if (handle_key (ic) < 0)
2432 /* KEY was not handled. Delete it from the current key sequence. */
2433 if (ic_info->used > 0)
2435 memmove (ic_info->keys, ic_info->keys + 1,
2436 sizeof (int) * (ic_info->used - 1));
2439 /* This forces returning 1. */
2440 ic_info->key_unhandled = 1;
2446 reset_ic (ic, Mnil);
2447 ic_info->key_unhandled = 1;
2450 /* Break the loop if all keys were handled. */
2451 } while (ic_info->key_head < ic_info->used);
2453 /* If the current map is the root of the initial state, we should
2454 produce any preedit text in ic->produced. */
2455 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2456 && mtext_nchars (ic->preedit) > 0)
2457 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2459 if (mtext_nchars (ic->produced) > 0)
2461 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2464 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2465 Mlanguage, ic->im->language);
2468 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2472 /** Return 1 if the last event or key was not handled, otherwise
2475 There is no need of looking up because ic->produced should already
2476 contain the produced text (if any).
2481 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2483 mtext_cat (mt, ic->produced);
2484 mtext_reset (ic->produced);
2485 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2488 static MPlist *load_im_info_keys;
2491 load_partial_im_info (MSymbol language, MSymbol name,
2492 MSymbol extra, MSymbol key)
2497 if (language == Mnil || name == Mnil)
2498 MERROR (MERROR_IM, NULL);
2499 mdb = mdatabase_find (Minput_method, language, name, Mnil);
2501 MERROR (MERROR_IM, NULL);
2503 mplist_push (load_im_info_keys, key, Mt);
2504 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2505 mplist_pop (load_im_info_keys);
2510 static MInputMethodInfo *
2511 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2515 MInputMethodInfo *im_info = NULL;
2517 if (language == Mnil)
2518 MERROR (MERROR_IM, NULL);
2519 mdb = mdatabase_find (Minput_method, language, name, extra);
2521 MERROR (MERROR_IM, NULL);
2524 im_info_list = mplist ();
2525 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2527 if (mdatabase__check (mdb))
2529 plist = MPLIST_NEXT (plist);
2530 im_info = MPLIST_VAL (plist);
2534 free_im_info (MPLIST_VAL (plist));
2538 plist = mdatabase_load (mdb);
2540 MERROR (MERROR_IM, NULL);
2541 im_info = load_im_info (language, name, plist);
2542 M17N_OBJECT_UNREF (plist);
2544 MERROR (MERROR_IM, NULL);
2545 mplist_push (im_info_list, Mt, im_info);
2546 mplist_push (im_info_list, Mt, mdb);
2551 /* Input method command handler. */
2553 /* List of all (global and local) commands.
2554 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2555 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2556 Global commands are storead as (t (t COMMAND ...)) */
2558 /* Check if PLIST is a valid command key sequence.
2559 PLIST must be NULL or:
2560 [ symbol:KEY | integer:KEY ] ... */
2563 check_command_keyseq (MPlist *plist)
2567 MPLIST_DO (plist, plist)
2569 if (MPLIST_SYMBOL_P (plist))
2571 else if (MPLIST_INTEGER_P (plist))
2573 int n = MPLIST_INTEGER (plist);
2577 MPLIST_KEY (plist) = Msymbol;
2578 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2586 /* Check if PLIST has this form:
2587 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2589 If the form of PLIST matches, return 0, otherwise return -1. */
2592 check_command_list (MPlist *plist)
2594 MPLIST_DO (plist, plist)
2596 if (MPLIST_PLIST_P (plist))
2598 MPlist *pl = MPLIST_PLIST (plist);
2601 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2604 else if (! MPLIST_MTEXT_P (plist))
2612 /* Input method variable handler. */
2614 /* Check if PLIST has this form:
2615 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2618 If the form of PLIST matches, return 0, otherwise return -1. */
2621 check_variable_list (MPlist *plist)
2623 MSymbol type = MPLIST_KEY (plist);
2626 if (type != Minteger && type != Mtext && type != Msymbol)
2628 MPLIST_DO (plist, MPLIST_NEXT (plist))
2630 if (type == Minteger && MPLIST_PLIST_P (plist))
2632 MPLIST_DO (p, MPLIST_PLIST (plist))
2633 if (! MPLIST_INTEGER_P (p))
2636 else if (type != MPLIST_KEY (plist))
2642 /* Support functions for mdebug_dump_im. */
2645 dump_im_map (MPlist *map_list, int indent)
2648 MSymbol key = MPLIST_KEY (map_list);
2649 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2651 prefix = (char *) alloca (indent + 1);
2652 memset (prefix, 32, indent);
2653 prefix[indent] = '\0';
2655 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2656 if (map->map_actions)
2657 mdebug_dump_plist (map->map_actions, indent + 2);
2660 MPLIST_DO (map_list, map->submaps)
2662 fprintf (stderr, "\n%s ", prefix);
2663 dump_im_map (map_list, indent + 2);
2666 if (map->branch_actions)
2668 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2669 mdebug_dump_plist (map->branch_actions, indent + 4);
2670 fprintf (stderr, ")");
2672 fprintf (stderr, ")");
2677 dump_im_state (MIMState *state, int indent)
2682 prefix = (char *) alloca (indent + 1);
2683 memset (prefix, 32, indent);
2684 prefix[indent] = '\0';
2686 fprintf (stderr, "(%s", msymbol_name (state->name));
2687 if (state->map->submaps)
2689 MPLIST_DO (map_list, state->map->submaps)
2691 fprintf (stderr, "\n%s ", prefix);
2692 dump_im_map (map_list, indent + 2);
2695 fprintf (stderr, ")");
2704 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2705 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2706 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2707 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2708 char buf[6], buf2[256];
2712 Minput_method = msymbol ("input-method");
2713 Minput_driver = msymbol ("input-driver");
2714 Mtitle = msymbol ("title");
2715 Mmacro = msymbol ("macro");
2716 Mmodule = msymbol ("module");
2717 Mmap = msymbol ("map");
2718 Mstate = msymbol ("state");
2719 Minclude = msymbol ("include");
2720 Minsert = msymbol ("insert");
2721 M_candidates = msymbol (" candidates");
2722 Mdelete = msymbol ("delete");
2723 Mmove = msymbol ("move");
2724 Mmark = msymbol ("mark");
2725 Mpushback = msymbol ("pushback");
2726 Mundo = msymbol ("undo");
2727 Mcall = msymbol ("call");
2728 Mshift = msymbol ("shift");
2729 Mselect = msymbol ("select");
2730 Mshow = msymbol ("show");
2731 Mhide = msymbol ("hide");
2732 Mcommit = msymbol ("commit");
2733 Munhandle = msymbol ("unhandle");
2734 Mset = msymbol ("set");
2735 Madd = msymbol ("add");
2736 Msub = msymbol ("sub");
2737 Mmul = msymbol ("mul");
2738 Mdiv = msymbol ("div");
2739 Mequal = msymbol ("=");
2740 Mless = msymbol ("<");
2741 Mgreater = msymbol (">");
2743 Mcandidates_group_size = msymbol ("candidates-group-size");
2744 Mcandidates_charset = msymbol ("candidates-charset");
2746 Minput_preedit_start = msymbol ("input-preedit-start");
2747 Minput_preedit_done = msymbol ("input-preedit-done");
2748 Minput_preedit_draw = msymbol ("input-preedit-draw");
2749 Minput_status_start = msymbol ("input-status-start");
2750 Minput_status_done = msymbol ("input-status-done");
2751 Minput_status_draw = msymbol ("input-status-draw");
2752 Minput_candidates_start = msymbol ("input-candidates-start");
2753 Minput_candidates_done = msymbol ("input-candidates-done");
2754 Minput_candidates_draw = msymbol ("input-candidates-draw");
2755 Minput_set_spot = msymbol ("input-set-spot");
2756 Minput_focus_move = msymbol ("input-focus-move");
2757 Minput_focus_in = msymbol ("input-focus-in");
2758 Minput_focus_out = msymbol ("input-focus-out");
2759 Minput_toggle = msymbol ("input-toggle");
2760 Minput_reset = msymbol ("input-reset");
2762 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2763 Mcandidate_index = msymbol (" candidate-index");
2765 Minit = msymbol ("init");
2766 Mfini = msymbol ("fini");
2768 M_key_alias = msymbol (" key-alias");
2769 M_description = msymbol ("description");
2770 M_command = msymbol ("command");
2771 M_variable = msymbol ("variable");
2773 load_im_info_keys = mplist ();
2774 plist = mplist_add (load_im_info_keys, Mstate, Mnil);
2779 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2783 one_char_symbol[i] = msymbol (buf);
2786 alias = msymbol (key_names[i]);
2787 msymbol_put (one_char_symbol[i], M_key_alias, alias);
2790 alias = one_char_symbol[i];
2791 buf[2] += (i == 0) ? -32 : 32;
2792 msymbol_put (alias, M_key_alias, msymbol (buf));
2793 buf[2] -= (i == 0) ? -32 : 32;
2795 for (buf[2] = i; i < 127; i++, buf[2]++)
2796 one_char_symbol[i] = msymbol (buf + 2);
2797 one_char_symbol[i++] = msymbol ("Delete");
2803 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2805 one_char_symbol[i] = msymbol (buf);
2806 if (key_names[i - 128])
2808 strcpy (buf2 + 2, key_names[i - 128]);
2809 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2812 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2813 one_char_symbol[i] = msymbol (buf + 2);
2814 one_char_symbol[i] = msymbol ("M-Delete");
2816 command_list = variable_list = NULL;
2818 minput_default_driver.open_im = open_im;
2819 minput_default_driver.close_im = close_im;
2820 minput_default_driver.create_ic = create_ic;
2821 minput_default_driver.destroy_ic = destroy_ic;
2822 minput_default_driver.filter = filter;
2823 minput_default_driver.lookup = lookup;
2824 minput_default_driver.callback_list = mplist ();
2825 mplist_put (minput_default_driver.callback_list, Minput_reset,
2827 minput_driver = &minput_default_driver;
2836 M17N_OBJECT_UNREF (command_list);
2837 command_list = NULL;
2841 M17N_OBJECT_UNREF (variable_list);
2842 variable_list = NULL;
2845 if (minput_default_driver.callback_list)
2847 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2848 minput_default_driver.callback_list = NULL;
2850 if (minput_driver->callback_list)
2852 M17N_OBJECT_UNREF (minput_driver->callback_list);
2853 minput_driver->callback_list = NULL;
2858 while (! MPLIST_TAIL_P (im_info_list))
2861 mplist_pop (im_info_list);
2862 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
2863 /* Pop (t . im_info) */
2864 mplist_pop (im_info_list);
2866 M17N_OBJECT_UNREF (im_info_list);
2867 im_info_list = NULL;
2870 M17N_OBJECT_UNREF (load_im_info_keys);
2874 minput__callback (MInputContext *ic, MSymbol command)
2876 if (ic->im->driver.callback_list)
2878 MInputCallbackFunc func
2879 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
2883 (func) (ic, command);
2888 minput__char_to_key (int c)
2890 if (c < 0 || c >= 0x100)
2893 return one_char_symbol[c];
2897 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2902 /*** @addtogroup m17nInputMethod */
2907 @name Variables: Predefined symbols for callback commands.
2909 These are the predefined symbols that are used as the @c COMMAND
2910 argument of callback functions of an input method driver (see
2911 #MInputDriver::callback_list ). */
2913 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
2915 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
2916 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
2921 MSymbol Minput_preedit_start;
2922 MSymbol Minput_preedit_done;
2923 MSymbol Minput_preedit_draw;
2924 MSymbol Minput_status_start;
2925 MSymbol Minput_status_done;
2926 MSymbol Minput_status_draw;
2927 MSymbol Minput_candidates_start;
2928 MSymbol Minput_candidates_done;
2929 MSymbol Minput_candidates_draw;
2930 MSymbol Minput_set_spot;
2931 MSymbol Minput_toggle;
2932 MSymbol Minput_reset;
2938 @name Variables: Predefined symbols for special input events.
2940 These are the predefined symbols that are used as the @c KEY
2941 argument of minput_filter (). */
2946 MSymbol Minput_focus_out;
2947 MSymbol Minput_focus_in;
2948 MSymbol Minput_focus_move;
2955 @brief The default driver for internal input methods.
2957 The variable #minput_default_driver is the default driver for
2958 internal input methods.
2960 The member MInputDriver::open_im () searches the m17n database for
2961 an input method that matches the tag \< #Minput_method, $LANGUAGE,
2962 $NAME\> and loads it.
2964 The member MInputDriver::callback_list () is @c NULL. Thus, it is
2965 programmers responsibility to set it to a plist of proper callback
2966 functions. Otherwise, no feedback information (e.g. preedit text)
2967 can be shown to users.
2969 The macro M17N_INIT () sets the variable #minput_driver to the
2970 pointer to this driver so that all internal input methods use it.
2972 Therefore, unless @c minput_driver is set differently, the driver
2973 dependent arguments $ARG of the functions whose name begin with
2974 "minput_" are all ignored. */
2977 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
2979 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
2981 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
2982 \< #Minput_method, $LANGUAGE, $NAME\>
2983 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
2985 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
2986 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
2987 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
2988 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
2990 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
2991 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
2993 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
2994 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
2996 MInputDriver minput_default_driver;
3000 @brief The driver for internal input methods.
3002 The variable #minput_driver is a pointer to the input method
3003 driver that is used by internal input methods. The macro
3004 M17N_INIT () initializes it to a pointer to #minput_default_driver
3005 if <m17n<EM></EM>.h> is included. */
3007 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
3009 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
3010 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
3011 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
3012 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
3014 MInputDriver *minput_driver;
3016 MSymbol Minput_driver;
3021 @brief Open an input method.
3023 The minput_open_im () function opens an input method that matches
3024 language $LANGUAGE and name $NAME, and returns a pointer to the
3025 input method object newly allocated.
3027 This function at first decides an driver for the input method as
3030 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3031 #minput_driver is used.
3033 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
3034 driver pointed to by the property value is used to open the input
3035 method. If $NAME has no such property, @c NULL is returned.
3037 Then, the member MInputDriver::open_im () of the driver is
3040 $ARG is set in the member @c arg of the structure MInputMethod so
3041 that the driver can refer to it. */
3044 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3046 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3047 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3049 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3051 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3052 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3054 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3055 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3056 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3058 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3060 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3062 @latexonly \IPAlabel{minput_open} @endlatexonly
3067 minput_open_im (MSymbol language, MSymbol name, void *arg)
3070 MInputDriver *driver;
3072 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3073 msymbol_name (language), msymbol_name (name));
3075 driver = minput_driver;
3078 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3080 MERROR (MERROR_IM, NULL);
3083 MSTRUCT_CALLOC (im, MERROR_IM);
3084 im->language = language;
3087 im->driver = *driver;
3088 if ((*im->driver.open_im) (im) < 0)
3090 MDEBUG_PRINT (" failed\n");
3094 MDEBUG_PRINT (" ok\n");
3101 @brief Close an input method.
3103 The minput_close_im () function closes the input method $IM, which
3104 must have been created by minput_open_im (). */
3107 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3109 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3110 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3113 minput_close_im (MInputMethod *im)
3115 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3116 msymbol_name (im->name), msymbol_name (im->language));
3117 (*im->driver.close_im) (im);
3119 MDEBUG_PRINT (" done\n");
3125 @brief Create an input context.
3127 The minput_create_ic () function creates an input context object
3128 associated with input method $IM, and calls callback functions
3129 corresponding to #Minput_preedit_start, #Minput_status_start, and
3130 #Minput_status_draw in this order.
3134 If an input context is successfully created, minput_create_ic ()
3135 returns a pointer to it. Otherwise it returns @c NULL. */
3138 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3140 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3141 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3142 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3143 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3147 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3148 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3152 minput_create_ic (MInputMethod *im, void *arg)
3156 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3157 msymbol_name (im->name), msymbol_name (im->language));
3158 MSTRUCT_CALLOC (ic, MERROR_IM);
3161 ic->preedit = mtext ();
3162 ic->candidate_list = NULL;
3163 ic->produced = mtext ();
3164 ic->spot.x = ic->spot.y = 0;
3166 ic->plist = mplist ();
3167 if ((*im->driver.create_ic) (ic) < 0)
3169 MDEBUG_PRINT (" failed\n");
3170 M17N_OBJECT_UNREF (ic->preedit);
3171 M17N_OBJECT_UNREF (ic->produced);
3172 M17N_OBJECT_UNREF (ic->plist);
3177 if (im->driver.callback_list)
3179 minput__callback (ic, Minput_preedit_start);
3180 minput__callback (ic, Minput_status_start);
3181 minput__callback (ic, Minput_status_draw);
3184 MDEBUG_PRINT (" ok\n");
3191 @brief Destroy an input context.
3193 The minput_destroy_ic () function destroys the input context $IC,
3194 which must have been created by minput_create_ic (). It calls
3195 callback functions corresponding to #Minput_preedit_done,
3196 #Minput_status_done, and #Minput_candidates_done in this order. */
3199 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3201 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3202 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3203 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3204 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3205 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3209 minput_destroy_ic (MInputContext *ic)
3211 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3212 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3213 if (ic->im->driver.callback_list)
3215 minput__callback (ic, Minput_preedit_done);
3216 minput__callback (ic, Minput_status_done);
3217 minput__callback (ic, Minput_candidates_done);
3219 (*ic->im->driver.destroy_ic) (ic);
3220 M17N_OBJECT_UNREF (ic->preedit);
3221 M17N_OBJECT_UNREF (ic->produced);
3222 M17N_OBJECT_UNREF (ic->plist);
3223 MDEBUG_PRINT (" done\n");
3230 @brief Filter an input key.
3232 The minput_filter () function filters input key $KEY according to
3233 input context $IC, and calls callback functions corresponding to
3234 #Minput_preedit_draw, #Minput_status_draw, and
3235 #Minput_candidates_draw if the preedit text, the status, and the
3236 current candidate are changed respectively.
3238 To make the input method commit the current preedit text (if any)
3239 and shift to the initial state, call this function with #Mnil as
3242 To inform the input method about the focus-out event, call this
3243 function with #Minput_focus_out as $KEY.
3245 To inform the input method about the focus-in event, call this
3246 function with #Minput_focus_in as $KEY.
3248 To inform the input method about the focus-move event (i.e. input
3249 spot change within the same input context), call this function
3250 with #Minput_focus_move as $KEY.
3253 If $KEY is filtered out, this function returns 1. In that case,
3254 the caller should discard the key. Otherwise, it returns 0, and
3255 the caller should handle the key, for instance, by calling the
3256 function minput_lookup () with the same key. */
3259 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3261 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3262 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3263 #Minput_preedit_draw, #Minput_status_draw,
3264 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3267 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3268 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3269 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3270 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3272 @latexonly \IPAlabel{minput_filter} @endlatexonly
3276 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3283 ret = (*ic->im->driver.filter) (ic, key, arg);
3285 if (ic->im->driver.callback_list)
3287 if (ic->preedit_changed)
3288 minput__callback (ic, Minput_preedit_draw);
3289 if (ic->status_changed)
3290 minput__callback (ic, Minput_status_draw);
3291 if (ic->candidates_changed)
3292 minput__callback (ic, Minput_candidates_draw);
3301 @brief Look up a text produced in the input context.
3303 The minput_lookup () function looks up a text in the input context
3304 $IC. $KEY must be the same one provided to the previous call of
3307 If a text was produced by the input method, it is concatenated
3310 This function calls #MInputDriver::lookup .
3313 If $KEY was correctly handled by the input method, this function
3314 returns 0. Otherwise, returns -1, even in that case, some text
3315 may be produced in $MT. */
3318 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3320 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3321 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3323 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3326 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3329 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3330 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3331 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3333 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3336 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3338 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3343 @brief Set the spot of the input context.
3345 The minput_set_spot () function set the spot of input context $IC
3346 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3347 The semantics of these values depend on the input method driver.
3349 For instance, a driver designed to work in a CUI environment may
3350 use $X and $Y as column and row numbers, and ignore $ASCENT and
3351 $DESCENT . A driver designed to work in a window system may
3352 interpret $X and $Y as pixel offsets relative to the origin of the
3353 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3354 descent pixels of the line at ($X . $Y ).
3356 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3358 $MT and $POS is the M-text and the character position at the spot.
3359 $MT may be @c NULL, in which case, the input method cannot get
3360 information about the text around the spot. */
3363 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3365 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3366 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3367 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3369 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3370 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3371 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3372 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3373 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3374 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3376 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3378 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3379 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3383 minput_set_spot (MInputContext *ic, int x, int y,
3384 int ascent, int descent, int fontsize,
3389 ic->spot.ascent = ascent;
3390 ic->spot.descent = descent;
3391 ic->spot.fontsize = fontsize;
3394 if (ic->im->driver.callback_list)
3395 minput__callback (ic, Minput_set_spot);
3400 @brief Toggle input method.
3402 The minput_toggle () function toggles the input method associated
3403 with input context $IC. */
3405 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3407 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3408 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3412 minput_toggle (MInputContext *ic)
3414 if (ic->im->driver.callback_list)
3415 minput__callback (ic, Minput_toggle);
3416 ic->active = ! ic->active;
3420 @brief Reset an input context.
3422 The minput_reset_ic () function resets input context $IC by
3423 calling a callback function corresponding to #Minput_reset. It
3424 resets the status of $IC to the one of just after created. As the
3425 current preedit text is deleted without commitment, if necessary,
3426 call minput_filter () with the arg @r key #Mnil to force the input
3427 method to commit the preedit in advance. */
3430 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3432 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3433 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3434 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3435 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3436 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3437 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3440 minput_reset_ic (MInputContext *ic)
3442 if (ic->im->driver.callback_list)
3443 minput__callback (ic, Minput_reset);
3447 @brief Get description text of an input method.
3449 The minput_get_description () function returns an M-text that
3450 describes the input method specified by $LANGUAGE and $NAME.
3453 If the specified input method has a description text, a pointer to
3454 #MText is returned. A caller have to free it by m17n_object_unref ().
3455 If the input method does not have a description text, @c NULL is
3458 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3460 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3461 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3463 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3464 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3465 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3466 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3469 minput_get_description (MSymbol language, MSymbol name)
3471 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3477 pl = MPLIST_PLIST (plist);
3478 pl = MPLIST_NEXT (pl);
3479 if (MPLIST_MTEXT_P (pl))
3481 mt = MPLIST_MTEXT (pl);
3482 M17N_OBJECT_REF (mt);
3484 M17N_OBJECT_UNREF (plist);
3489 @brief Get information about input method commands.
3491 The minput_get_commands () function returns information about
3492 input method commands of the input method specified by $LANGUAGE
3493 and $NAME. An input method command is a pseudo key event to which
3494 one or more actual input key sequences are assigned.
3496 There are two kinds of commands, global and local. Global
3497 commands are used by multiple input methods for the same purpose,
3498 and have global key assignments. Local commands are used only in
3499 a specific input method, and have only local key assignments.
3501 Each input method may locally change key assignments for global
3502 commands. A global key assignment for a global command are
3503 effective only when the current input method does not have local
3504 key assignments for that command.
3506 If $NAME is #Mnil, information about global commands is returned.
3507 In this case $LANGUAGE is ignored.
3509 If $NAME is not #Mnil, information about those commands that have
3510 local key assignments in the input method specified by $LANGUAGE
3511 and $NAME is returned.
3514 If no input method commands are found, this function returns @c NULL.
3516 Otherwise, a pointer to a plist is returned. The key of each
3517 element in the plist is a symbol representing a command, and the
3518 value is a plist of the form COMMAND-INFO described below.
3520 The first element of COMMAND-INFO has the key #Mtext, and the
3521 value is an M-text describing the command.
3523 If there are no more elements, that means no key sequences are
3524 assigned to the command. Otherwise, each of the remaining
3525 elements has the key #Mplist, and the value is a plist whose keys are
3526 #Msymbol and values are symbols representing input keys, which are
3527 currently assigned to the command.
3529 As the returned plist is kept in the library, the caller must not
3530 modify nor free it. */
3532 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3534 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3535 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3536 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3537 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3539 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3540 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3541 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3542 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3544 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3545 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3546 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3549 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3550 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3552 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3553 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3557 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3559 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3560 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3561 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3563 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3564 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3565 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3568 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3569 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3570 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3571 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3572 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3574 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3575 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3578 minput_get_commands (MSymbol language, MSymbol name)
3580 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
3582 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3586 @brief Assign a key sequence to an input method command.
3588 The minput_assign_command_keys () function assigns input key
3589 sequence $KEYSEQ to input method command $COMMAND for the input
3590 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3591 key sequence is assigned globally no matter what $LANGUAGE is.
3592 Otherwise the key sequence is assigned locally.
3594 Each element of $KEYSEQ must have the key $Msymbol and the value
3595 must be a symbol representing an input key.
3597 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3598 globally or locally.
3600 This assignment gets effective in a newly opened input method.
3603 If the operation was successful, 0 is returned. Otherwise -1 is
3604 returned, and #merror_code is set to #MERROR_IM. */
3606 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3608 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
3609 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
3610 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
3611 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
3612 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3614 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
3615 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3617 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
3618 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3620 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
3623 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3624 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3627 minput_assign_command_keys (MSymbol language, MSymbol name,
3628 MSymbol command, MPlist *keyseq)
3630 MPlist *plist, *pl, *p;
3632 if (check_command_keyseq (keyseq) < 0
3633 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
3634 MERROR (MERROR_IM, -1);
3635 pl = mplist_get (plist, command);
3638 pl = MPLIST_NEXT (pl);
3640 while ((p = mplist_pop (pl)))
3641 M17N_OBJECT_UNREF (p);
3644 keyseq = mplist_copy (keyseq);
3645 mplist_push (pl, Mplist, keyseq);
3646 M17N_OBJECT_UNREF (keyseq);
3652 MERROR (MERROR_IM, -1);
3655 /* Get global commands. */
3656 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
3657 pl = mplist_get (pl, command);
3659 MERROR (MERROR_IM, -1);
3661 mplist_add (p, Mtext, mplist_value (pl));
3662 keyseq = mplist_copy (keyseq);
3663 mplist_add (p, Mplist, keyseq);
3664 M17N_OBJECT_UNREF (keyseq);
3665 mplist_push (plist, command, p);
3671 @brief Get a list of variables of an input method.
3673 The minput_get_variables () function returns a plist (#MPlist) of
3674 variables used to control the behavior of the input method
3675 specified by $LANGUAGE and $NAME. The key of an element of the
3676 plist is a symbol representing a variable, and the value is a
3677 plist of the form VAR-INFO (described below) that carries the
3678 information about the variable.
3680 The first element of VAR-INFO has the key #Mtext or #Msymbol. If
3681 the key is #Mtext, the value is an M-text describing the variable.
3682 If the key is #Msymbol, that value is #Mnil which means the
3683 variable has no description text.
3685 The second element of VAR-INFO is for the value of the variable.
3686 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3687 integer, a symbol, or an M-text, respectively. The variable is
3688 set to this value when an input context is created for the input
3691 If there are no more elements, the variable can take any value
3692 that matches with the above type. Otherwise, the remaining
3693 elements of VAR-INFO are to specify valid values of the variable.
3695 If the type of the variable is integer, the following elements
3696 have the key #Minteger or #Mplist. If it is #Minteger, the value
3697 is a valid integer value. If it is #Mplist, the value is a plist
3698 of two of elements. Both of them have the key #Minteger, and
3699 values are the minimum and maximum bounds of the valid value
3702 If the type of the variable is symbol or M-text, the following
3703 elements of the plist have the key #Msymbol or #Mtext,
3704 respectively, and the value must be a valid one.
3706 For instance, suppose an input method has the variables:
3708 @li name:intvar, description:"value is an integer",
3709 initial value:0, value-range:0..3,10,20
3711 @li name:symvar, description:"value is a symbol",
3712 initial value:nil, value-range:a, b, c, nil
3714 @li name:txtvar, description:"value is an M-text",
3715 initial value:empty text, no value-range (i.e. any text)
3717 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3718 a value, and '(...)' means a plist):
3721 plist:(intvar:(mtext:"value is an integer"
3723 plist:(integer:0 integer:3)
3726 symvar:(mtext:"value is a symbol"
3732 txtvar:(mtext:"value is an M-text"
3737 If the input method uses any variables, a pointer to #MPlist is
3738 returned. As the plist is kept in the library, a caller must not
3739 modify nor free it. If the input method does not use any
3740 variable, @c NULL is returned. */
3742 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3744 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3745 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3746 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3747 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3748 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3750 VAR-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼¤¬
3751 #Mtext ¤Ê¤é¡¢ÃͤϤ½¤ÎÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬ #Msymbol
3752 ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤ÎÊÑ¿ô¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê¤¤¤³¤È¤Ë¤Ê¤ë¡£
3754 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3755 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3756 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3758 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3759 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3761 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3762 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3763 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3764 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3766 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3767 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3769 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3771 @li name:intvar, ÀâÌÀ:"value is an integer",
3772 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3774 @li name:symvar, ÀâÌÀ:"value is a symbol",
3775 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3777 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3778 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3780 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3781 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3784 plist:(intvar:(mtext:"value is an integer"
3786 plist:(integer:0 integer:3)
3789 symvar:(mtext:"value is a symbol"
3795 txtvar:(mtext:"value is an M-text"
3800 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3801 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3802 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3805 minput_get_variables (MSymbol language, MSymbol name)
3807 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
3809 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3813 @brief Set the initial value of an input method variable.
3815 The minput_set_variable () function sets the initial value of
3816 input method variable $VARIABLE to $VALUE for the input method
3817 specified by $LANGUAGE and $NAME.
3819 By default, the initial value is 0.
3821 This setting gets effective in a newly opened input method.
3824 If the operation was successful, 0 is returned. Otherwise -1 is
3825 returned, and #merror_code is set to #MERROR_IM. */
3827 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3829 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3830 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3831 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3833 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3835 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3838 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3839 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3842 minput_set_variable (MSymbol language, MSymbol name,
3843 MSymbol variable, void *value)
3845 MPlist *plist, *val_element, *range_element;
3848 if (language == Mnil || name == Mnil)
3849 MERROR (MERROR_IM, -1);
3850 plist = get_nested_list (language, name, Mnil, M_variable);
3852 MERROR (MERROR_IM, -1);
3853 plist = (MPlist *) mplist_get (plist, variable);
3855 MERROR (MERROR_IM, -1);
3856 val_element = MPLIST_NEXT (plist);
3857 type = MPLIST_KEY (val_element);
3858 range_element = MPLIST_NEXT (val_element);
3860 if (! MPLIST_TAIL_P (range_element))
3862 if (type == Minteger)
3864 int val = (int) value, this_val;
3866 MPLIST_DO (plist, range_element)
3868 this_val = (int) MPLIST_VAL (plist);
3869 if (MPLIST_PLIST_P (plist))
3871 int min_bound, max_bound;
3872 MPlist *pl = MPLIST_PLIST (plist);
3874 min_bound = (int) MPLIST_VAL (pl);
3875 pl = MPLIST_NEXT (pl);
3876 max_bound = (int) MPLIST_VAL (pl);
3877 if (val >= min_bound && val <= max_bound)
3880 else if (val == this_val)
3883 if (MPLIST_TAIL_P (plist))
3884 MERROR (MERROR_IM, -1);
3886 else if (type == Msymbol)
3888 MPLIST_DO (plist, range_element)
3889 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
3891 if (MPLIST_TAIL_P (plist))
3892 MERROR (MERROR_IM, -1);
3894 else /* type == Mtext */
3896 MPLIST_DO (plist, range_element)
3897 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
3899 if (MPLIST_TAIL_P (plist))
3900 MERROR (MERROR_IM, -1);
3901 M17N_OBJECT_REF (value);
3905 mplist_set (val_element, type, value);
3911 /*** @addtogroup m17nDebug */
3917 @brief Dump an input method.
3919 The mdebug_dump_im () function prints the input method $IM in a
3920 human readable way to the stderr. $INDENT specifies how many
3921 columns to indent the lines but the first one.
3924 This function returns $IM. */
3926 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
3928 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
3929 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
3932 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
3935 mdebug_dump_im (MInputMethod *im, int indent)
3937 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
3940 prefix = (char *) alloca (indent + 1);
3941 memset (prefix, 32, indent);
3942 prefix[indent] = '\0';
3944 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
3945 msymbol_name (im->name));
3946 mdebug_dump_mtext (im_info->title, 0, 0);
3947 if (im->name != Mnil)
3951 MPLIST_DO (state, im_info->states)
3953 fprintf (stderr, "\n%s ", prefix);
3954 dump_im_state (MPLIST_VAL (state), indent + 2);
3957 fprintf (stderr, ")");