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 an 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 its 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 drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
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 has 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 its body is
56 defined in an external resource (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
142 #include <sys/types.h>
144 #include <sys/stat.h>
153 #include "m17n-gui.h"
154 #include "m17n-misc.h"
155 #include "internal.h"
160 #include "database.h"
163 static int mdebug_mask = MDEBUG_INPUT;
165 static MSymbol Minput_method;
167 /** Symbols to load an input method data. */
168 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
170 /** Symbols for actions. */
171 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
172 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
173 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
174 static MSymbol Mless_equal, Mgreater_equal;
175 static MSymbol Mcond;
176 static MSymbol Mplus, Mminus, Mstar, Mslush, Mand, Mor, Mnot;
178 static MSymbol M_candidates;
180 static MSymbol Mcandidate_list, Mcandidate_index;
182 static MSymbol Minit, Mfini;
184 /** Symbols for variables. */
185 static MSymbol Mcandidates_group_size, Mcandidates_charset;
187 /** Symbols for key events. */
188 static MSymbol one_char_symbol[256];
190 static MSymbol M_key_alias;
192 static MSymbol M_description, M_command, M_variable;
194 /** Structure to hold a map. */
198 /** List of actions to take when we reach the map. In a root map,
199 the actions are executed only when there's no more key. */
202 /** List of deeper maps. If NULL, this is a terminal map. */
205 /** List of actions to take when we leave the map successfully. In
206 a root map, the actions are executed only when none of submaps
207 handle the current key. */
208 MPlist *branch_actions;
211 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
216 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
223 /** Name of the state. */
226 /** Title of the state, or NULL. */
229 /** Key translation map of the state. Built by merging all maps of
234 /* Lookup keys KEY1,2,3 in the nested plist PLIST, and return the
238 lookup_nested_list (MPlist *plist, MSymbol key1, MSymbol key2, MSymbol key3)
243 key[0] = key1, key[1] = key2, key[2] = key3;
244 for (i = 0; i < 3; i++)
246 plist = mplist_find_by_value (plist, key[i]);
249 plist = MPLIST_NEXT (plist);
250 plist = MPLIST_PLIST (plist);
255 /* Set VAL for keys KEY1,2,3 in the nested plist PLIST. */
258 set_nested_list (MPlist *plist, MSymbol key1, MSymbol key2, MSymbol key3,
265 key[0] = key1, key[1] = key2, key[2] = key3;
266 for (i = 0; i < 3; i++)
268 pl = mplist_find_by_value (plist, key[i]);
271 pl = MPLIST_NEXT (pl);
272 plist = MPLIST_PLIST (pl);
276 pl = mplist_add (plist, Msymbol, key[i]);
278 pl = mplist_add (pl, Mplist, plist);
279 M17N_OBJECT_UNREF (plist);
282 mplist_set (pl, Mplist, val);
283 M17N_OBJECT_UNREF (val);
287 /* Parse PLIST as a value of nested list and return an adjusted list.
292 [ mtext:DESCRIPTION | symbol:nil ]
293 ;; The remaining elements are checked CHECK_FUNC.
296 [ mtext:DESCRIPTION | symbol:nil ]
297 ;; The remaining elements are checked CHECK_FUNC.
301 GLOBAL is a global list. If a description text is missing, it is
302 extracted from GLOBAL.
304 The return value is a plist of this format:
306 plist:([ mtext:DESCRIPTION | symbol:nil ]
309 plist:([ mtext:DESCRIPTION | symbol:nil ]
313 PLIST itself is unref-ed. */
316 parse_nested_list_value (MPlist *plist, MPlist *global, MSymbol key,
317 int (*check_func) (MPlist *))
319 MPlist *val, *pl, *p, *p0;
322 if (! MPLIST_PLIST_P (plist))
324 M17N_OBJECT_UNREF (plist);
327 pl = MPLIST_PLIST (plist);
328 if (! MPLIST_SYMBOL_P (pl)
329 || MPLIST_SYMBOL (pl) != key)
331 M17N_OBJECT_UNREF (plist);
335 MPLIST_DO (pl, MPLIST_NEXT (pl))
338 MPlist *global_def = NULL;
340 if (! MPLIST_PLIST_P (pl))
342 p = MPLIST_PLIST (pl);
343 if (! MPLIST_SYMBOL_P (p))
345 name = MPLIST_SYMBOL (p);
347 if (MPLIST_TAIL_P (p))
351 global_def = mplist_find_by_value (global, name);
354 global_def = MPLIST_PLIST (MPLIST_NEXT (global_def));
355 mplist__conc (p, global_def);
357 p0 = MPLIST_NEXT (p);
358 if (MPLIST_TAIL_P (p0))
360 if (! global || global_def)
362 global_def = mplist_find_by_value (global, name);
365 global_def = MPLIST_PLIST (MPLIST_NEXT (global_def));
366 global_def = MPLIST_NEXT (global_def);
367 if (MPLIST_TAIL_P (global_def))
369 mplist__conc (p0, global_def);
371 if ((*check_func) (p0) < 0)
373 mplist_add (val, Msymbol, name);
374 mplist_add (val, Mplist, p);
377 M17N_OBJECT_UNREF (plist);
381 static MPlist *variable_list, *command_list;
382 static int check_variable_list (MPlist *plist);
383 static int check_command_list (MPlist *plist);
384 static MPlist *load_partial_im_info (MSymbol language, MSymbol name,
385 MSymbol extra, MSymbol key);
388 get_nested_list (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
391 int (*check_func) (MPlist *);
392 MPlist *plist, *global;
394 if (key == M_variable)
397 variable_list = mplist ();
398 total_list = variable_list;
399 check_func = check_variable_list;
404 command_list = mplist ();
405 total_list = command_list;
406 check_func = check_command_list;
409 if (MPLIST_TAIL_P (total_list))
411 plist = load_partial_im_info (Mt, Mnil, key, key);
413 global = parse_nested_list_value (plist, NULL, key, check_func);
416 set_nested_list (total_list, Mt, Mnil, key, global);
419 global = lookup_nested_list (total_list, Mt, Mnil, key);
424 plist = lookup_nested_list (total_list, language, name, extra);
428 plist = load_partial_im_info (language, name, extra, key);
430 plist = parse_nested_list_value (plist, global, key, check_func);
433 set_nested_list (total_list, language, name, extra, plist);
438 marker_code (MSymbol sym)
444 name = MSYMBOL_NAME (sym);
445 return ((name[0] == '@'
446 && ((name[1] >= '0' && name[1] <= '9')
447 || name[1] == '<' || name[1] == '>'
448 || name[1] == '=' || name[1] == '+' || name[1] == '-'
449 || name[1] == '[' || name[1] == ']'
457 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
461 MPLIST_DO (p, ic_info->vars)
463 if (MPLIST_SYMBOL (p) == var)
467 if (MPLIST_TAIL_P (p))
470 mplist_push (p, Minteger, (void *) 0);
471 mplist_push (p, Msymbol, var);
473 return (MPLIST_NEXT (p));
477 get_surrounding_text (MInputContext *ic, int len)
481 mplist_push (ic->plist, Minteger, (void *) len);
482 minput__callback (ic, Minput_get_surrounding_text);
483 if (MPLIST_MTEXT_P (ic->plist))
485 mt = MPLIST_MTEXT (ic->plist);
486 mplist_pop (ic->plist);
492 delete_surrounding_text (MInputContext *ic, int pos)
494 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
496 mplist_push (ic->plist, Minteger, (void *) pos);
497 minput__callback (ic, Minput_delete_surrounding_text);
498 mplist_pop (ic->plist);
500 M17N_OBJECT_UNREF (ic_info->preceding_text);
502 M17N_OBJECT_UNREF (ic_info->following_text);
506 get_preceding_char (MInputContext *ic, int pos)
508 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
512 if (ic_info->preceding_text)
514 len = mtext_nchars (ic_info->preceding_text);
516 return mtext_ref_char (ic_info->preceding_text, len - pos);
518 mt = get_surrounding_text (ic, - pos);
521 len = mtext_nchars (mt);
522 if (ic_info->preceding_text)
524 if (mtext_nchars (ic_info->preceding_text) < len)
526 M17N_OBJECT_UNREF (ic_info->preceding_text);
527 ic_info->preceding_text = mt;
531 ic_info->preceding_text = mt;
534 return mtext_ref_char (ic_info->preceding_text, len - pos);
538 get_following_char (MInputContext *ic, int pos)
540 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
544 if (ic_info->following_text)
546 len = mtext_nchars (ic_info->following_text);
548 return mtext_ref_char (ic_info->following_text, pos - 1);
550 mt = get_surrounding_text (ic, pos);
553 len = mtext_nchars (mt);
554 if (ic_info->following_text)
556 if (mtext_nchars (ic_info->following_text) < len)
558 M17N_OBJECT_UNREF (ic_info->following_text);
559 ic_info->following_text = mt;
563 ic_info->following_text = mt;
566 return mtext_ref_char (ic_info->following_text, pos - 1);
570 surrounding_pos (MSymbol sym)
576 name = MSYMBOL_NAME (sym);
577 if ((name[1] == '-' || name[1] == '+')
578 && name[2] >= '1' && name[2] <= '9')
579 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
584 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
586 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
588 MText *preedit = ic->preedit;
589 int len = mtext_nchars (preedit);
593 if (MPLIST_INTEGER_P (arg))
594 return MPLIST_INTEGER (arg);
596 && (surrounding = surrounding_pos (MPLIST_SYMBOL (arg))) != 0)
597 return (surrounding < 0
598 ? get_preceding_char (ic, - surrounding)
599 : get_following_char (ic, surrounding));
600 code = marker_code (MPLIST_SYMBOL (arg));
603 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
607 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
610 return ic_info->key_head;
611 if (code >= '0' && code <= '9')
613 else if (code == '=')
614 code = ic->cursor_pos;
615 else if (code == '-' || code == '[')
616 code = ic->cursor_pos - 1;
617 else if (code == '+' || code == ']')
618 code = ic->cursor_pos + 1;
619 else if (code == '<')
621 else if (code == '>')
623 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
627 parse_expression (MPlist *plist)
631 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
633 if (! MPLIST_PLIST_P (plist))
635 plist = MPLIST_PLIST (plist);
636 op = MPLIST_SYMBOL (plist);
637 if (op != Mplus && op != Mminus && op != Mstar && op != Mslush
638 && op != Mand && op != Mor && op != Mnot
639 && op != Mless && op != Mgreater && op != Mequal
640 && op != Mless_equal && op != Mgreater_equal)
641 MERROR (MERROR_IM, -1);
642 MPLIST_DO (plist, MPLIST_NEXT (plist))
643 if (parse_expression (plist) < 0)
649 resolve_expression (MInputContext *ic, MPlist *plist)
654 if (MPLIST_INTEGER_P (plist))
655 return MPLIST_INTEGER (plist);
656 if (MPLIST_SYMBOL_P (plist))
657 return integer_value (ic, plist, NULL, 1);
658 if (! MPLIST_PLIST_P (plist))
660 plist = MPLIST_PLIST (plist);
661 if (! MPLIST_SYMBOL_P (plist))
663 op = MPLIST_SYMBOL (plist);
664 plist = MPLIST_NEXT (plist);
665 val = resolve_expression (ic, plist);
667 MPLIST_DO (plist, MPLIST_NEXT (plist))
668 val += resolve_expression (ic, plist);
669 else if (op == Mminus)
670 MPLIST_DO (plist, MPLIST_NEXT (plist))
671 val -= resolve_expression (ic, plist);
672 else if (op == Mstar)
673 MPLIST_DO (plist, MPLIST_NEXT (plist))
674 val *= resolve_expression (ic, plist);
675 else if (op == Mslush)
676 MPLIST_DO (plist, MPLIST_NEXT (plist))
677 val /= resolve_expression (ic, plist);
679 MPLIST_DO (plist, MPLIST_NEXT (plist))
680 val &= resolve_expression (ic, plist);
682 MPLIST_DO (plist, MPLIST_NEXT (plist))
683 val |= resolve_expression (ic, plist);
686 else if (op == Mless)
687 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
688 else if (op == Mequal)
689 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
690 else if (op == Mgreater)
691 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
692 else if (op == Mless_equal)
693 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
694 else if (op == Mgreater_equal)
695 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
699 /* Parse PLIST as an action list. PLIST should have this form:
700 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
701 Return 0 if successfully parsed, otherwise return -1. */
704 parse_action_list (MPlist *plist, MPlist *macros)
706 MPLIST_DO (plist, plist)
708 if (MPLIST_MTEXT_P (plist))
710 /* This is a short form of (insert MTEXT). */
711 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
712 MERROR (MERROR_IM, -1); */
714 else if (MPLIST_PLIST_P (plist)
715 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
716 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
720 /* This is a short form of (insert (GROUPS *)). */
721 MPLIST_DO (pl, MPLIST_PLIST (plist))
723 if (MPLIST_PLIST_P (pl))
727 MPLIST_DO (elt, MPLIST_PLIST (pl))
728 if (! MPLIST_MTEXT_P (elt)
729 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
730 MERROR (MERROR_IM, -1);
734 if (! MPLIST_MTEXT_P (pl)
735 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
736 MERROR (MERROR_IM, -1);
740 else if (MPLIST_INTEGER_P (plist))
742 int c = MPLIST_INTEGER (plist);
744 if (c < 0 || c > MCHAR_MAX)
745 MERROR (MERROR_IM, -1);
747 else if (MPLIST_PLIST_P (plist)
748 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
750 MPlist *pl = MPLIST_PLIST (plist);
751 MSymbol action_name = MPLIST_SYMBOL (pl);
753 pl = MPLIST_NEXT (pl);
755 if (action_name == Minsert)
757 if (MPLIST_MTEXT_P (pl))
759 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
760 MERROR (MERROR_IM, -1);
762 else if (MPLIST_PLIST_P (pl))
766 if (MPLIST_PLIST_P (pl))
770 MPLIST_DO (elt, MPLIST_PLIST (pl))
771 if (! MPLIST_MTEXT_P (elt)
772 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
773 MERROR (MERROR_IM, -1);
777 if (! MPLIST_MTEXT_P (pl)
778 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
779 MERROR (MERROR_IM, -1);
783 else if (! MPLIST_SYMBOL_P (pl))
784 MERROR (MERROR_IM, -1);
786 else if (action_name == Mselect
787 || action_name == Mdelete
788 || action_name == Mmove)
790 if (parse_expression (pl) < 0)
793 else if (action_name == Mmark
794 || action_name == Mcall
795 || action_name == Mshift)
797 if (! MPLIST_SYMBOL_P (pl))
798 MERROR (MERROR_IM, -1);
800 else if (action_name == Mundo)
802 if (! MPLIST_TAIL_P (pl))
804 if (! MPLIST_SYMBOL_P (pl)
805 && (! MPLIST_INTEGER_P (pl)
806 || MPLIST_INTEGER (pl) == 0))
807 MERROR (MERROR_IM, -1);
810 else if (action_name == Mpushback)
812 if (MPLIST_MTEXT_P (pl))
814 MText *mt = MPLIST_MTEXT (pl);
816 if (mtext_nchars (mt) != mtext_nbytes (mt))
817 MERROR (MERROR_IM, -1);
819 else if (MPLIST_PLIST_P (pl))
823 MPLIST_DO (p, MPLIST_PLIST (pl))
824 if (! MPLIST_SYMBOL_P (p))
825 MERROR (MERROR_IM, -1);
827 else if (! MPLIST_INTEGER_P (pl))
828 MERROR (MERROR_IM, -1);
830 else if (action_name == Mset || action_name == Madd
831 || action_name == Msub || action_name == Mmul
832 || action_name == Mdiv)
834 if (! MPLIST_SYMBOL_P (pl))
835 MERROR (MERROR_IM, -1);
836 if (parse_expression (MPLIST_NEXT (pl)) < 0)
839 else if (action_name == Mequal || action_name == Mless
840 || action_name == Mgreater || action_name == Mless_equal
841 || action_name == Mgreater_equal)
843 if (parse_expression (pl) < 0
844 || parse_expression (MPLIST_NEXT (pl)) < 0)
846 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
847 if (! MPLIST_PLIST_P (pl))
848 MERROR (MERROR_IM, -1);
849 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
850 MERROR (MERROR_IM, -1);
851 pl = MPLIST_NEXT (pl);
852 if (MPLIST_PLIST_P (pl)
853 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
854 MERROR (MERROR_IM, -1);
856 else if (action_name == Mshow || action_name == Mhide
857 || action_name == Mcommit || action_name == Munhandle)
859 else if (action_name == Mcond)
862 if (! MPLIST_PLIST_P (pl))
863 MERROR (MERROR_IM, -1);
865 else if (! macros || ! mplist_get (macros, action_name))
866 MERROR (MERROR_IM, -1);
869 MERROR (MERROR_IM, -1);
876 resolve_command (MSymbol language, MSymbol name, MSymbol command)
878 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
881 MERROR (MERROR_IM, NULL);
882 MPLIST_DO (plist, plist)
884 if (MPLIST_SYMBOL (plist) == command)
886 plist = MPLIST_NEXT (plist);
888 if (MPLIST_TAIL_P (plist))
889 MERROR (MERROR_IM, NULL);
890 plist = MPLIST_NEXT (plist);
891 if (! MPLIST_PLIST_P (plist))
892 MERROR (MERROR_IM, NULL);
893 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
897 /* Load a translation into MAP from PLIST.
899 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
902 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
903 MPlist *branch_actions, MPlist *macros)
908 if (MPLIST_MTEXT_P (keylist))
910 MText *mt = MPLIST_MTEXT (keylist);
912 len = mtext_nchars (mt);
913 if (len == 0 || len != mtext_nbytes (mt))
914 MERROR (MERROR_IM, -1);
915 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
916 for (i = 0; i < len; i++)
917 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
919 else if (MPLIST_PLIST_P (keylist))
921 MPlist *elt = MPLIST_PLIST (keylist);
923 len = MPLIST_LENGTH (elt);
925 MERROR (MERROR_IM, -1);
926 keyseq = (MSymbol *) alloca (sizeof (int) * len);
927 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
929 if (MPLIST_INTEGER_P (elt))
931 int c = MPLIST_INTEGER (elt);
933 if (c < 0 || c >= 0x100)
934 MERROR (MERROR_IM, -1);
935 keyseq[i] = one_char_symbol[c];
937 else if (MPLIST_SYMBOL_P (elt))
938 keyseq[i] = MPLIST_SYMBOL (elt);
940 MERROR (MERROR_IM, -1);
944 MERROR (MERROR_IM, -1);
946 for (i = 0; i < len; i++)
948 MIMMap *deeper = NULL;
951 deeper = mplist_get (map->submaps, keyseq[i]);
953 map->submaps = mplist ();
956 /* Fixme: It is better to make all deeper maps at once. */
957 MSTRUCT_CALLOC (deeper, MERROR_IM);
958 mplist_put (map->submaps, keyseq[i], deeper);
963 /* We reach a terminal map. */
965 || map->branch_actions)
966 /* This map is already defined. We avoid overriding it. */
969 if (! MPLIST_TAIL_P (map_actions))
971 if (parse_action_list (map_actions, macros) < 0)
972 MERROR (MERROR_IM, -1);
973 map->map_actions = map_actions;
977 map->branch_actions = branch_actions;
978 M17N_OBJECT_REF (branch_actions);
984 /* Load a branch from PLIST into MAP. PLIST has this form:
985 PLIST ::= ( MAP-NAME BRANCH-ACTION * )
986 MAPS is a plist of raw maps.
987 STATE is the current state. */
990 load_branch (MPlist *plist, MPlist *maps, MIMMap *map,
991 MSymbol language, MSymbol name, MPlist *macros)
994 MPlist *branch_actions;
996 if (! MPLIST_SYMBOL_P (plist))
997 MERROR (MERROR_IM, -1);
998 map_name = MPLIST_SYMBOL (plist);
999 plist = MPLIST_NEXT (plist);
1000 if (MPLIST_TAIL_P (plist))
1001 branch_actions = NULL;
1002 else if (parse_action_list (plist, macros) < 0)
1003 MERROR (MERROR_IM, -1);
1005 branch_actions = plist;
1006 if (map_name == Mnil)
1008 map->branch_actions = branch_actions;
1010 M17N_OBJECT_REF (branch_actions);
1012 else if (map_name == Mt)
1014 map->map_actions = branch_actions;
1016 M17N_OBJECT_REF (branch_actions);
1018 else if ((plist = (MPlist *) mplist_get (maps, map_name)))
1020 MPLIST_DO (plist, plist)
1022 MPlist *keylist, *map_actions;
1024 if (! MPLIST_PLIST_P (plist))
1025 MERROR (MERROR_IM, -1);
1026 keylist = MPLIST_PLIST (plist);
1027 map_actions = MPLIST_NEXT (keylist);
1028 if (MPLIST_SYMBOL_P (keylist))
1030 MSymbol command = MPLIST_SYMBOL (keylist);
1031 MPlist *pl = resolve_command (language, name, command);
1036 if (load_translation (map, pl, map_actions, branch_actions,
1038 MERROR (MERROR_IM, -1);
1041 if (load_translation (map, keylist, map_actions, branch_actions,
1043 MERROR (MERROR_IM, -1);
1050 /* Load a macro from PLIST into MACROS.
1051 PLIST has this from:
1052 PLIST ::= ( MACRO-NAME ACTION * )
1053 MACROS is a plist of macro names vs action list. */
1055 load_macros (MPlist *plist, MPlist *macros)
1060 if (! MPLIST_SYMBOL_P (plist))
1061 MERROR (MERROR_IM, -1);
1062 name = MPLIST_SYMBOL (plist);
1063 plist = MPLIST_NEXT (plist);
1064 if (MPLIST_TAIL_P (plist)
1065 || parse_action_list (plist, macros) < 0)
1066 MERROR (MERROR_IM, -1);
1067 pl = mplist_get (macros, name);
1069 M17N_OBJECT_UNREF (pl);
1070 mplist_put (macros, name, plist);
1071 M17N_OBJECT_REF (plist);
1075 /* Load an external module from PLIST into EXTERNALS.
1076 PLIST has this form:
1077 PLIST ::= ( MODULE-NAME FUNCTION * )
1078 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
1081 load_external_module (MPlist *plist, MPlist *externals)
1086 MIMExternalModule *external;
1090 if (MPLIST_MTEXT_P (plist))
1091 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1092 else if (MPLIST_SYMBOL_P (plist))
1093 module = MPLIST_SYMBOL (plist);
1094 module_file = alloca (strlen (MSYMBOL_NAME (module))
1095 + strlen (DLOPEN_SHLIB_EXT) + 1);
1096 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1098 handle = dlopen (module_file, RTLD_NOW);
1101 fprintf (stderr, "%s\n", dlerror ());
1102 MERROR (MERROR_IM, -1);
1104 func_list = mplist ();
1105 MPLIST_DO (plist, MPLIST_NEXT (plist))
1107 if (! MPLIST_SYMBOL_P (plist))
1108 MERROR_GOTO (MERROR_IM, err_label);
1109 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1111 MERROR_GOTO (MERROR_IM, err_label);
1112 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1115 MSTRUCT_MALLOC (external, MERROR_IM);
1116 external->handle = handle;
1117 external->func_list = func_list;
1118 mplist_add (externals, module, external);
1123 M17N_OBJECT_UNREF (func_list);
1128 free_map (MIMMap *map, int top)
1133 M17N_OBJECT_UNREF (map->map_actions);
1136 MPLIST_DO (plist, map->submaps)
1137 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1138 M17N_OBJECT_UNREF (map->submaps);
1140 M17N_OBJECT_UNREF (map->branch_actions);
1145 free_state (void *object)
1147 MIMState *state = object;
1150 M17N_OBJECT_UNREF (state->title);
1152 free_map (state->map, 1);
1156 /** Load a state from PLIST into a newly allocated state object.
1157 PLIST has this form:
1158 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1159 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1160 MAPS is a plist of defined maps.
1161 Return the state object. */
1164 load_state (MPlist *plist, MPlist *maps, MSymbol language, MSymbol name,
1169 if (! MPLIST_SYMBOL_P (plist))
1170 MERROR (MERROR_IM, NULL);
1171 M17N_OBJECT (state, free_state, MERROR_IM);
1172 state->name = MPLIST_SYMBOL (plist);
1173 plist = MPLIST_NEXT (plist);
1174 if (MPLIST_MTEXT_P (plist))
1176 state->title = MPLIST_MTEXT (plist);
1177 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1178 Mlanguage, language);
1179 M17N_OBJECT_REF (state->title);
1180 plist = MPLIST_NEXT (plist);
1182 MSTRUCT_CALLOC (state->map, MERROR_IM);
1183 MPLIST_DO (plist, plist)
1184 if (! MPLIST_PLIST_P (plist)
1185 || load_branch (MPLIST_PLIST (plist), maps, state->map, language, name,
1187 MERROR (MERROR_IM, NULL);
1192 static MPlist *im_info_list;
1195 free_im_info (MInputMethodInfo *im_info)
1200 M17N_OBJECT_UNREF (im_info->title);
1201 if (im_info->states)
1203 MPLIST_DO (plist, im_info->states)
1205 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1207 M17N_OBJECT_UNREF (state);
1209 M17N_OBJECT_UNREF (im_info->states);
1212 if (im_info->macros)
1214 MPLIST_DO (plist, im_info->macros)
1215 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1216 M17N_OBJECT_UNREF (im_info->macros);
1219 if (im_info->externals)
1221 MPLIST_DO (plist, im_info->externals)
1223 MIMExternalModule *external = MPLIST_VAL (plist);
1225 dlclose (external->handle);
1226 M17N_OBJECT_UNREF (external->func_list);
1228 MPLIST_KEY (plist) = Mt;
1230 M17N_OBJECT_UNREF (im_info->externals);
1234 MPLIST_DO (plist, im_info->maps)
1236 MPlist *p = MPLIST_PLIST (plist);
1238 M17N_OBJECT_UNREF (p);
1240 M17N_OBJECT_UNREF (im_info->maps);
1246 static MInputMethodInfo *get_im_info (MSymbol language, MSymbol name,
1249 static MInputMethodInfo *
1250 get_im_info_by_tags (MPlist *plist)
1255 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1256 i++, plist = MPLIST_NEXT (plist))
1257 tag[i] = MPLIST_SYMBOL (plist);
1262 return get_im_info (tag[0], tag[1], tag[2]);
1265 /* Load an input method from PLIST into IM_INTO, and return it. */
1267 static MInputMethodInfo *
1268 load_im_info (MSymbol language, MSymbol name, MPlist *plist)
1270 MInputMethodInfo *im_info;
1271 MText *title = NULL;
1272 MPlist *maps = NULL;
1273 MPlist *states = NULL;
1274 MPlist *externals = NULL;
1275 MPlist *macros = NULL;
1278 MSTRUCT_CALLOC (im_info, MERROR_IM);
1280 while (MPLIST_PLIST_P (plist))
1282 elt = MPLIST_PLIST (plist);
1283 if (! MPLIST_SYMBOL_P (elt))
1284 MERROR_GOTO (MERROR_IM, err);
1285 if (MPLIST_SYMBOL (elt) == Mtitle)
1287 elt = MPLIST_NEXT (elt);
1288 if (! MPLIST_MTEXT_P (elt))
1289 MERROR_GOTO (MERROR_IM, err);
1290 im_info->title = title = MPLIST_MTEXT (elt);
1291 M17N_OBJECT_REF (title);
1293 else if (MPLIST_SYMBOL (elt) == Mmap)
1295 MPlist *pl = mplist__from_alist (MPLIST_NEXT (elt));
1298 MERROR_GOTO (MERROR_IM, err);
1300 im_info->maps = maps = pl;
1302 maps = mplist__conc (maps, pl);
1304 else if (MPLIST_SYMBOL (elt) == Mmacro)
1307 im_info->macros = macros = mplist ();
1308 MPLIST_DO (elt, MPLIST_NEXT (elt))
1310 if (! MPLIST_PLIST_P (elt)
1311 || load_macros (MPLIST_PLIST (elt), macros) < 0)
1312 MERROR_GOTO (MERROR_IM, err);
1315 else if (MPLIST_SYMBOL (elt) == Mmodule)
1318 im_info->externals = externals = mplist ();
1319 MPLIST_DO (elt, MPLIST_NEXT (elt))
1321 if (! MPLIST_PLIST_P (elt)
1322 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
1323 MERROR_GOTO (MERROR_IM, err);
1326 else if (MPLIST_SYMBOL (elt) == Mstate)
1328 MPLIST_DO (elt, MPLIST_NEXT (elt))
1332 if (! MPLIST_PLIST_P (elt))
1333 MERROR_GOTO (MERROR_IM, err);
1334 state = load_state (MPLIST_PLIST (elt), maps, language, name,
1337 MERROR_GOTO (MERROR_IM, err);
1339 im_info->states = states = mplist ();
1340 mplist_put (states, state->name, state);
1343 else if (MPLIST_SYMBOL (elt) == Minclude)
1345 /* elt ::= include (tag1 tag2 ...) key item ... */
1347 MInputMethodInfo *temp;
1350 elt = MPLIST_NEXT (elt);
1351 if (! MPLIST_PLIST_P (elt))
1352 MERROR_GOTO (MERROR_IM, err);
1353 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
1355 MERROR_GOTO (MERROR_IM, err);
1356 elt = MPLIST_NEXT (elt);
1357 if (! MPLIST_SYMBOL_P (elt))
1358 MERROR_GOTO (MERROR_IM, err);
1359 key = MPLIST_SYMBOL (elt);
1360 elt = MPLIST_NEXT (elt);
1364 im_info->maps = maps = mplist ();
1365 MPLIST_DO (pl, temp->maps)
1367 p = MPLIST_VAL (pl);
1368 MPLIST_ADD_PLIST (maps, MPLIST_KEY (pl), p);
1369 M17N_OBJECT_REF (p);
1372 else if (key == Mmacro)
1375 im_info->macros = macros = mplist ();
1376 MPLIST_DO (pl, temp->macros)
1378 p = MPLIST_VAL (pl);
1379 MPLIST_ADD_PLIST (macros, MPLIST_KEY (pl), p);
1380 M17N_OBJECT_REF (p);
1383 else if (key == Mstate)
1386 im_info->states = states = mplist ();
1387 MPLIST_DO (pl, temp->states)
1389 MIMState *state = MPLIST_VAL (pl);
1391 mplist_add (states, MPLIST_KEY (pl), state);
1392 M17N_OBJECT_REF (state);
1396 MERROR_GOTO (MERROR_IM, err);
1398 plist = MPLIST_NEXT (plist);
1403 if (! title && name)
1405 = title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
1406 MTEXT_FORMAT_US_ASCII);
1410 free_im_info (im_info);
1416 static int take_action_list (MInputContext *ic, MPlist *action_list);
1417 static void preedit_commit (MInputContext *ic);
1420 shift_state (MInputContext *ic, MSymbol state_name)
1422 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1423 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1424 MIMState *orig_state = ic_info->state, *state;
1426 /* Find a state to shift to. If not found, shift to the initial
1428 if (state_name == Mt)
1430 if (! ic_info->prev_state)
1432 state = ic_info->prev_state;
1436 state = (MIMState *) mplist_get (im_info->states, state_name);
1438 state = (MIMState *) MPLIST_VAL (im_info->states);
1441 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
1443 /* Enter the new state. */
1444 ic_info->state = state;
1445 ic_info->map = state->map;
1446 ic_info->state_key_head = ic_info->key_head;
1447 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1448 /* We have shifted to the initial state. */
1449 preedit_commit (ic);
1450 mtext_cpy (ic_info->preedit_saved, ic->preedit);
1451 ic_info->state_pos = ic->cursor_pos;
1452 if (state != orig_state )
1454 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1455 ic_info->prev_state = NULL;
1457 ic_info->prev_state = orig_state;
1460 ic->status = state->title;
1462 ic->status = im_info->title;
1463 ic->status_changed = 1;
1464 if (ic_info->map == ic_info->state->map
1465 && ic_info->map->map_actions)
1467 MDEBUG_PRINT (" init-actions:");
1468 take_action_list (ic, ic_info->map->map_actions);
1473 /* Find a candidate group that contains a candidate number INDEX from
1474 PLIST. Set START_INDEX to the first candidate number of the group,
1475 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
1476 candidate group number if they are non-NULL. If INDEX is -1, find
1477 the last candidate group. */
1480 find_candidates_group (MPlist *plist, int index,
1481 int *start_index, int *end_index, int *group_index)
1483 int i = 0, gidx = 0, len;
1485 MPLIST_DO (plist, plist)
1487 if (MPLIST_MTEXT_P (plist))
1488 len = mtext_nchars (MPLIST_MTEXT (plist));
1490 len = mplist_length (MPLIST_PLIST (plist));
1491 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
1497 *end_index = i + len;
1499 *group_index = gidx;
1509 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
1511 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1513 int nchars = mt ? mtext_nchars (mt) : 1;
1516 mtext_ins (ic->preedit, pos, mt);
1518 mtext_ins_char (ic->preedit, pos, c, 1);
1519 MPLIST_DO (markers, ic_info->markers)
1520 if (MPLIST_INTEGER (markers) > pos)
1521 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
1522 if (ic->cursor_pos >= pos)
1523 ic->cursor_pos += nchars;
1524 ic->preedit_changed = 1;
1529 preedit_delete (MInputContext *ic, int from, int to)
1531 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1534 mtext_del (ic->preedit, from, to);
1535 MPLIST_DO (markers, ic_info->markers)
1537 if (MPLIST_INTEGER (markers) > to)
1538 MPLIST_VAL (markers)
1539 = (void *) (MPLIST_INTEGER (markers) - (to - from));
1540 else if (MPLIST_INTEGER (markers) > from);
1541 MPLIST_VAL (markers) = (void *) from;
1543 if (ic->cursor_pos >= to)
1544 ic->cursor_pos -= to - from;
1545 else if (ic->cursor_pos > from)
1546 ic->cursor_pos = from;
1547 ic->preedit_changed = 1;
1551 preedit_commit (MInputContext *ic)
1553 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1554 int preedit_len = mtext_nchars (ic->preedit);
1556 if (preedit_len > 0)
1560 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1561 Mcandidate_list, NULL, 0);
1562 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1563 Mcandidate_index, NULL, 0);
1564 mtext_cat (ic->produced, ic->preedit);
1565 if ((mdebug__flag & mdebug_mask)
1566 && mtext_nchars (ic->produced) > 0)
1570 MDEBUG_PRINT (" (produced");
1571 for (i = 0; i < mtext_nchars (ic->produced); i++)
1572 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
1575 mtext_reset (ic->preedit);
1576 mtext_reset (ic_info->preedit_saved);
1577 MPLIST_DO (p, ic_info->markers)
1579 ic->cursor_pos = ic_info->state_pos = 0;
1580 ic->preedit_changed = 1;
1582 if (ic->candidate_list)
1584 M17N_OBJECT_UNREF (ic->candidate_list);
1585 ic->candidate_list = NULL;
1586 ic->candidate_show = 0;
1587 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
1588 if (ic->candidate_show)
1590 ic->candidate_show = 0;
1591 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
1595 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
1596 sizeof (int) * (ic_info->used - ic_info->key_head));
1597 ic_info->used -= ic_info->key_head;
1598 ic_info->state_key_head = ic_info->key_head = 0;
1602 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
1604 int code = marker_code (sym);
1606 if (mt && (code == '[' || code == ']'))
1610 if (code == '[' && current > 0)
1612 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
1616 else if (code == ']' && current < mtext_nchars (mt))
1618 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
1624 return (code == '<' ? 0
1625 : code == '>' ? limit
1626 : code == '-' ? current - 1
1627 : code == '+' ? current + 1
1628 : code == '=' ? current
1629 : code - '0' > limit ? limit
1633 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1637 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1639 int from = mtext_property_start (prop);
1640 int to = mtext_property_end (prop);
1642 MPlist *candidate_list = mtext_property_value (prop);
1643 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1645 int ingroup_index = idx - start;
1648 preedit_delete (ic, from, to);
1649 if (MPLIST_MTEXT_P (group))
1651 mt = MPLIST_MTEXT (group);
1652 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1660 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1661 i++, plist = MPLIST_NEXT (plist));
1662 mt = MPLIST_MTEXT (plist);
1663 preedit_insert (ic, from, mt, 0);
1664 to = from + mtext_nchars (mt);
1666 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1667 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1668 ic->cursor_pos = to;
1672 get_select_charset (MInputContextInfo * ic_info)
1674 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
1677 if (! MPLIST_VAL (plist))
1679 sym = MPLIST_SYMBOL (plist);
1682 return MCHARSET (sym);
1686 adjust_candidates (MPlist *plist, MCharset *charset)
1690 /* plist ::= MTEXT ... | PLIST ... */
1691 plist = mplist_copy (plist);
1692 if (MPLIST_MTEXT_P (plist))
1695 while (! MPLIST_TAIL_P (pl))
1697 /* pl ::= MTEXT ... */
1698 MText *mt = MPLIST_MTEXT (pl);
1702 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1704 c = mtext_ref_char (mt, i);
1705 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1709 mt = mtext_dup (mt);
1710 mplist_set (pl, Mtext, mt);
1711 M17N_OBJECT_UNREF (mt);
1714 mtext_del (mt, i, i + 1);
1717 if (mtext_len (mt) > 0)
1718 pl = MPLIST_NEXT (pl);
1722 M17N_OBJECT_UNREF (mt);
1726 else /* MPLIST_PLIST_P (plist) */
1729 while (! MPLIST_TAIL_P (pl))
1731 /* pl ::= (MTEXT ...) ... */
1732 MPlist *p = MPLIST_PLIST (pl);
1734 /* p ::= MTEXT ... */
1738 while (! MPLIST_TAIL_P (p0))
1740 MText *mt = MPLIST_MTEXT (p0);
1743 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1745 c = mtext_ref_char (mt, i);
1746 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1751 p0 = MPLIST_NEXT (p0);
1758 p = mplist_copy (p);
1759 mplist_set (pl, Mplist, p);
1760 M17N_OBJECT_UNREF (p);
1764 p0 = MPLIST_NEXT (p0);
1767 M17N_OBJECT_UNREF (mt);
1770 if (! MPLIST_TAIL_P (p))
1771 pl = MPLIST_NEXT (pl);
1775 M17N_OBJECT_UNREF (p);
1779 if (MPLIST_TAIL_P (plist))
1781 M17N_OBJECT_UNREF (plist);
1788 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
1790 MCharset *charset = get_select_charset (ic_info);
1795 plist = resolve_variable (ic_info, Mcandidates_group_size);
1796 column = MPLIST_INTEGER (plist);
1798 plist = MPLIST_PLIST (args);
1801 if (! (plist = adjust_candidates (plist, charset)))
1805 M17N_OBJECT_REF (plist);
1809 if (MPLIST_MTEXT_P (plist))
1811 MText *mt = MPLIST_MTEXT (plist);
1812 MPlist *next = MPLIST_NEXT (plist);
1814 if (MPLIST_TAIL_P (next))
1815 M17N_OBJECT_REF (mt);
1818 mt = mtext_dup (mt);
1819 while (! MPLIST_TAIL_P (next))
1821 mt = mtext_cat (mt, MPLIST_MTEXT (next));
1822 next = MPLIST_NEXT (next);
1825 M17N_OBJECT_UNREF (plist);
1827 len = mtext_nchars (mt);
1829 mplist_add (plist, Mtext, mt);
1832 for (i = 0; i < len; i += column)
1834 int to = (i + column < len ? i + column : len);
1835 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
1837 mplist_add (plist, Mtext, sub);
1838 M17N_OBJECT_UNREF (sub);
1841 M17N_OBJECT_UNREF (mt);
1843 else /* MPLIST_PLIST_P (plist) */
1845 MPlist *pl = MPLIST_PLIST (plist), *p;
1846 MPlist *next = MPLIST_NEXT (plist);
1849 if (MPLIST_TAIL_P (next))
1850 M17N_OBJECT_REF (pl);
1853 pl = mplist_copy (pl);
1854 while (! MPLIST_TAIL_P (next))
1856 p = mplist_copy (MPLIST_PLIST (next));
1857 pl = mplist__conc (pl, p);
1858 M17N_OBJECT_UNREF (p);
1859 next = MPLIST_NEXT (next);
1862 M17N_OBJECT_UNREF (plist);
1864 len = mplist_length (pl);
1866 mplist_add (plist, Mplist, pl);
1871 for (i = 0; i < len; i += column)
1874 mplist_add (plist, Mplist, p);
1875 M17N_OBJECT_UNREF (p);
1876 for (j = 0; j < column && i + j < len; j++)
1878 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
1879 p0 = MPLIST_NEXT (p0);
1883 M17N_OBJECT_UNREF (pl);
1892 regularize_action (MPlist *action_list)
1894 MPlist *action = NULL;
1898 if (MPLIST_PLIST_P (action_list))
1900 action = MPLIST_PLIST (action_list);
1901 if (MPLIST_SYMBOL_P (action))
1903 name = MPLIST_SYMBOL (action);
1904 args = MPLIST_NEXT (action);
1906 && MPLIST_PLIST_P (args))
1907 mplist_set (action, Msymbol, M_candidates);
1909 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
1912 mplist_push (action, Mplist, MPLIST_VAL (action_list));
1913 mplist_push (action, Msymbol, M_candidates);
1914 mplist_set (action_list, Mplist, action);
1915 M17N_OBJECT_UNREF (action);
1918 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
1921 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
1922 mplist_push (action, Msymbol, Minsert);
1923 mplist_set (action_list, Mplist, action);
1924 M17N_OBJECT_UNREF (action);
1930 take_action_list (MInputContext *ic, MPlist *action_list)
1932 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1933 MPlist *candidate_list = ic->candidate_list;
1934 int candidate_index = ic->candidate_index;
1935 int candidate_show = ic->candidate_show;
1936 MTextProperty *prop;
1938 MPLIST_DO (action_list, action_list)
1940 MPlist *action = regularize_action (action_list);
1946 name = MPLIST_SYMBOL (action);
1947 args = MPLIST_NEXT (action);
1949 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1950 if (name == Minsert)
1952 if (MPLIST_SYMBOL_P (args))
1954 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
1955 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
1958 if (MPLIST_MTEXT_P (args))
1959 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1960 else /* MPLIST_INTEGER_P (args)) */
1961 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1963 else if (name == M_candidates)
1965 MPlist *plist = get_candidate_list (ic_info, args);
1970 if (MPLIST_MTEXT_P (plist))
1972 preedit_insert (ic, ic->cursor_pos, NULL,
1973 mtext_ref_char (MPLIST_MTEXT (plist), 0));
1978 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
1980 preedit_insert (ic, ic->cursor_pos, mt, 0);
1981 len = mtext_nchars (mt);
1983 mtext_put_prop (ic->preedit,
1984 ic->cursor_pos - len, ic->cursor_pos,
1985 Mcandidate_list, plist);
1986 mtext_put_prop (ic->preedit,
1987 ic->cursor_pos - len, ic->cursor_pos,
1988 Mcandidate_index, (void *) 0);
1989 M17N_OBJECT_UNREF (plist);
1991 else if (name == Mselect)
1994 int code, idx, gindex;
1995 int pos = ic->cursor_pos;
1999 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2002 if (MPLIST_SYMBOL_P (args))
2004 code = marker_code (MPLIST_SYMBOL (args));
2010 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2011 group = find_candidates_group (mtext_property_value (prop), idx,
2012 &start, &end, &gindex);
2014 if (code != '[' && code != ']')
2018 ? new_index (NULL, ic->candidate_index - start,
2019 end - start - 1, MPLIST_SYMBOL (args),
2021 : MPLIST_INTEGER (args)));
2024 find_candidates_group (mtext_property_value (prop), -1,
2029 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2034 int ingroup_index = idx - start;
2037 group = mtext_property_value (prop);
2038 len = mplist_length (group);
2051 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2052 idx += (MPLIST_MTEXT_P (group)
2053 ? mtext_nchars (MPLIST_MTEXT (group))
2054 : mplist_length (MPLIST_PLIST (group)));
2055 len = (MPLIST_MTEXT_P (group)
2056 ? mtext_nchars (MPLIST_MTEXT (group))
2057 : mplist_length (MPLIST_PLIST (group)));
2058 if (ingroup_index >= len)
2059 ingroup_index = len - 1;
2060 idx += ingroup_index;
2062 update_candidate (ic, prop, idx);
2064 else if (name == Mshow)
2065 ic->candidate_show = 1;
2066 else if (name == Mhide)
2067 ic->candidate_show = 0;
2068 else if (name == Mdelete)
2070 int len = mtext_nchars (ic->preedit);
2074 if (MPLIST_SYMBOL_P (args)
2075 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
2077 delete_surrounding_text (ic, pos);
2081 to = (MPLIST_SYMBOL_P (args)
2082 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2084 : MPLIST_INTEGER (args));
2089 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
2090 if (to < ic->cursor_pos)
2091 preedit_delete (ic, to, ic->cursor_pos);
2092 else if (to > ic->cursor_pos)
2093 preedit_delete (ic, ic->cursor_pos, to);
2096 else if (name == Mmove)
2098 int len = mtext_nchars (ic->preedit);
2100 = (MPLIST_SYMBOL_P (args)
2101 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2103 : MPLIST_INTEGER (args));
2109 if (pos != ic->cursor_pos)
2111 ic->cursor_pos = pos;
2112 ic->preedit_changed = 1;
2115 else if (name == Mmark)
2117 int code = marker_code (MPLIST_SYMBOL (args));
2120 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
2121 (void *) ic->cursor_pos);
2123 else if (name == Mpushback)
2125 if (MPLIST_INTEGER_P (args))
2127 int num = MPLIST_INTEGER (args);
2130 ic_info->key_head -= num;
2132 ic_info->key_head = num;
2133 if (ic_info->key_head > ic_info->used)
2134 ic_info->key_head = ic_info->used;
2136 else if (MPLIST_MTEXT_P (args))
2138 MText *mt = MPLIST_MTEXT (args);
2139 int i, len = mtext_nchars (mt);
2142 ic_info->key_head--;
2143 for (i = 0; i < len; i++)
2145 key = one_char_symbol[MTEXT_DATA (mt)[i]];
2146 if (ic_info->key_head + i < ic_info->used)
2147 ic_info->keys[ic_info->key_head + i] = key;
2149 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2154 MPlist *plist = MPLIST_PLIST (args), *pl;
2158 ic_info->key_head--;
2160 MPLIST_DO (pl, plist)
2162 key = MPLIST_SYMBOL (pl);
2163 if (ic_info->key_head < ic_info->used)
2164 ic_info->keys[ic_info->key_head + i] = key;
2166 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2171 else if (name == Mcall)
2173 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2174 MIMExternalFunc func = NULL;
2175 MSymbol module, func_name;
2176 MPlist *func_args, *val;
2179 module = MPLIST_SYMBOL (args);
2180 args = MPLIST_NEXT (args);
2181 func_name = MPLIST_SYMBOL (args);
2183 if (im_info->externals)
2185 MIMExternalModule *external
2186 = (MIMExternalModule *) mplist_get (im_info->externals,
2189 func = (MIMExternalFunc) mplist_get (external->func_list,
2194 func_args = mplist ();
2195 mplist_add (func_args, Mt, ic);
2196 MPLIST_DO (args, MPLIST_NEXT (args))
2200 if (MPLIST_KEY (args) == Msymbol
2201 && MPLIST_KEY (args) != Mnil
2202 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
2204 code = new_index (ic, ic->cursor_pos,
2205 mtext_nchars (ic->preedit),
2206 MPLIST_SYMBOL (args), ic->preedit);
2207 mplist_add (func_args, Minteger, (void *) code);
2210 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
2212 val = (func) (func_args);
2213 M17N_OBJECT_UNREF (func_args);
2214 if (val && ! MPLIST_TAIL_P (val))
2215 ret = take_action_list (ic, val);
2216 M17N_OBJECT_UNREF (val);
2220 else if (name == Mshift)
2222 shift_state (ic, MPLIST_SYMBOL (args));
2224 else if (name == Mundo)
2226 int intarg = (MPLIST_TAIL_P (args)
2228 : integer_value (ic, args, NULL, 0));
2230 mtext_reset (ic->preedit);
2231 mtext_reset (ic_info->preedit_saved);
2232 ic->cursor_pos = ic_info->state_pos = 0;
2233 ic_info->state_key_head = ic_info->key_head = 0;
2236 ic_info->used += intarg;
2238 ic_info->used = intarg;
2239 shift_state (ic, Mnil);
2242 else if (name == Mset || name == Madd || name == Msub
2243 || name == Mmul || name == Mdiv)
2245 MSymbol sym = MPLIST_SYMBOL (args);
2250 val1 = integer_value (ic, args, &value, 0);
2251 args = MPLIST_NEXT (args);
2252 val2 = resolve_expression (ic, args);
2254 val1 = val2, op = "=";
2255 else if (name == Madd)
2256 val1 += val2, op = "+=";
2257 else if (name == Msub)
2258 val1 -= val2, op = "-=";
2259 else if (name == Mmul)
2260 val1 *= val2, op = "*=";
2262 val1 /= val2, op = "/=";
2263 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
2264 MSYMBOL_NAME (sym), op, val1, val1);
2266 mplist_set (value, Minteger, (void *) val1);
2268 else if (name == Mequal || name == Mless || name == Mgreater
2269 || name == Mless_equal || name == Mgreater_equal)
2272 MPlist *actions1, *actions2;
2275 val1 = resolve_expression (ic, args);
2276 args = MPLIST_NEXT (args);
2277 val2 = resolve_expression (ic, args);
2278 args = MPLIST_NEXT (args);
2279 actions1 = MPLIST_PLIST (args);
2280 args = MPLIST_NEXT (args);
2281 if (MPLIST_TAIL_P (args))
2284 actions2 = MPLIST_PLIST (args);
2285 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
2286 if (name == Mequal ? val1 == val2
2287 : name == Mless ? val1 < val2
2288 : name == Mgreater ? val1 > val2
2289 : name == Mless_equal ? val1 <= val2
2292 MDEBUG_PRINT ("ok");
2293 ret = take_action_list (ic, actions1);
2297 MDEBUG_PRINT ("no");
2299 ret = take_action_list (ic, actions2);
2304 else if (name == Mcond)
2308 MPLIST_DO (args, args)
2313 if (! MPLIST_PLIST (args))
2315 cond = MPLIST_PLIST (args);
2316 if (resolve_expression (ic, cond) != 0)
2318 MDEBUG_PRINT1 ("(%dth)", idx);
2319 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
2325 else if (name == Mcommit)
2327 preedit_commit (ic);
2329 else if (name == Munhandle)
2331 preedit_commit (ic);
2336 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2340 && (actions = mplist_get (im_info->macros, name)))
2342 if (take_action_list (ic, actions) < 0)
2349 if (ic->candidate_list)
2351 M17N_OBJECT_UNREF (ic->candidate_list);
2352 ic->candidate_list = NULL;
2354 if (ic->cursor_pos > 0
2355 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
2358 ic->candidate_list = mtext_property_value (prop);
2359 M17N_OBJECT_REF (ic->candidate_list);
2361 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
2363 ic->candidate_from = mtext_property_start (prop);
2364 ic->candidate_to = mtext_property_end (prop);
2367 if (candidate_list != ic->candidate_list)
2368 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
2369 if (candidate_index != ic->candidate_index)
2370 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
2371 if (candidate_show != ic->candidate_show)
2372 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2377 /* Handle the input key KEY in the current state and map specified in
2378 the input context IC. If KEY is handled correctly, return 0.
2379 Otherwise, return -1. */
2382 handle_key (MInputContext *ic)
2384 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2385 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2386 MIMMap *map = ic_info->map;
2387 MIMMap *submap = NULL;
2388 MSymbol key = ic_info->keys[ic_info->key_head];
2389 MSymbol alias = Mnil;
2392 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
2393 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
2397 submap = mplist_get (map->submaps, key);
2398 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
2399 submap = mplist_get (map->submaps, alias);
2405 MDEBUG_PRINT (" submap-found");
2407 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
2408 mtext_cpy (ic->preedit, ic_info->preedit_saved);
2409 ic->preedit_changed = 1;
2410 ic->cursor_pos = ic_info->state_pos;
2411 ic_info->key_head++;
2412 ic_info->map = map = submap;
2413 if (map->map_actions)
2415 MDEBUG_PRINT (" map-actions:");
2416 if (take_action_list (ic, map->map_actions) < 0)
2418 MDEBUG_PRINT ("\n");
2422 else if (map->submaps)
2424 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
2426 MSymbol key = ic_info->keys[i];
2427 char *name = msymbol_name (key);
2429 if (! name[0] || ! name[1])
2430 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
2434 /* If this is the terminal map or we have shifted to another
2435 state, perform branch actions (if any). */
2436 if (! map->submaps || map != ic_info->map)
2438 if (map->branch_actions)
2440 MDEBUG_PRINT (" branch-actions:");
2441 if (take_action_list (ic, map->branch_actions) < 0)
2443 MDEBUG_PRINT ("\n");
2447 /* If MAP is still not the root map, shift to the current
2449 if (ic_info->map != ic_info->state->map)
2450 shift_state (ic, ic_info->state->name);
2455 /* MAP can not handle KEY. */
2457 /* If MAP is the root map of the initial state, it means that
2458 the current input method can not handle KEY. */
2459 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
2461 MDEBUG_PRINT (" unhandled\n");
2465 if (map != ic_info->state->map)
2467 /* If MAP is not the root map... */
2468 /* If MAP has branch actions, perform them. */
2469 if (map->branch_actions)
2471 MDEBUG_PRINT (" branch-actions:");
2472 if (take_action_list (ic, map->branch_actions) < 0)
2474 MDEBUG_PRINT ("\n");
2478 /* If MAP is still not the root map, shift to the current
2480 if (ic_info->map != ic_info->state->map)
2482 shift_state (ic, ic_info->state->name);
2483 /* If MAP has branch_actions, perform them. */
2484 if (ic_info->map->branch_actions)
2486 MDEBUG_PRINT (" brank-actions:");
2487 if (take_action_list (ic, ic_info->map->branch_actions) < 0)
2494 /* MAP is the root map, perform branch actions (if any) or
2495 shift to the initial state. */
2496 if (map->branch_actions)
2498 MDEBUG_PRINT (" branch-actions:");
2499 if (take_action_list (ic, map->branch_actions) < 0)
2501 MDEBUG_PRINT ("\n");
2506 shift_state (ic, Mnil);
2509 MDEBUG_PRINT ("\n");
2514 reset_ic (MInputContext *ic, MSymbol ignore)
2516 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2517 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2520 MDEBUG_PRINT ("\n [IM] reset\n");
2522 ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
2523 ic_info->prev_state = NULL;
2524 ic_info->map = ic_info->state->map;
2525 ic_info->state_key_head = ic_info->key_head;
2526 MLIST_RESET (ic_info);
2527 ic_info->key_unhandled = 0;
2529 if (mtext_nchars (ic->produced) > 0)
2530 mtext_reset (ic->produced);
2531 if (mtext_nchars (ic->preedit) > 0)
2535 mtext_reset (ic->preedit);
2536 MPLIST_DO (plist, ic_info->markers)
2537 MPLIST_VAL (plist) = 0;
2538 ic->preedit_changed = 1;
2540 if (ic->candidate_show)
2542 ic->candidate_show = 0;
2543 ic->candidates_changed = MINPUT_CANDIDATES_SHOW_CHANGED;
2544 if (ic->candidate_list)
2546 M17N_OBJECT_UNREF (ic->candidate_list);
2547 ic->candidate_list = NULL;
2548 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
2551 mtext_reset (ic_info->preedit_saved);
2552 ic_info->state_pos = ic->cursor_pos = 0;
2554 status = ic_info->state->title ? ic_info->state->title : im_info->title;
2555 if (ic->status != status)
2557 ic->status = status;
2558 ic->status_changed = 1;
2563 open_im (MInputMethod *im)
2565 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil);
2568 MERROR (MERROR_IM, -1);
2575 close_im (MInputMethod *im)
2581 create_ic (MInputContext *ic)
2583 MInputMethod *im = ic->im;
2584 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
2585 MInputContextInfo *ic_info;
2589 ic_info = (MInputContextInfo *) ic->info;
2592 MSTRUCT_CALLOC (ic_info, MERROR_IM);
2595 MLIST_INIT1 (ic_info, keys, 8);
2596 ic_info->markers = mplist ();
2597 ic_info->vars = mplist ();
2598 plist = get_nested_list (im->language, im->name, Mnil, M_variable);
2599 MPLIST_DO (plist, plist)
2601 MSymbol var = MPLIST_SYMBOL (plist);
2604 plist = MPLIST_NEXT (plist);
2605 pl = MPLIST_PLIST (plist);
2606 pl = MPLIST_NEXT (pl); /* Skip description. */
2607 mplist_push (ic_info->vars, MPLIST_KEY (pl), MPLIST_VAL (pl));
2608 mplist_push (ic_info->vars, Msymbol, var);
2611 ic_info->preedit_saved = mtext ();
2612 if (im_info->externals)
2614 MPlist *func_args = mplist (), *plist;
2616 mplist_add (func_args, Mt, ic);
2617 MPLIST_DO (plist, im_info->externals)
2619 MIMExternalModule *external = MPLIST_VAL (plist);
2620 MIMExternalFunc func
2621 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
2626 M17N_OBJECT_UNREF (func_args);
2628 reset_ic (ic, Mnil);
2633 destroy_ic (MInputContext *ic)
2635 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2636 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2638 if (im_info->externals)
2640 MPlist *func_args = mplist (), *plist;
2642 mplist_add (func_args, Mt, ic);
2643 MPLIST_DO (plist, im_info->externals)
2645 MIMExternalModule *external = MPLIST_VAL (plist);
2646 MIMExternalFunc func
2647 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
2652 M17N_OBJECT_UNREF (func_args);
2654 MLIST_FREE1 (ic_info, keys);
2655 M17N_OBJECT_UNREF (ic_info->preedit_saved);
2656 M17N_OBJECT_UNREF (ic_info->markers);
2657 M17N_OBJECT_UNREF (ic_info->vars);
2658 M17N_OBJECT_UNREF (ic_info->preceding_text);
2659 M17N_OBJECT_UNREF (ic_info->following_text);
2664 /** Handle the input key KEY in the current state and map of IC->info.
2665 If KEY is handled but no text is produced, return 0, otherwise
2671 filter (MInputContext *ic, MSymbol key, void *arg)
2673 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2674 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2677 if (! ic_info->state)
2679 ic_info->key_unhandled = 1;
2682 mtext_reset (ic->produced);
2683 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
2684 M17N_OBJECT_UNREF (ic_info->preceding_text);
2685 M17N_OBJECT_UNREF (ic_info->following_text);
2686 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2687 ic_info->key_unhandled = 0;
2689 /* If KEY has Meta or Alt modifier, put M_key_alias property. */
2692 if (! msymbol_get (key, M_key_alias)
2693 && (strchr (MSYMBOL_NAME (key), 'M')
2694 || strchr (MSYMBOL_NAME (key), 'A')))
2696 char *name = MSYMBOL_NAME (key);
2699 while (name[0] && name[1] == '-'
2700 && (name[0] != 'M' && name[0] != 'A'))
2702 if ((name[0] == 'M' || name[0] == 'A') && name[1] == '-')
2707 name = alloca (MSYMBOL_NAMELEN (key) + 1);
2708 memcpy (name, MSYMBOL_NAME (key), MSYMBOL_NAMELEN (key) + 1);
2709 name[meta_or_alt - MSYMBOL_NAME (key)]
2710 = *meta_or_alt == 'M' ? 'A' : 'M';
2711 alias = msymbol (name);
2712 msymbol_put (key, M_key_alias, alias);
2715 else if (MSYMBOL_NAME (key)[0] == 'S'
2716 && MSYMBOL_NAME (key)[1] == '-'
2717 && MSYMBOL_NAME (key)[2] >= 'A' && MSYMBOL_NAME (key)[2] <= 'Z')
2718 msymbol_put (key, M_key_alias, one_char_symbol[(int)MSYMBOL_NAME (key)[2]]);
2722 if (handle_key (ic) < 0)
2724 /* KEY was not handled. Delete it from the current key sequence. */
2725 if (ic_info->used > 0)
2727 memmove (ic_info->keys, ic_info->keys + 1,
2728 sizeof (int) * (ic_info->used - 1));
2731 /* This forces returning 1. */
2732 ic_info->key_unhandled = 1;
2738 reset_ic (ic, Mnil);
2739 ic_info->key_unhandled = 1;
2742 /* Break the loop if all keys were handled. */
2743 } while (ic_info->key_head < ic_info->used);
2745 /* If the current map is the root of the initial state, we should
2746 produce any preedit text in ic->produced. */
2747 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2748 && mtext_nchars (ic->preedit) > 0)
2749 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2751 if (mtext_nchars (ic->produced) > 0)
2753 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2756 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2757 Mlanguage, ic->im->language);
2760 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2764 /** Return 1 if the last event or key was not handled, otherwise
2767 There is no need of looking up because ic->produced should already
2768 contain the produced text (if any).
2773 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2775 mtext_cat (mt, ic->produced);
2776 mtext_reset (ic->produced);
2777 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2780 static MPlist *load_im_info_keys;
2783 load_partial_im_info (MSymbol language, MSymbol name,
2784 MSymbol extra, MSymbol key)
2789 if (language == Mnil)
2790 MERROR (MERROR_IM, NULL);
2791 mdb = mdatabase_find (Minput_method, language, name, extra);
2793 MERROR (MERROR_IM, NULL);
2795 mplist_push (load_im_info_keys, key, Mt);
2796 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2797 mplist_pop (load_im_info_keys);
2802 static MInputMethodInfo *
2803 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2807 MInputMethodInfo *im_info = NULL;
2809 if (language == Mnil)
2810 MERROR (MERROR_IM, NULL);
2811 mdb = mdatabase_find (Minput_method, language, name, extra);
2813 MERROR (MERROR_IM, NULL);
2816 im_info_list = mplist ();
2817 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2819 if (mdatabase__check (mdb))
2821 plist = MPLIST_NEXT (plist);
2822 im_info = MPLIST_VAL (plist);
2826 free_im_info (MPLIST_VAL (plist));
2830 plist = mdatabase_load (mdb);
2832 MERROR (MERROR_IM, NULL);
2833 im_info = load_im_info (language, name, plist);
2834 M17N_OBJECT_UNREF (plist);
2836 MERROR (MERROR_IM, NULL);
2837 mplist_push (im_info_list, Mt, im_info);
2838 mplist_push (im_info_list, Mt, mdb);
2843 /* Input method command handler. */
2845 /* List of all (global and local) commands.
2846 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2847 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2848 Global commands are storead as (t (t COMMAND ...)) */
2850 /* Check if PLIST is a valid command key sequence.
2851 PLIST must be NULL or:
2852 [ symbol:KEY | integer:KEY ] ... */
2855 check_command_keyseq (MPlist *plist)
2859 MPLIST_DO (plist, plist)
2861 if (MPLIST_SYMBOL_P (plist))
2863 else if (MPLIST_INTEGER_P (plist))
2865 int n = MPLIST_INTEGER (plist);
2869 MPLIST_KEY (plist) = Msymbol;
2870 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2878 /* Check if PLIST has this form:
2879 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2881 If the form of PLIST matches, return 0, otherwise return -1. */
2884 check_command_list (MPlist *plist)
2886 MPLIST_DO (plist, plist)
2888 if (MPLIST_PLIST_P (plist))
2890 MPlist *pl = MPLIST_PLIST (plist);
2893 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2896 else if (! MPLIST_MTEXT_P (plist))
2904 /* Input method variable handler. */
2906 /* Check if PLIST has this form:
2907 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2910 If the form of PLIST matches, return 0, otherwise return -1. */
2913 check_variable_list (MPlist *plist)
2915 MSymbol type = MPLIST_KEY (plist);
2918 if (type != Minteger && type != Mtext && type != Msymbol)
2920 MPLIST_DO (plist, MPLIST_NEXT (plist))
2922 if (type == Minteger && MPLIST_PLIST_P (plist))
2924 MPLIST_DO (p, MPLIST_PLIST (plist))
2925 if (! MPLIST_INTEGER_P (p))
2928 else if (type != MPLIST_KEY (plist))
2934 /* Support functions for mdebug_dump_im. */
2937 dump_im_map (MPlist *map_list, int indent)
2940 MSymbol key = MPLIST_KEY (map_list);
2941 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2943 prefix = (char *) alloca (indent + 1);
2944 memset (prefix, 32, indent);
2945 prefix[indent] = '\0';
2947 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2948 if (map->map_actions)
2949 mdebug_dump_plist (map->map_actions, indent + 2);
2952 MPLIST_DO (map_list, map->submaps)
2954 fprintf (stderr, "\n%s ", prefix);
2955 dump_im_map (map_list, indent + 2);
2958 if (map->branch_actions)
2960 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2961 mdebug_dump_plist (map->branch_actions, indent + 4);
2962 fprintf (stderr, ")");
2964 fprintf (stderr, ")");
2969 dump_im_state (MIMState *state, int indent)
2974 prefix = (char *) alloca (indent + 1);
2975 memset (prefix, 32, indent);
2976 prefix[indent] = '\0';
2978 fprintf (stderr, "(%s", msymbol_name (state->name));
2979 if (state->map->submaps)
2981 MPLIST_DO (map_list, state->map->submaps)
2983 fprintf (stderr, "\n%s ", prefix);
2984 dump_im_map (map_list, indent + 2);
2987 fprintf (stderr, ")");
2996 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2997 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2998 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2999 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
3000 char buf[6], buf2[256];
3003 Minput_method = msymbol ("input-method");
3004 Minput_driver = msymbol ("input-driver");
3005 Mtitle = msymbol ("title");
3006 Mmacro = msymbol ("macro");
3007 Mmodule = msymbol ("module");
3008 Mmap = msymbol ("map");
3009 Mstate = msymbol ("state");
3010 Minclude = msymbol ("include");
3011 Minsert = msymbol ("insert");
3012 M_candidates = msymbol (" candidates");
3013 Mdelete = msymbol ("delete");
3014 Mmove = msymbol ("move");
3015 Mmark = msymbol ("mark");
3016 Mpushback = msymbol ("pushback");
3017 Mundo = msymbol ("undo");
3018 Mcall = msymbol ("call");
3019 Mshift = msymbol ("shift");
3020 Mselect = msymbol ("select");
3021 Mshow = msymbol ("show");
3022 Mhide = msymbol ("hide");
3023 Mcommit = msymbol ("commit");
3024 Munhandle = msymbol ("unhandle");
3025 Mset = msymbol ("set");
3026 Madd = msymbol ("add");
3027 Msub = msymbol ("sub");
3028 Mmul = msymbol ("mul");
3029 Mdiv = msymbol ("div");
3030 Mequal = msymbol ("=");
3031 Mless = msymbol ("<");
3032 Mgreater = msymbol (">");
3033 Mless_equal = msymbol ("<=");
3034 Mgreater_equal = msymbol (">=");
3035 Mcond = msymbol ("cond");
3036 Mplus = msymbol ("+");
3037 Mminus = msymbol ("-");
3038 Mstar = msymbol ("*");
3039 Mslush = msymbol ("/");
3040 Mand = msymbol ("&");
3041 Mor = msymbol ("|");
3042 Mnot = msymbol ("!");
3044 Mcandidates_group_size = msymbol ("candidates-group-size");
3045 Mcandidates_charset = msymbol ("candidates-charset");
3047 Minput_preedit_start = msymbol ("input-preedit-start");
3048 Minput_preedit_done = msymbol ("input-preedit-done");
3049 Minput_preedit_draw = msymbol ("input-preedit-draw");
3050 Minput_status_start = msymbol ("input-status-start");
3051 Minput_status_done = msymbol ("input-status-done");
3052 Minput_status_draw = msymbol ("input-status-draw");
3053 Minput_candidates_start = msymbol ("input-candidates-start");
3054 Minput_candidates_done = msymbol ("input-candidates-done");
3055 Minput_candidates_draw = msymbol ("input-candidates-draw");
3056 Minput_set_spot = msymbol ("input-set-spot");
3057 Minput_focus_move = msymbol ("input-focus-move");
3058 Minput_focus_in = msymbol ("input-focus-in");
3059 Minput_focus_out = msymbol ("input-focus-out");
3060 Minput_toggle = msymbol ("input-toggle");
3061 Minput_reset = msymbol ("input-reset");
3062 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3063 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3065 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
3066 Mcandidate_index = msymbol (" candidate-index");
3068 Minit = msymbol ("init");
3069 Mfini = msymbol ("fini");
3071 M_key_alias = msymbol (" key-alias");
3072 M_description = msymbol ("description");
3073 M_command = msymbol ("command");
3074 M_variable = msymbol ("variable");
3076 load_im_info_keys = mplist ();
3077 mplist_add (load_im_info_keys, Mstate, Mnil);
3078 mplist_push (load_im_info_keys, Mmap, Mnil);
3083 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
3087 one_char_symbol[i] = msymbol (buf);
3090 alias = msymbol (key_names[i]);
3091 msymbol_put (one_char_symbol[i], M_key_alias, alias);
3094 alias = one_char_symbol[i];
3095 buf[2] += (i == 0) ? -32 : 32;
3096 msymbol_put (alias, M_key_alias, msymbol (buf));
3097 buf[2] -= (i == 0) ? -32 : 32;
3099 for (buf[2] = i; i < 127; i++, buf[2]++)
3100 one_char_symbol[i] = msymbol (buf + 2);
3101 one_char_symbol[i++] = msymbol ("Delete");
3107 for (buf[4] = '@'; i < 160; i++, buf[4]++)
3109 one_char_symbol[i] = msymbol (buf);
3110 if (key_names[i - 128])
3112 strcpy (buf2 + 2, key_names[i - 128]);
3113 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
3116 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
3117 one_char_symbol[i] = msymbol (buf + 2);
3118 one_char_symbol[i] = msymbol ("M-Delete");
3120 command_list = variable_list = NULL;
3122 minput_default_driver.open_im = open_im;
3123 minput_default_driver.close_im = close_im;
3124 minput_default_driver.create_ic = create_ic;
3125 minput_default_driver.destroy_ic = destroy_ic;
3126 minput_default_driver.filter = filter;
3127 minput_default_driver.lookup = lookup;
3128 minput_default_driver.callback_list = mplist ();
3129 mplist_put (minput_default_driver.callback_list, Minput_reset,
3131 minput_driver = &minput_default_driver;
3140 M17N_OBJECT_UNREF (command_list);
3141 command_list = NULL;
3145 M17N_OBJECT_UNREF (variable_list);
3146 variable_list = NULL;
3149 if (minput_default_driver.callback_list)
3151 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3152 minput_default_driver.callback_list = NULL;
3154 if (minput_driver->callback_list)
3156 M17N_OBJECT_UNREF (minput_driver->callback_list);
3157 minput_driver->callback_list = NULL;
3162 while (! MPLIST_TAIL_P (im_info_list))
3165 mplist_pop (im_info_list);
3166 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
3167 /* Pop (t . im_info) */
3168 mplist_pop (im_info_list);
3170 M17N_OBJECT_UNREF (im_info_list);
3171 im_info_list = NULL;
3174 M17N_OBJECT_UNREF (load_im_info_keys);
3178 minput__callback (MInputContext *ic, MSymbol command)
3180 if (ic->im->driver.callback_list)
3182 MInputCallbackFunc func
3183 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3187 (func) (ic, command);
3192 minput__char_to_key (int c)
3194 if (c < 0 || c >= 0x100)
3197 return one_char_symbol[c];
3201 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3206 /*** @addtogroup m17nInputMethod */
3211 @name Variables: Predefined symbols for callback commands.
3213 These are the predefined symbols that are used as the @c COMMAND
3214 argument of callback functions of an input method driver (see
3215 #MInputDriver::callback_list ).
3217 Most of them don't require extra argument nor return any value;
3218 exceptions are these:
3220 Minput_get_surrounding_text: When a callback function assigned for
3221 this command is called, the first element of #MInputContext::plist
3222 has key #Msymbol and the value specifies which portion of the
3223 surrounding text should be retrieved. If the value is positive,
3224 it specifies the number of characters following the current cursor
3225 position. If the value is negative, the absolute value specifies
3226 the number of characters preceding the current cursor position.
3227 The callback function must set the key of this element to #Mtext
3228 and the value to the retrived M-text (whose length may be shorter
3229 than the requested number of characters if the available text is
3230 not that long, or it may be longer if an application thinks it's
3231 more efficient to return that length).
3233 Minput_delete_surrounding_text: When a callback function assigned
3234 for this command is called, the first element of
3235 #MInputContext::plist has key #Msymbol and the value specifies
3236 which portion of the surrounding text should be deleted in the
3237 same way as the case of Minput_get_surrounding_text. The callback
3238 function must delete the specified text. It should not alter
3239 #MInputContext::plist. */
3242 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3244 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3245 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3250 MSymbol Minput_preedit_start;
3251 MSymbol Minput_preedit_done;
3252 MSymbol Minput_preedit_draw;
3253 MSymbol Minput_status_start;
3254 MSymbol Minput_status_done;
3255 MSymbol Minput_status_draw;
3256 MSymbol Minput_candidates_start;
3257 MSymbol Minput_candidates_done;
3258 MSymbol Minput_candidates_draw;
3259 MSymbol Minput_set_spot;
3260 MSymbol Minput_toggle;
3261 MSymbol Minput_reset;
3262 MSymbol Minput_get_surrounding_text;
3263 MSymbol Minput_delete_surrounding_text;
3269 @name Variables: Predefined symbols for special input events.
3271 These are the predefined symbols that are used as the @c KEY
3272 argument of minput_filter (). */
3277 MSymbol Minput_focus_out;
3278 MSymbol Minput_focus_in;
3279 MSymbol Minput_focus_move;
3286 @brief The default driver for internal input methods.
3288 The variable #minput_default_driver is the default driver for
3289 internal input methods.
3291 The member MInputDriver::open_im () searches the m17n database for
3292 an input method that matches the tag \< #Minput_method, $LANGUAGE,
3293 $NAME\> and loads it.
3295 The member MInputDriver::callback_list () is @c NULL. Thus, it is
3296 programmers responsibility to set it to a plist of proper callback
3297 functions. Otherwise, no feedback information (e.g. preedit text)
3298 can be shown to users.
3300 The macro M17N_INIT () sets the variable #minput_driver to the
3301 pointer to this driver so that all internal input methods use it.
3303 Therefore, unless @c minput_driver is set differently, the driver
3304 dependent arguments $ARG of the functions whose name begins with
3305 "minput_" are all ignored. */
3308 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
3310 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
3312 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
3313 \< #Minput_method, $LANGUAGE, $NAME\>
3314 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
3316 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
3317 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
3318 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
3319 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
3321 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
3322 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
3324 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
3325 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
3327 MInputDriver minput_default_driver;
3331 @brief The driver for internal input methods.
3333 The variable #minput_driver is a pointer to the input method
3334 driver that is used by internal input methods. The macro
3335 M17N_INIT () initializes it to a pointer to #minput_default_driver
3336 if <m17n<EM></EM>.h> is included. */
3338 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
3340 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
3341 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
3342 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
3343 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
3345 MInputDriver *minput_driver;
3347 MSymbol Minput_driver;
3352 @brief Open an input method.
3354 The minput_open_im () function opens an input method whose
3355 language and name match $LANGUAGE and $NAME, and returns a pointer
3356 to the input method object newly allocated.
3358 This function at first decides a driver for the input method as
3361 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3362 #minput_driver is used.
3364 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
3365 driver pointed to by the property value is used to open the input
3366 method. If $NAME has no such a property, @c NULL is returned.
3368 Then, the member MInputDriver::open_im () of the driver is
3371 $ARG is set in the member @c arg of the structure MInputMethod so
3372 that the driver can refer to it. */
3375 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3377 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3378 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3380 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3382 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3383 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3385 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3386 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3387 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3389 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3391 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3393 @latexonly \IPAlabel{minput_open} @endlatexonly
3398 minput_open_im (MSymbol language, MSymbol name, void *arg)
3401 MInputDriver *driver;
3403 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3404 msymbol_name (language), msymbol_name (name));
3406 driver = minput_driver;
3409 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3411 MERROR (MERROR_IM, NULL);
3414 MSTRUCT_CALLOC (im, MERROR_IM);
3415 im->language = language;
3418 im->driver = *driver;
3419 if ((*im->driver.open_im) (im) < 0)
3421 MDEBUG_PRINT (" failed\n");
3425 MDEBUG_PRINT (" ok\n");
3432 @brief Close an input method.
3434 The minput_close_im () function closes the input method $IM, which
3435 must have been created by minput_open_im (). */
3438 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3440 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3441 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3444 minput_close_im (MInputMethod *im)
3446 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3447 msymbol_name (im->name), msymbol_name (im->language));
3448 (*im->driver.close_im) (im);
3450 MDEBUG_PRINT (" done\n");
3456 @brief Create an input context.
3458 The minput_create_ic () function creates an input context object
3459 associated with input method $IM, and calls callback functions
3460 corresponding to #Minput_preedit_start, #Minput_status_start, and
3461 #Minput_status_draw in this order.
3464 If an input context is successfully created, minput_create_ic ()
3465 returns a pointer to it. Otherwise it returns @c NULL. */
3468 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3470 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3471 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3472 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3473 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3476 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3477 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3481 minput_create_ic (MInputMethod *im, void *arg)
3485 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3486 msymbol_name (im->name), msymbol_name (im->language));
3487 MSTRUCT_CALLOC (ic, MERROR_IM);
3490 ic->preedit = mtext ();
3491 ic->candidate_list = NULL;
3492 ic->produced = mtext ();
3493 ic->spot.x = ic->spot.y = 0;
3495 ic->plist = mplist ();
3496 if ((*im->driver.create_ic) (ic) < 0)
3498 MDEBUG_PRINT (" failed\n");
3499 M17N_OBJECT_UNREF (ic->preedit);
3500 M17N_OBJECT_UNREF (ic->produced);
3501 M17N_OBJECT_UNREF (ic->plist);
3506 if (im->driver.callback_list)
3508 minput__callback (ic, Minput_preedit_start);
3509 minput__callback (ic, Minput_status_start);
3510 minput__callback (ic, Minput_status_draw);
3513 MDEBUG_PRINT (" ok\n");
3520 @brief Destroy an input context.
3522 The minput_destroy_ic () function destroys the input context $IC,
3523 which must have been created by minput_create_ic (). It calls
3524 callback functions corresponding to #Minput_preedit_done,
3525 #Minput_status_done, and #Minput_candidates_done in this order. */
3528 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3530 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3531 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3532 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3533 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3534 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3538 minput_destroy_ic (MInputContext *ic)
3540 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3541 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3542 if (ic->im->driver.callback_list)
3544 minput__callback (ic, Minput_preedit_done);
3545 minput__callback (ic, Minput_status_done);
3546 minput__callback (ic, Minput_candidates_done);
3548 (*ic->im->driver.destroy_ic) (ic);
3549 M17N_OBJECT_UNREF (ic->preedit);
3550 M17N_OBJECT_UNREF (ic->produced);
3551 M17N_OBJECT_UNREF (ic->plist);
3552 MDEBUG_PRINT (" done\n");
3559 @brief Filter an input key.
3561 The minput_filter () function filters input key $KEY according to
3562 input context $IC, and calls callback functions corresponding to
3563 #Minput_preedit_draw, #Minput_status_draw, and
3564 #Minput_candidates_draw if the preedit text, the status, and the
3565 current candidate are changed respectively.
3567 To make the input method commit the current preedit text (if any)
3568 and shift to the initial state, call this function with #Mnil as
3571 To inform the input method about the focus-out event, call this
3572 function with #Minput_focus_out as $KEY.
3574 To inform the input method about the focus-in event, call this
3575 function with #Minput_focus_in as $KEY.
3577 To inform the input method about the focus-move event (i.e. input
3578 spot change within the same input context), call this function
3579 with #Minput_focus_move as $KEY.
3582 If $KEY is filtered out, this function returns 1. In that case,
3583 the caller should discard the key. Otherwise, it returns 0, and
3584 the caller should handle the key, for instance, by calling the
3585 function minput_lookup () with the same key. */
3588 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3590 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3591 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3592 #Minput_preedit_draw, #Minput_status_draw,
3593 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3596 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3597 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3598 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3599 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3601 @latexonly \IPAlabel{minput_filter} @endlatexonly
3605 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3612 ret = (*ic->im->driver.filter) (ic, key, arg);
3614 if (ic->im->driver.callback_list)
3616 if (ic->preedit_changed)
3617 minput__callback (ic, Minput_preedit_draw);
3618 if (ic->status_changed)
3619 minput__callback (ic, Minput_status_draw);
3620 if (ic->candidates_changed)
3621 minput__callback (ic, Minput_candidates_draw);
3630 @brief Look up a text produced in the input context.
3632 The minput_lookup () function looks up a text in the input context
3633 $IC. $KEY must be identical to the one that was used in the previous call of
3636 If a text was produced by the input method, it is concatenated
3639 This function calls #MInputDriver::lookup .
3642 If $KEY was correctly handled by the input method, this function
3643 returns 0. Otherwise, it returns -1, even though some text
3644 might be produced in $MT. */
3647 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3649 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3650 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3652 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3655 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3658 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3659 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3660 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3662 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3665 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3667 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3672 @brief Set the spot of the input context.
3674 The minput_set_spot () function sets the spot of input context $IC
3675 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3676 The semantics of these values depends on the input method driver.
3678 For instance, a driver designed to work in a CUI environment may
3679 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
3680 $DESCENT . A driver designed to work in a window system may
3681 interpret $X and $Y as the pixel offsets relative to the origin of the
3682 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3683 descent pixels of the line at ($X . $Y ).
3685 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3687 $MT and $POS are the M-text and the character position at the spot.
3688 $MT may be @c NULL, in which case, the input method cannot get
3689 information about the text around the spot. */
3692 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3694 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3695 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3696 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3698 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3699 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3700 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3701 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3702 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3703 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3705 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3707 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3708 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3712 minput_set_spot (MInputContext *ic, int x, int y,
3713 int ascent, int descent, int fontsize,
3718 ic->spot.ascent = ascent;
3719 ic->spot.descent = descent;
3720 ic->spot.fontsize = fontsize;
3723 if (ic->im->driver.callback_list)
3724 minput__callback (ic, Minput_set_spot);
3729 @brief Toggle input method.
3731 The minput_toggle () function toggles the input method associated
3732 with input context $IC. */
3734 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3736 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3737 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3741 minput_toggle (MInputContext *ic)
3743 if (ic->im->driver.callback_list)
3744 minput__callback (ic, Minput_toggle);
3745 ic->active = ! ic->active;
3751 @brief Reset an input context.
3753 The minput_reset_ic () function resets input context $IC by
3754 calling a callback function corresponding to #Minput_reset. It
3755 resets the status of $IC to its initial one. As the
3756 current preedit text is deleted without commitment, if necessary,
3757 call minput_filter () with the arg @r key #Mnil to force the input
3758 method to commit the preedit in advance. */
3761 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3763 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3764 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3765 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3766 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3767 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3768 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3771 minput_reset_ic (MInputContext *ic)
3773 if (ic->im->driver.callback_list)
3774 minput__callback (ic, Minput_reset);
3780 @brief Get title and icon filename of an input method.
3782 The minput_get_title_icon () function returns a plist containing a
3783 title and icon filename (if any) of the input method specifies by
3784 $LANGUAGE and $NAME.
3786 The first element of the plist has key Mtext and the value is an
3787 M-text of the title for identifying the input method. The second
3788 element (if any) has key M-text and the value is an M-text of the
3789 icon image (absolute) filename for the same purpose.
3792 If there exists the specified input method and it defines an
3793 title, a plist is retured. Otherwise, NULL is returned. A caller
3794 must free the plist by m17n_object_unref ().
3798 minput_get_title_icon (MSymbol language, MSymbol name)
3800 MPlist *plist = load_partial_im_info (language, name, Mnil, Mtitle);
3807 if (MPLIST_TAIL_P (plist))
3809 pl = MPLIST_PLIST (plist);
3810 pl = MPLIST_NEXT (pl);
3811 if (! MPLIST_MTEXT_P (pl))
3813 M17N_OBJECT_REF (pl);
3814 M17N_OBJECT_UNREF (plist);
3816 pl = MPLIST_NEXT (pl);
3817 if (MPLIST_MTEXT_P (pl))
3819 if (mtext_nchars (MPLIST_MTEXT (pl)) > 0)
3821 mt = MPLIST_MTEXT (pl);
3822 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
3825 else if (language != Mnil && name != Mnil)
3828 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
3831 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
3832 (char *) MSYMBOL_NAME (name));
3833 file = mdatabase__find_file (buf);
3834 if (! file && language == Mt)
3836 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
3837 file = mdatabase__find_file (buf);
3843 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
3845 mplist_set (pl, Mtext, mt);
3846 M17N_OBJECT_UNREF (mt);
3849 mplist_set (pl, Mnil, NULL);
3853 M17N_OBJECT_UNREF (plist);
3860 @brief Get description text of an input method.
3862 The minput_get_description () function returns an M-text that
3863 describes the input method specified by $LANGUAGE and $NAME.
3866 If the specified input method has a description text, a pointer to
3867 #MText is returned. The caller has to free it by m17n_object_unref ().
3868 If the input method does not have a description text, @c NULL is
3871 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3873 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3874 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3876 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3877 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3878 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3879 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3882 minput_get_description (MSymbol language, MSymbol name)
3884 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3890 if (MPLIST_TAIL_P (plist))
3892 M17N_OBJECT_UNREF (plist);
3895 pl = MPLIST_PLIST (plist);
3896 pl = MPLIST_NEXT (pl);
3897 if (MPLIST_MTEXT_P (pl))
3899 mt = MPLIST_MTEXT (pl);
3900 M17N_OBJECT_REF (mt);
3902 M17N_OBJECT_UNREF (plist);
3907 @brief Get information about input method commands.
3909 The minput_get_commands () function returns information about
3910 input method commands of the input method specified by $LANGUAGE
3911 and $NAME. An input method command is a pseudo key event to which
3912 one or more actual input key sequences are assigned.
3914 There are two kinds of commands, global and local. Global
3915 commands are used by multiple input methods for the same purpose,
3916 and have global key assignments. Local commands are used only by
3917 a specific input method, and have only local key assignments.
3919 Each input method may locally change key assignments for global
3920 commands. The global key assignment for a global command is
3921 effective only when the current input method does not have local
3922 key assignments for that command.
3924 If $NAME is #Mnil, information about global commands is returned.
3925 In this case $LANGUAGE is ignored.
3927 If $NAME is not #Mnil, information about those commands that have
3928 local key assignments in the input method specified by $LANGUAGE
3929 and $NAME is returned.
3932 If no input method commands are found, this function returns @c NULL.
3934 Otherwise, a pointer to a plist is returned. The key of each
3935 element in the plist is a symbol representing a command, and the
3936 value is a plist of the form COMMAND-INFO described below.
3938 The first element of COMMAND-INFO has the key #Mtext, and the
3939 value is an M-text describing the command.
3941 If there are no more elements, that means no key sequences are
3942 assigned to the command. Otherwise, each of the remaining
3943 elements has the key #Mplist, and the value is a plist whose keys are
3944 #Msymbol and values are symbols representing input keys, which are
3945 currently assigned to the command.
3947 As the returned plist is kept in the library, the caller must not
3948 modify nor free it. */
3950 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3952 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3953 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3954 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3955 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3957 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3958 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3959 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3960 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3962 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3963 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3964 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3967 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3968 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3970 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3971 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3975 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3977 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3978 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3979 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3981 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3982 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3983 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3986 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3987 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3988 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3989 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3990 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3992 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3993 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3996 minput_get_commands (MSymbol language, MSymbol name)
3998 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
4000 return (MPLIST_TAIL_P (plist) ? NULL : plist);
4004 @brief Assign a key sequence to an input method command.
4006 The minput_assign_command_keys () function assigns input key
4007 sequence $KEYSEQ to input method command $COMMAND for the input
4008 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
4009 key sequence is assigned globally no matter what $LANGUAGE is.
4010 Otherwise the key sequence is assigned locally.
4012 Each element of $KEYSEQ must have the key $Msymbol and the value
4013 must be a symbol representing an input key.
4015 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
4016 globally or locally.
4018 This assignment gets effective in a newly opened input method.
4021 If the operation was successful, 0 is returned. Otherwise -1 is
4022 returned, and #merror_code is set to #MERROR_IM. */
4024 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
4026 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
4027 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
4028 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
4029 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
4030 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
4032 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
4033 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4035 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
4036 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
4038 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
4041 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
4042 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
4045 minput_assign_command_keys (MSymbol language, MSymbol name,
4046 MSymbol command, MPlist *keyseq)
4048 MPlist *plist, *pl, *p;
4050 if (check_command_keyseq (keyseq) < 0
4051 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
4052 MERROR (MERROR_IM, -1);
4053 pl = mplist_get (plist, command);
4056 pl = MPLIST_NEXT (pl);
4058 while ((p = mplist_pop (pl)))
4059 M17N_OBJECT_UNREF (p);
4062 keyseq = mplist_copy (keyseq);
4063 mplist_push (pl, Mplist, keyseq);
4064 M17N_OBJECT_UNREF (keyseq);
4070 MERROR (MERROR_IM, -1);
4073 /* Get global commands. */
4074 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
4075 pl = mplist_get (pl, command);
4077 MERROR (MERROR_IM, -1);
4079 mplist_add (p, Mtext, mplist_value (pl));
4080 keyseq = mplist_copy (keyseq);
4081 mplist_add (p, Mplist, keyseq);
4082 M17N_OBJECT_UNREF (keyseq);
4083 mplist_push (plist, command, p);
4089 @brief Get a list of variables of an input method.
4091 The minput_get_variables () function returns a plist (#MPlist) of
4092 variables used to control the behavior of the input method
4093 specified by $LANGUAGE and $NAME. The plist is @e well-formed
4094 (#m17nPlist) of the following format:
4097 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
4098 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
4102 @c VARNAME is a symbol representing the variable name.
4104 @c DOC-MTEXT is an M-text describing the variable.
4106 @c DEFAULT-VALUE is the default value of the varible. It is a
4107 symbol, integer, or M-text.
4109 @c VALUEs (if any) specifies the possible values of the variable.
4110 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
4111 @c TO), where @c FROM and @c TO specifies a range of possible
4114 For instance, suppose an input method has the variables:
4116 @li name:intvar, description:"value is an integer",
4117 initial value:0, value-range:0..3,10,20
4119 @li name:symvar, description:"value is a symbol",
4120 initial value:nil, value-range:a, b, c, nil
4122 @li name:txtvar, description:"value is an M-text",
4123 initial value:empty text, no value-range (i.e. any text)
4125 Then, the returned plist is as follows.
4128 (intvar ("value is an integer" 0 (0 3) 10 20)
4129 symvar ("value is a symbol" nil a b c nil)
4130 txtvar ("value is an M-text" ""))
4134 If the input method uses any variables, a pointer to #MPlist is
4135 returned. As the plist is kept in the library, a caller must not
4136 modify nor free it. If the input method does not use any
4137 variable, @c NULL is returned. */
4139 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
4141 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
4142 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
4143 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
4147 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
4148 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
4152 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4154 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
4156 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
4159 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
4160 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
4161 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
4163 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
4165 @li name:intvar, ÀâÌÀ:"value is an integer",
4166 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
4168 @li name:symvar, ÀâÌÀ:"value is a symbol",
4169 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
4171 @li name:txtvar, ÀâÌÀ:"value is an M-text",
4172 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
4174 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
4177 (intvar ("value is an integer" 0 (0 3) 10 20)
4178 symvar ("value is a symbol" nil a b c nil)
4179 txtvar ("value is an M-text" ""))
4183 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4184 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4185 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
4188 minput_get_variables (MSymbol language, MSymbol name)
4190 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
4192 return (MPLIST_TAIL_P (plist) ? NULL : plist);
4196 @brief Set the initial value of an input method variable.
4198 The minput_set_variable () function sets the initial value of
4199 input method variable $VARIABLE to $VALUE for the input method
4200 specified by $LANGUAGE and $NAME.
4202 By default, the initial value is 0.
4204 This setting gets effective in a newly opened input method.
4207 If the operation was successful, 0 is returned. Otherwise -1 is
4208 returned, and #merror_code is set to #MERROR_IM. */
4210 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
4212 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
4213 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
4214 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
4216 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
4218 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
4221 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
4222 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
4225 minput_set_variable (MSymbol language, MSymbol name,
4226 MSymbol variable, void *value)
4228 MPlist *plist, *val_element, *range_element;
4231 plist = get_nested_list (language, name, Mnil, M_variable);
4233 MERROR (MERROR_IM, -1);
4234 plist = mplist_find_by_value (plist, variable);
4236 MERROR (MERROR_IM, -1);
4237 plist = MPLIST_PLIST (MPLIST_NEXT (plist));
4238 val_element = MPLIST_NEXT (plist);
4239 type = MPLIST_KEY (val_element);
4240 range_element = MPLIST_NEXT (val_element);
4242 if (! MPLIST_TAIL_P (range_element))
4244 if (type == Minteger)
4246 int val = (int) value, this_val;
4248 MPLIST_DO (plist, range_element)
4250 this_val = (int) MPLIST_VAL (plist);
4251 if (MPLIST_PLIST_P (plist))
4253 int min_bound, max_bound;
4254 MPlist *pl = MPLIST_PLIST (plist);
4256 min_bound = (int) MPLIST_VAL (pl);
4257 pl = MPLIST_NEXT (pl);
4258 max_bound = (int) MPLIST_VAL (pl);
4259 if (val >= min_bound && val <= max_bound)
4262 else if (val == this_val)
4265 if (MPLIST_TAIL_P (plist))
4266 MERROR (MERROR_IM, -1);
4268 else if (type == Msymbol)
4270 MPLIST_DO (plist, range_element)
4271 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
4273 if (MPLIST_TAIL_P (plist))
4274 MERROR (MERROR_IM, -1);
4276 else /* type == Mtext */
4278 MPLIST_DO (plist, range_element)
4279 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
4281 if (MPLIST_TAIL_P (plist))
4282 MERROR (MERROR_IM, -1);
4283 M17N_OBJECT_REF (value);
4287 mplist_set (val_element, type, value);
4293 /*** @addtogroup m17nDebug */
4299 @brief Dump an input method.
4301 The mdebug_dump_im () function prints the input method $IM in a
4302 human readable way to the stderr. $INDENT specifies how many
4303 columns to indent the lines but the first one.
4306 This function returns $IM. */
4308 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
4310 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
4311 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
4314 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
4317 mdebug_dump_im (MInputMethod *im, int indent)
4319 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
4322 prefix = (char *) alloca (indent + 1);
4323 memset (prefix, 32, indent);
4324 prefix[indent] = '\0';
4326 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
4327 msymbol_name (im->name));
4328 mdebug_dump_mtext (im_info->title, 0, 0);
4329 if (im->name != Mnil)
4333 MPLIST_DO (state, im_info->states)
4335 fprintf (stderr, "\n%s ", prefix);
4336 dump_im_state (MPLIST_VAL (state), indent + 2);
4339 fprintf (stderr, ")");