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. */
2690 if (! msymbol_get (key, M_key_alias)
2691 && (strchr (MSYMBOL_NAME (key), 'M')
2692 || strchr (MSYMBOL_NAME (key), 'A')))
2694 char *name = MSYMBOL_NAME (key);
2697 while (name[0] && name[1] == '-'
2698 && (name[0] != 'M' && name[0] != 'A'))
2700 if ((name[0] == 'M' || name[0] == 'A') && name[1] == '-')
2705 name = alloca (MSYMBOL_NAMELEN (key) + 1);
2706 memcpy (name, MSYMBOL_NAME (key), MSYMBOL_NAMELEN (key) + 1);
2707 name[meta_or_alt - MSYMBOL_NAME (key)]
2708 = *meta_or_alt == 'M' ? 'A' : 'M';
2709 alias = msymbol (name);
2710 msymbol_put (key, M_key_alias, alias);
2713 else if (MSYMBOL_NAME (key)[0] == 'S'
2714 && MSYMBOL_NAME (key)[1] == '-'
2715 && MSYMBOL_NAME (key)[2] >= 'A' && MSYMBOL_NAME (key)[2] <= 'Z')
2716 msymbol_put (key, M_key_alias, one_char_symbol[(int)MSYMBOL_NAME (key)[2]]);
2719 if (handle_key (ic) < 0)
2721 /* KEY was not handled. Delete it from the current key sequence. */
2722 if (ic_info->used > 0)
2724 memmove (ic_info->keys, ic_info->keys + 1,
2725 sizeof (int) * (ic_info->used - 1));
2728 /* This forces returning 1. */
2729 ic_info->key_unhandled = 1;
2735 reset_ic (ic, Mnil);
2736 ic_info->key_unhandled = 1;
2739 /* Break the loop if all keys were handled. */
2740 } while (ic_info->key_head < ic_info->used);
2742 /* If the current map is the root of the initial state, we should
2743 produce any preedit text in ic->produced. */
2744 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2745 && mtext_nchars (ic->preedit) > 0)
2746 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2748 if (mtext_nchars (ic->produced) > 0)
2750 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2753 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2754 Mlanguage, ic->im->language);
2757 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2761 /** Return 1 if the last event or key was not handled, otherwise
2764 There is no need of looking up because ic->produced should already
2765 contain the produced text (if any).
2770 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2772 mtext_cat (mt, ic->produced);
2773 mtext_reset (ic->produced);
2774 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2777 static MPlist *load_im_info_keys;
2780 load_partial_im_info (MSymbol language, MSymbol name,
2781 MSymbol extra, MSymbol key)
2786 if (language == Mnil)
2787 MERROR (MERROR_IM, NULL);
2788 mdb = mdatabase_find (Minput_method, language, name, extra);
2790 MERROR (MERROR_IM, NULL);
2792 mplist_push (load_im_info_keys, key, Mt);
2793 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2794 mplist_pop (load_im_info_keys);
2799 static MInputMethodInfo *
2800 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2804 MInputMethodInfo *im_info = NULL;
2806 if (language == Mnil)
2807 MERROR (MERROR_IM, NULL);
2808 mdb = mdatabase_find (Minput_method, language, name, extra);
2810 MERROR (MERROR_IM, NULL);
2813 im_info_list = mplist ();
2814 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2816 if (mdatabase__check (mdb))
2818 plist = MPLIST_NEXT (plist);
2819 im_info = MPLIST_VAL (plist);
2823 free_im_info (MPLIST_VAL (plist));
2827 plist = mdatabase_load (mdb);
2829 MERROR (MERROR_IM, NULL);
2830 im_info = load_im_info (language, name, plist);
2831 M17N_OBJECT_UNREF (plist);
2833 MERROR (MERROR_IM, NULL);
2834 mplist_push (im_info_list, Mt, im_info);
2835 mplist_push (im_info_list, Mt, mdb);
2840 /* Input method command handler. */
2842 /* List of all (global and local) commands.
2843 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2844 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2845 Global commands are storead as (t (t COMMAND ...)) */
2847 /* Check if PLIST is a valid command key sequence.
2848 PLIST must be NULL or:
2849 [ symbol:KEY | integer:KEY ] ... */
2852 check_command_keyseq (MPlist *plist)
2856 MPLIST_DO (plist, plist)
2858 if (MPLIST_SYMBOL_P (plist))
2860 else if (MPLIST_INTEGER_P (plist))
2862 int n = MPLIST_INTEGER (plist);
2866 MPLIST_KEY (plist) = Msymbol;
2867 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2875 /* Check if PLIST has this form:
2876 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2878 If the form of PLIST matches, return 0, otherwise return -1. */
2881 check_command_list (MPlist *plist)
2883 MPLIST_DO (plist, plist)
2885 if (MPLIST_PLIST_P (plist))
2887 MPlist *pl = MPLIST_PLIST (plist);
2890 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2893 else if (! MPLIST_MTEXT_P (plist))
2901 /* Input method variable handler. */
2903 /* Check if PLIST has this form:
2904 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2907 If the form of PLIST matches, return 0, otherwise return -1. */
2910 check_variable_list (MPlist *plist)
2912 MSymbol type = MPLIST_KEY (plist);
2915 if (type != Minteger && type != Mtext && type != Msymbol)
2917 MPLIST_DO (plist, MPLIST_NEXT (plist))
2919 if (type == Minteger && MPLIST_PLIST_P (plist))
2921 MPLIST_DO (p, MPLIST_PLIST (plist))
2922 if (! MPLIST_INTEGER_P (p))
2925 else if (type != MPLIST_KEY (plist))
2931 /* Support functions for mdebug_dump_im. */
2934 dump_im_map (MPlist *map_list, int indent)
2937 MSymbol key = MPLIST_KEY (map_list);
2938 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2940 prefix = (char *) alloca (indent + 1);
2941 memset (prefix, 32, indent);
2942 prefix[indent] = '\0';
2944 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2945 if (map->map_actions)
2946 mdebug_dump_plist (map->map_actions, indent + 2);
2949 MPLIST_DO (map_list, map->submaps)
2951 fprintf (stderr, "\n%s ", prefix);
2952 dump_im_map (map_list, indent + 2);
2955 if (map->branch_actions)
2957 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2958 mdebug_dump_plist (map->branch_actions, indent + 4);
2959 fprintf (stderr, ")");
2961 fprintf (stderr, ")");
2966 dump_im_state (MIMState *state, int indent)
2971 prefix = (char *) alloca (indent + 1);
2972 memset (prefix, 32, indent);
2973 prefix[indent] = '\0';
2975 fprintf (stderr, "(%s", msymbol_name (state->name));
2976 if (state->map->submaps)
2978 MPLIST_DO (map_list, state->map->submaps)
2980 fprintf (stderr, "\n%s ", prefix);
2981 dump_im_map (map_list, indent + 2);
2984 fprintf (stderr, ")");
2993 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2994 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2995 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2996 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2997 char buf[6], buf2[256];
3000 Minput_method = msymbol ("input-method");
3001 Minput_driver = msymbol ("input-driver");
3002 Mtitle = msymbol ("title");
3003 Mmacro = msymbol ("macro");
3004 Mmodule = msymbol ("module");
3005 Mmap = msymbol ("map");
3006 Mstate = msymbol ("state");
3007 Minclude = msymbol ("include");
3008 Minsert = msymbol ("insert");
3009 M_candidates = msymbol (" candidates");
3010 Mdelete = msymbol ("delete");
3011 Mmove = msymbol ("move");
3012 Mmark = msymbol ("mark");
3013 Mpushback = msymbol ("pushback");
3014 Mundo = msymbol ("undo");
3015 Mcall = msymbol ("call");
3016 Mshift = msymbol ("shift");
3017 Mselect = msymbol ("select");
3018 Mshow = msymbol ("show");
3019 Mhide = msymbol ("hide");
3020 Mcommit = msymbol ("commit");
3021 Munhandle = msymbol ("unhandle");
3022 Mset = msymbol ("set");
3023 Madd = msymbol ("add");
3024 Msub = msymbol ("sub");
3025 Mmul = msymbol ("mul");
3026 Mdiv = msymbol ("div");
3027 Mequal = msymbol ("=");
3028 Mless = msymbol ("<");
3029 Mgreater = msymbol (">");
3030 Mless_equal = msymbol ("<=");
3031 Mgreater_equal = msymbol (">=");
3032 Mcond = msymbol ("cond");
3033 Mplus = msymbol ("+");
3034 Mminus = msymbol ("-");
3035 Mstar = msymbol ("*");
3036 Mslush = msymbol ("/");
3037 Mand = msymbol ("&");
3038 Mor = msymbol ("|");
3039 Mnot = msymbol ("!");
3041 Mcandidates_group_size = msymbol ("candidates-group-size");
3042 Mcandidates_charset = msymbol ("candidates-charset");
3044 Minput_preedit_start = msymbol ("input-preedit-start");
3045 Minput_preedit_done = msymbol ("input-preedit-done");
3046 Minput_preedit_draw = msymbol ("input-preedit-draw");
3047 Minput_status_start = msymbol ("input-status-start");
3048 Minput_status_done = msymbol ("input-status-done");
3049 Minput_status_draw = msymbol ("input-status-draw");
3050 Minput_candidates_start = msymbol ("input-candidates-start");
3051 Minput_candidates_done = msymbol ("input-candidates-done");
3052 Minput_candidates_draw = msymbol ("input-candidates-draw");
3053 Minput_set_spot = msymbol ("input-set-spot");
3054 Minput_focus_move = msymbol ("input-focus-move");
3055 Minput_focus_in = msymbol ("input-focus-in");
3056 Minput_focus_out = msymbol ("input-focus-out");
3057 Minput_toggle = msymbol ("input-toggle");
3058 Minput_reset = msymbol ("input-reset");
3059 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3060 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3062 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
3063 Mcandidate_index = msymbol (" candidate-index");
3065 Minit = msymbol ("init");
3066 Mfini = msymbol ("fini");
3068 M_key_alias = msymbol (" key-alias");
3069 M_description = msymbol ("description");
3070 M_command = msymbol ("command");
3071 M_variable = msymbol ("variable");
3073 load_im_info_keys = mplist ();
3074 mplist_add (load_im_info_keys, Mstate, Mnil);
3075 mplist_push (load_im_info_keys, Mmap, Mnil);
3080 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
3084 one_char_symbol[i] = msymbol (buf);
3087 alias = msymbol (key_names[i]);
3088 msymbol_put (one_char_symbol[i], M_key_alias, alias);
3091 alias = one_char_symbol[i];
3092 buf[2] += (i == 0) ? -32 : 32;
3093 msymbol_put (alias, M_key_alias, msymbol (buf));
3094 buf[2] -= (i == 0) ? -32 : 32;
3096 for (buf[2] = i; i < 127; i++, buf[2]++)
3097 one_char_symbol[i] = msymbol (buf + 2);
3098 one_char_symbol[i++] = msymbol ("Delete");
3104 for (buf[4] = '@'; i < 160; i++, buf[4]++)
3106 one_char_symbol[i] = msymbol (buf);
3107 if (key_names[i - 128])
3109 strcpy (buf2 + 2, key_names[i - 128]);
3110 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
3113 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
3114 one_char_symbol[i] = msymbol (buf + 2);
3115 one_char_symbol[i] = msymbol ("M-Delete");
3117 command_list = variable_list = NULL;
3119 minput_default_driver.open_im = open_im;
3120 minput_default_driver.close_im = close_im;
3121 minput_default_driver.create_ic = create_ic;
3122 minput_default_driver.destroy_ic = destroy_ic;
3123 minput_default_driver.filter = filter;
3124 minput_default_driver.lookup = lookup;
3125 minput_default_driver.callback_list = mplist ();
3126 mplist_put (minput_default_driver.callback_list, Minput_reset,
3128 minput_driver = &minput_default_driver;
3137 M17N_OBJECT_UNREF (command_list);
3138 command_list = NULL;
3142 M17N_OBJECT_UNREF (variable_list);
3143 variable_list = NULL;
3146 if (minput_default_driver.callback_list)
3148 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3149 minput_default_driver.callback_list = NULL;
3151 if (minput_driver->callback_list)
3153 M17N_OBJECT_UNREF (minput_driver->callback_list);
3154 minput_driver->callback_list = NULL;
3159 while (! MPLIST_TAIL_P (im_info_list))
3162 mplist_pop (im_info_list);
3163 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
3164 /* Pop (t . im_info) */
3165 mplist_pop (im_info_list);
3167 M17N_OBJECT_UNREF (im_info_list);
3168 im_info_list = NULL;
3171 M17N_OBJECT_UNREF (load_im_info_keys);
3175 minput__callback (MInputContext *ic, MSymbol command)
3177 if (ic->im->driver.callback_list)
3179 MInputCallbackFunc func
3180 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3184 (func) (ic, command);
3189 minput__char_to_key (int c)
3191 if (c < 0 || c >= 0x100)
3194 return one_char_symbol[c];
3198 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3203 /*** @addtogroup m17nInputMethod */
3208 @name Variables: Predefined symbols for callback commands.
3210 These are the predefined symbols that are used as the @c COMMAND
3211 argument of callback functions of an input method driver (see
3212 #MInputDriver::callback_list ).
3214 Most of them don't require extra argument nor return any value;
3215 exceptions are these:
3217 Minput_get_surrounding_text: When a callback function assigned for
3218 this command is called, the first element of #MInputContext::plist
3219 has key #Msymbol and the value specifies which portion of the
3220 surrounding text should be retrieved. If the value is positive,
3221 it specifies the number of characters following the current cursor
3222 position. If the value is negative, the absolute value specifies
3223 the number of characters preceding the current cursor position.
3224 The callback function must set the key of this element to #Mtext
3225 and the value to the retrived M-text (whose length may be shorter
3226 than the requested number of characters if the available text is
3227 not that long, or it may be longer if an application thinks it's
3228 more efficient to return that length).
3230 Minput_delete_surrounding_text: When a callback function assigned
3231 for this command is called, the first element of
3232 #MInputContext::plist has key #Msymbol and the value specifies
3233 which portion of the surrounding text should be deleted in the
3234 same way as the case of Minput_get_surrounding_text. The callback
3235 function must delete the specified text. It should not alter
3236 #MInputContext::plist. */
3239 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3241 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3242 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3247 MSymbol Minput_preedit_start;
3248 MSymbol Minput_preedit_done;
3249 MSymbol Minput_preedit_draw;
3250 MSymbol Minput_status_start;
3251 MSymbol Minput_status_done;
3252 MSymbol Minput_status_draw;
3253 MSymbol Minput_candidates_start;
3254 MSymbol Minput_candidates_done;
3255 MSymbol Minput_candidates_draw;
3256 MSymbol Minput_set_spot;
3257 MSymbol Minput_toggle;
3258 MSymbol Minput_reset;
3259 MSymbol Minput_get_surrounding_text;
3260 MSymbol Minput_delete_surrounding_text;
3266 @name Variables: Predefined symbols for special input events.
3268 These are the predefined symbols that are used as the @c KEY
3269 argument of minput_filter (). */
3274 MSymbol Minput_focus_out;
3275 MSymbol Minput_focus_in;
3276 MSymbol Minput_focus_move;
3283 @brief The default driver for internal input methods.
3285 The variable #minput_default_driver is the default driver for
3286 internal input methods.
3288 The member MInputDriver::open_im () searches the m17n database for
3289 an input method that matches the tag \< #Minput_method, $LANGUAGE,
3290 $NAME\> and loads it.
3292 The member MInputDriver::callback_list () is @c NULL. Thus, it is
3293 programmers responsibility to set it to a plist of proper callback
3294 functions. Otherwise, no feedback information (e.g. preedit text)
3295 can be shown to users.
3297 The macro M17N_INIT () sets the variable #minput_driver to the
3298 pointer to this driver so that all internal input methods use it.
3300 Therefore, unless @c minput_driver is set differently, the driver
3301 dependent arguments $ARG of the functions whose name begins with
3302 "minput_" are all ignored. */
3305 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
3307 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
3309 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
3310 \< #Minput_method, $LANGUAGE, $NAME\>
3311 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
3313 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
3314 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
3315 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
3316 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
3318 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
3319 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
3321 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
3322 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
3324 MInputDriver minput_default_driver;
3328 @brief The driver for internal input methods.
3330 The variable #minput_driver is a pointer to the input method
3331 driver that is used by internal input methods. The macro
3332 M17N_INIT () initializes it to a pointer to #minput_default_driver
3333 if <m17n<EM></EM>.h> is included. */
3335 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
3337 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
3338 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
3339 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
3340 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
3342 MInputDriver *minput_driver;
3344 MSymbol Minput_driver;
3349 @brief Open an input method.
3351 The minput_open_im () function opens an input method whose
3352 language and name match $LANGUAGE and $NAME, and returns a pointer
3353 to the input method object newly allocated.
3355 This function at first decides a driver for the input method as
3358 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3359 #minput_driver is used.
3361 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
3362 driver pointed to by the property value is used to open the input
3363 method. If $NAME has no such a property, @c NULL is returned.
3365 Then, the member MInputDriver::open_im () of the driver is
3368 $ARG is set in the member @c arg of the structure MInputMethod so
3369 that the driver can refer to it. */
3372 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3374 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3375 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3377 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3379 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3380 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3382 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3383 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3384 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3386 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3388 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3390 @latexonly \IPAlabel{minput_open} @endlatexonly
3395 minput_open_im (MSymbol language, MSymbol name, void *arg)
3398 MInputDriver *driver;
3400 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3401 msymbol_name (language), msymbol_name (name));
3403 driver = minput_driver;
3406 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3408 MERROR (MERROR_IM, NULL);
3411 MSTRUCT_CALLOC (im, MERROR_IM);
3412 im->language = language;
3415 im->driver = *driver;
3416 if ((*im->driver.open_im) (im) < 0)
3418 MDEBUG_PRINT (" failed\n");
3422 MDEBUG_PRINT (" ok\n");
3429 @brief Close an input method.
3431 The minput_close_im () function closes the input method $IM, which
3432 must have been created by minput_open_im (). */
3435 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3437 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3438 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3441 minput_close_im (MInputMethod *im)
3443 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3444 msymbol_name (im->name), msymbol_name (im->language));
3445 (*im->driver.close_im) (im);
3447 MDEBUG_PRINT (" done\n");
3453 @brief Create an input context.
3455 The minput_create_ic () function creates an input context object
3456 associated with input method $IM, and calls callback functions
3457 corresponding to #Minput_preedit_start, #Minput_status_start, and
3458 #Minput_status_draw in this order.
3461 If an input context is successfully created, minput_create_ic ()
3462 returns a pointer to it. Otherwise it returns @c NULL. */
3465 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3467 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3468 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3469 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3470 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3473 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3474 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3478 minput_create_ic (MInputMethod *im, void *arg)
3482 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3483 msymbol_name (im->name), msymbol_name (im->language));
3484 MSTRUCT_CALLOC (ic, MERROR_IM);
3487 ic->preedit = mtext ();
3488 ic->candidate_list = NULL;
3489 ic->produced = mtext ();
3490 ic->spot.x = ic->spot.y = 0;
3492 ic->plist = mplist ();
3493 if ((*im->driver.create_ic) (ic) < 0)
3495 MDEBUG_PRINT (" failed\n");
3496 M17N_OBJECT_UNREF (ic->preedit);
3497 M17N_OBJECT_UNREF (ic->produced);
3498 M17N_OBJECT_UNREF (ic->plist);
3503 if (im->driver.callback_list)
3505 minput__callback (ic, Minput_preedit_start);
3506 minput__callback (ic, Minput_status_start);
3507 minput__callback (ic, Minput_status_draw);
3510 MDEBUG_PRINT (" ok\n");
3517 @brief Destroy an input context.
3519 The minput_destroy_ic () function destroys the input context $IC,
3520 which must have been created by minput_create_ic (). It calls
3521 callback functions corresponding to #Minput_preedit_done,
3522 #Minput_status_done, and #Minput_candidates_done in this order. */
3525 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3527 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3528 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3529 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3530 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3531 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3535 minput_destroy_ic (MInputContext *ic)
3537 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3538 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3539 if (ic->im->driver.callback_list)
3541 minput__callback (ic, Minput_preedit_done);
3542 minput__callback (ic, Minput_status_done);
3543 minput__callback (ic, Minput_candidates_done);
3545 (*ic->im->driver.destroy_ic) (ic);
3546 M17N_OBJECT_UNREF (ic->preedit);
3547 M17N_OBJECT_UNREF (ic->produced);
3548 M17N_OBJECT_UNREF (ic->plist);
3549 MDEBUG_PRINT (" done\n");
3556 @brief Filter an input key.
3558 The minput_filter () function filters input key $KEY according to
3559 input context $IC, and calls callback functions corresponding to
3560 #Minput_preedit_draw, #Minput_status_draw, and
3561 #Minput_candidates_draw if the preedit text, the status, and the
3562 current candidate are changed respectively.
3564 To make the input method commit the current preedit text (if any)
3565 and shift to the initial state, call this function with #Mnil as
3568 To inform the input method about the focus-out event, call this
3569 function with #Minput_focus_out as $KEY.
3571 To inform the input method about the focus-in event, call this
3572 function with #Minput_focus_in as $KEY.
3574 To inform the input method about the focus-move event (i.e. input
3575 spot change within the same input context), call this function
3576 with #Minput_focus_move as $KEY.
3579 If $KEY is filtered out, this function returns 1. In that case,
3580 the caller should discard the key. Otherwise, it returns 0, and
3581 the caller should handle the key, for instance, by calling the
3582 function minput_lookup () with the same key. */
3585 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3587 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3588 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3589 #Minput_preedit_draw, #Minput_status_draw,
3590 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3593 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3594 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3595 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3596 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3598 @latexonly \IPAlabel{minput_filter} @endlatexonly
3602 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3609 ret = (*ic->im->driver.filter) (ic, key, arg);
3611 if (ic->im->driver.callback_list)
3613 if (ic->preedit_changed)
3614 minput__callback (ic, Minput_preedit_draw);
3615 if (ic->status_changed)
3616 minput__callback (ic, Minput_status_draw);
3617 if (ic->candidates_changed)
3618 minput__callback (ic, Minput_candidates_draw);
3627 @brief Look up a text produced in the input context.
3629 The minput_lookup () function looks up a text in the input context
3630 $IC. $KEY must be identical to the one that was used in the previous call of
3633 If a text was produced by the input method, it is concatenated
3636 This function calls #MInputDriver::lookup .
3639 If $KEY was correctly handled by the input method, this function
3640 returns 0. Otherwise, it returns -1, even though some text
3641 might be produced in $MT. */
3644 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3646 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3647 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3649 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3652 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3655 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3656 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3657 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3659 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3662 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3664 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3669 @brief Set the spot of the input context.
3671 The minput_set_spot () function sets the spot of input context $IC
3672 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3673 The semantics of these values depends on the input method driver.
3675 For instance, a driver designed to work in a CUI environment may
3676 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
3677 $DESCENT . A driver designed to work in a window system may
3678 interpret $X and $Y as the pixel offsets relative to the origin of the
3679 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3680 descent pixels of the line at ($X . $Y ).
3682 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3684 $MT and $POS are the M-text and the character position at the spot.
3685 $MT may be @c NULL, in which case, the input method cannot get
3686 information about the text around the spot. */
3689 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3691 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3692 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3693 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3695 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3696 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3697 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3698 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3699 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3700 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3702 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3704 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3705 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3709 minput_set_spot (MInputContext *ic, int x, int y,
3710 int ascent, int descent, int fontsize,
3715 ic->spot.ascent = ascent;
3716 ic->spot.descent = descent;
3717 ic->spot.fontsize = fontsize;
3720 if (ic->im->driver.callback_list)
3721 minput__callback (ic, Minput_set_spot);
3726 @brief Toggle input method.
3728 The minput_toggle () function toggles the input method associated
3729 with input context $IC. */
3731 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3733 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3734 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3738 minput_toggle (MInputContext *ic)
3740 if (ic->im->driver.callback_list)
3741 minput__callback (ic, Minput_toggle);
3742 ic->active = ! ic->active;
3748 @brief Reset an input context.
3750 The minput_reset_ic () function resets input context $IC by
3751 calling a callback function corresponding to #Minput_reset. It
3752 resets the status of $IC to its initial one. As the
3753 current preedit text is deleted without commitment, if necessary,
3754 call minput_filter () with the arg @r key #Mnil to force the input
3755 method to commit the preedit in advance. */
3758 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3760 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3761 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3762 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3763 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3764 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3765 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3768 minput_reset_ic (MInputContext *ic)
3770 if (ic->im->driver.callback_list)
3771 minput__callback (ic, Minput_reset);
3777 @brief Get title and icon filename of an input method.
3779 The minput_get_title_icon () function returns a plist containing a
3780 title and icon filename (if any) of the input method specifies by
3781 $LANGUAGE and $NAME.
3783 The first element of the plist has key Mtext and the value is an
3784 M-text of the title for identifying the input method. The second
3785 element (if any) has key M-text and the value is an M-text of the
3786 icon image (absolute) filename for the same purpose.
3789 If there exists the specified input method and it defines an
3790 title, a plist is retured. Otherwise, NULL is returned. A caller
3791 must free the plist by m17n_object_unref ().
3795 minput_get_title_icon (MSymbol language, MSymbol name)
3797 MPlist *plist = load_partial_im_info (language, name, Mnil, Mtitle);
3804 if (MPLIST_TAIL_P (plist))
3806 pl = MPLIST_PLIST (plist);
3807 pl = MPLIST_NEXT (pl);
3808 if (! MPLIST_MTEXT_P (pl))
3810 M17N_OBJECT_REF (pl);
3811 M17N_OBJECT_UNREF (plist);
3813 pl = MPLIST_NEXT (pl);
3814 if (MPLIST_MTEXT_P (pl))
3816 if (mtext_nchars (MPLIST_MTEXT (pl)) > 0)
3818 mt = MPLIST_MTEXT (pl);
3819 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
3822 else if (language != Mnil && name != Mnil)
3825 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
3828 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
3829 (char *) MSYMBOL_NAME (name));
3830 file = mdatabase__find_file (buf);
3831 if (! file && language == Mt)
3833 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
3834 file = mdatabase__find_file (buf);
3840 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
3842 mplist_set (pl, Mtext, mt);
3843 M17N_OBJECT_UNREF (mt);
3846 mplist_set (pl, Mnil, NULL);
3850 M17N_OBJECT_UNREF (plist);
3857 @brief Get description text of an input method.
3859 The minput_get_description () function returns an M-text that
3860 describes the input method specified by $LANGUAGE and $NAME.
3863 If the specified input method has a description text, a pointer to
3864 #MText is returned. The caller has to free it by m17n_object_unref ().
3865 If the input method does not have a description text, @c NULL is
3868 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3870 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3871 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3873 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3874 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3875 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3876 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3879 minput_get_description (MSymbol language, MSymbol name)
3881 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3887 if (MPLIST_TAIL_P (plist))
3889 M17N_OBJECT_UNREF (plist);
3892 pl = MPLIST_PLIST (plist);
3893 pl = MPLIST_NEXT (pl);
3894 if (MPLIST_MTEXT_P (pl))
3896 mt = MPLIST_MTEXT (pl);
3897 M17N_OBJECT_REF (mt);
3899 M17N_OBJECT_UNREF (plist);
3904 @brief Get information about input method commands.
3906 The minput_get_commands () function returns information about
3907 input method commands of the input method specified by $LANGUAGE
3908 and $NAME. An input method command is a pseudo key event to which
3909 one or more actual input key sequences are assigned.
3911 There are two kinds of commands, global and local. Global
3912 commands are used by multiple input methods for the same purpose,
3913 and have global key assignments. Local commands are used only by
3914 a specific input method, and have only local key assignments.
3916 Each input method may locally change key assignments for global
3917 commands. The global key assignment for a global command is
3918 effective only when the current input method does not have local
3919 key assignments for that command.
3921 If $NAME is #Mnil, information about global commands is returned.
3922 In this case $LANGUAGE is ignored.
3924 If $NAME is not #Mnil, information about those commands that have
3925 local key assignments in the input method specified by $LANGUAGE
3926 and $NAME is returned.
3929 If no input method commands are found, this function returns @c NULL.
3931 Otherwise, a pointer to a plist is returned. The key of each
3932 element in the plist is a symbol representing a command, and the
3933 value is a plist of the form COMMAND-INFO described below.
3935 The first element of COMMAND-INFO has the key #Mtext, and the
3936 value is an M-text describing the command.
3938 If there are no more elements, that means no key sequences are
3939 assigned to the command. Otherwise, each of the remaining
3940 elements has the key #Mplist, and the value is a plist whose keys are
3941 #Msymbol and values are symbols representing input keys, which are
3942 currently assigned to the command.
3944 As the returned plist is kept in the library, the caller must not
3945 modify nor free it. */
3947 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3949 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3950 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3951 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3952 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3954 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3955 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3956 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3957 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3959 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3960 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3961 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3964 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3965 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3967 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3968 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3972 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3974 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3975 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3976 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3978 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3979 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3980 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3983 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3984 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3985 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3986 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3987 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3989 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3990 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3993 minput_get_commands (MSymbol language, MSymbol name)
3995 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
3997 return (MPLIST_TAIL_P (plist) ? NULL : plist);
4001 @brief Assign a key sequence to an input method command.
4003 The minput_assign_command_keys () function assigns input key
4004 sequence $KEYSEQ to input method command $COMMAND for the input
4005 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
4006 key sequence is assigned globally no matter what $LANGUAGE is.
4007 Otherwise the key sequence is assigned locally.
4009 Each element of $KEYSEQ must have the key $Msymbol and the value
4010 must be a symbol representing an input key.
4012 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
4013 globally or locally.
4015 This assignment gets effective in a newly opened input method.
4018 If the operation was successful, 0 is returned. Otherwise -1 is
4019 returned, and #merror_code is set to #MERROR_IM. */
4021 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
4023 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
4024 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
4025 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
4026 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
4027 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
4029 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
4030 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4032 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
4033 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
4035 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
4038 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
4039 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
4042 minput_assign_command_keys (MSymbol language, MSymbol name,
4043 MSymbol command, MPlist *keyseq)
4045 MPlist *plist, *pl, *p;
4047 if (check_command_keyseq (keyseq) < 0
4048 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
4049 MERROR (MERROR_IM, -1);
4050 pl = mplist_get (plist, command);
4053 pl = MPLIST_NEXT (pl);
4055 while ((p = mplist_pop (pl)))
4056 M17N_OBJECT_UNREF (p);
4059 keyseq = mplist_copy (keyseq);
4060 mplist_push (pl, Mplist, keyseq);
4061 M17N_OBJECT_UNREF (keyseq);
4067 MERROR (MERROR_IM, -1);
4070 /* Get global commands. */
4071 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
4072 pl = mplist_get (pl, command);
4074 MERROR (MERROR_IM, -1);
4076 mplist_add (p, Mtext, mplist_value (pl));
4077 keyseq = mplist_copy (keyseq);
4078 mplist_add (p, Mplist, keyseq);
4079 M17N_OBJECT_UNREF (keyseq);
4080 mplist_push (plist, command, p);
4086 @brief Get a list of variables of an input method.
4088 The minput_get_variables () function returns a plist (#MPlist) of
4089 variables used to control the behavior of the input method
4090 specified by $LANGUAGE and $NAME. The plist is @e well-formed
4091 (#m17nPlist) of the following format:
4094 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
4095 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
4099 @c VARNAME is a symbol representing the variable name.
4101 @c DOC-MTEXT is an M-text describing the variable.
4103 @c DEFAULT-VALUE is the default value of the varible. It is a
4104 symbol, integer, or M-text.
4106 @c VALUEs (if any) specifies the possible values of the variable.
4107 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
4108 @c TO), where @c FROM and @c TO specifies a range of possible
4111 For instance, suppose an input method has the variables:
4113 @li name:intvar, description:"value is an integer",
4114 initial value:0, value-range:0..3,10,20
4116 @li name:symvar, description:"value is a symbol",
4117 initial value:nil, value-range:a, b, c, nil
4119 @li name:txtvar, description:"value is an M-text",
4120 initial value:empty text, no value-range (i.e. any text)
4122 Then, the returned plist is as follows.
4125 (intvar ("value is an integer" 0 (0 3) 10 20)
4126 symvar ("value is a symbol" nil a b c nil)
4127 txtvar ("value is an M-text" ""))
4131 If the input method uses any variables, a pointer to #MPlist is
4132 returned. As the plist is kept in the library, a caller must not
4133 modify nor free it. If the input method does not use any
4134 variable, @c NULL is returned. */
4136 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
4138 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
4139 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
4140 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
4144 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
4145 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
4149 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4151 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
4153 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
4156 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
4157 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
4158 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
4160 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
4162 @li name:intvar, ÀâÌÀ:"value is an integer",
4163 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
4165 @li name:symvar, ÀâÌÀ:"value is a symbol",
4166 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
4168 @li name:txtvar, ÀâÌÀ:"value is an M-text",
4169 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
4171 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
4174 (intvar ("value is an integer" 0 (0 3) 10 20)
4175 symvar ("value is a symbol" nil a b c nil)
4176 txtvar ("value is an M-text" ""))
4180 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4181 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4182 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
4185 minput_get_variables (MSymbol language, MSymbol name)
4187 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
4189 return (MPLIST_TAIL_P (plist) ? NULL : plist);
4193 @brief Set the initial value of an input method variable.
4195 The minput_set_variable () function sets the initial value of
4196 input method variable $VARIABLE to $VALUE for the input method
4197 specified by $LANGUAGE and $NAME.
4199 By default, the initial value is 0.
4201 This setting gets effective in a newly opened input method.
4204 If the operation was successful, 0 is returned. Otherwise -1 is
4205 returned, and #merror_code is set to #MERROR_IM. */
4207 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
4209 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
4210 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
4211 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
4213 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
4215 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
4218 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
4219 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
4222 minput_set_variable (MSymbol language, MSymbol name,
4223 MSymbol variable, void *value)
4225 MPlist *plist, *val_element, *range_element;
4228 plist = get_nested_list (language, name, Mnil, M_variable);
4230 MERROR (MERROR_IM, -1);
4231 plist = mplist_find_by_value (plist, variable);
4233 MERROR (MERROR_IM, -1);
4234 plist = MPLIST_PLIST (MPLIST_NEXT (plist));
4235 val_element = MPLIST_NEXT (plist);
4236 type = MPLIST_KEY (val_element);
4237 range_element = MPLIST_NEXT (val_element);
4239 if (! MPLIST_TAIL_P (range_element))
4241 if (type == Minteger)
4243 int val = (int) value, this_val;
4245 MPLIST_DO (plist, range_element)
4247 this_val = (int) MPLIST_VAL (plist);
4248 if (MPLIST_PLIST_P (plist))
4250 int min_bound, max_bound;
4251 MPlist *pl = MPLIST_PLIST (plist);
4253 min_bound = (int) MPLIST_VAL (pl);
4254 pl = MPLIST_NEXT (pl);
4255 max_bound = (int) MPLIST_VAL (pl);
4256 if (val >= min_bound && val <= max_bound)
4259 else if (val == this_val)
4262 if (MPLIST_TAIL_P (plist))
4263 MERROR (MERROR_IM, -1);
4265 else if (type == Msymbol)
4267 MPLIST_DO (plist, range_element)
4268 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
4270 if (MPLIST_TAIL_P (plist))
4271 MERROR (MERROR_IM, -1);
4273 else /* type == Mtext */
4275 MPLIST_DO (plist, range_element)
4276 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
4278 if (MPLIST_TAIL_P (plist))
4279 MERROR (MERROR_IM, -1);
4280 M17N_OBJECT_REF (value);
4284 mplist_set (val_element, type, value);
4290 /*** @addtogroup m17nDebug */
4296 @brief Dump an input method.
4298 The mdebug_dump_im () function prints the input method $IM in a
4299 human readable way to the stderr. $INDENT specifies how many
4300 columns to indent the lines but the first one.
4303 This function returns $IM. */
4305 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
4307 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
4308 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
4311 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
4314 mdebug_dump_im (MInputMethod *im, int indent)
4316 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
4319 prefix = (char *) alloca (indent + 1);
4320 memset (prefix, 32, indent);
4321 prefix[indent] = '\0';
4323 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
4324 msymbol_name (im->name));
4325 mdebug_dump_mtext (im_info->title, 0, 0);
4326 if (im->name != Mnil)
4330 MPLIST_DO (state, im_info->states)
4332 fprintf (stderr, "\n%s ", prefix);
4333 dump_im_state (MPLIST_VAL (state), indent + 2);
4336 fprintf (stderr, ")");