1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides a input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and the body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those driver utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provides an input method that is not only for a specific language.
44 The database uses @c Mt as LANGUAGE of such an input method.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer have to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and the body is
56 defined in an external resources (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤÏm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë
95 <Minput_method, LANGUAGE, NAME>
96 ¤È¤¤¤¦¥¿¥°¤òÉÕ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£
97 ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç¤Ï
98 CUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ¤¤¤ë¡£
99 ¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍøÍѤ¹¤ë¡£
100 m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄêµÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢
101 ¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
103 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£
104 @c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢
105 ÆþÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
106 ¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤ÎÀâÌÀ¤ò»²¾È¡£
108 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
110 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£
111 ¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê¤É¡£)
112 ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver
113 ¤ò¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
114 ¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â
115 @c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö¤¬¤Ç¤¤ë¡£
117 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot
118 ¤ÎÆþÎÏ¥¹¥¿¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
119 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý¤·¤Æ¤¤¤ë¡£
120 ¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
126 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
128 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
129 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
130 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
131 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
135 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
136 /*** @addtogroup m17nInternal
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 M_candidates;
176 static MSymbol Mcandidate_list, Mcandidate_index;
178 static MSymbol Minit, Mfini;
180 /** Symbols for variables. */
181 static MSymbol Mcandidates_group_size, Mcandidates_charset;
183 /** Symbols for key events. */
184 static MSymbol one_char_symbol[256];
186 static MSymbol M_key_alias;
188 static MSymbol M_description, M_command, M_variable;
190 /** Structure to hold a map. */
194 /** List of actions to take when we reach the map. In a root map,
195 the actions are executed only when there's no more key. */
198 /** List of deeper maps. If NULL, this is a terminal map. */
201 /** List of actions to take when we leave the map successfully. In
202 a root map, the actions are executed only when none of submaps
203 handle the current key. */
204 MPlist *branch_actions;
207 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
212 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
219 /** Name of the state. */
222 /** Title of the state, or NULL. */
225 /** Key translation map of the state. Built by merging all maps of
230 /* Lookup keys KEY1,2,3 in the nested plist PLIST, and return the
234 lookup_nested_list (MPlist *plist, MSymbol key1, MSymbol key2, MSymbol key3)
239 key[0] = key1, key[1] = key2, key[2] = key3;
240 for (i = 0; i < 3; i++)
242 plist = mplist_find_by_value (plist, key[i]);
245 plist = MPLIST_NEXT (plist);
246 plist = MPLIST_PLIST (plist);
251 /* Set VAL for keys KEY1,2,3 in the nested plist PLIST. */
254 set_nested_list (MPlist *plist, MSymbol key1, MSymbol key2, MSymbol key3,
261 key[0] = key1, key[1] = key2, key[2] = key3;
262 for (i = 0; i < 3; i++)
264 pl = mplist_find_by_value (plist, key[i]);
267 pl = MPLIST_NEXT (pl);
268 plist = MPLIST_PLIST (pl);
272 pl = mplist_add (plist, Msymbol, key[i]);
274 pl = mplist_add (pl, Mplist, plist);
275 M17N_OBJECT_UNREF (plist);
278 mplist_set (pl, Mplist, val);
279 M17N_OBJECT_UNREF (val);
283 /* Parse PLIST as a value of nested list and return an adjusted list.
288 [ mtext:DESCRIPTION | symbol:nil ]
289 ;; The remaining elements are checked CHECK_FUNC.
292 [ mtext:DESCRIPTION | symbol:nil ]
293 ;; The remaining elements are checked CHECK_FUNC.
297 GLOBAL is a global list. If a description text is missing, it is
298 extracted from GLOBAL.
300 The return value is a plist of this format:
302 plist:([ mtext:DESCRIPTION | symbol:nil ]
305 plist:([ mtext:DESCRIPTION | symbol:nil ]
309 PLIST itself is unref-ed. */
312 parse_nested_list_value (MPlist *plist, MPlist *global, MSymbol key,
313 int (*check_func) (MPlist *))
315 MPlist *val, *pl, *p, *p0;
318 if (! MPLIST_PLIST_P (plist))
320 M17N_OBJECT_UNREF (plist);
323 pl = MPLIST_PLIST (plist);
324 if (! MPLIST_SYMBOL_P (pl)
325 || MPLIST_SYMBOL (pl) != key)
327 M17N_OBJECT_UNREF (plist);
331 MPLIST_DO (pl, MPLIST_NEXT (pl))
336 if (! MPLIST_PLIST_P (pl))
338 p = MPLIST_PLIST (pl);
339 if (! MPLIST_SYMBOL_P (p))
341 name = MPLIST_SYMBOL (p);
343 if (MPLIST_TAIL_P (p))
347 global_def = mplist_find_by_value (global, name);
350 global_def = MPLIST_PLIST (MPLIST_NEXT (global_def));
351 mplist__conc (p, global_def);
354 p0 = MPLIST_NEXT (p);
355 if (MPLIST_TAIL_P (p0))
359 global_def = mplist_find_by_value (global, name);
362 global_def = MPLIST_PLIST (MPLIST_NEXT (global_def));
363 global_def = MPLIST_NEXT (global_def);
364 if (MPLIST_TAIL_P (global_def))
366 mplist__conc (p0, global_def);
368 if ((*check_func) (p0) < 0)
370 mplist_add (val, Msymbol, name);
371 mplist_add (val, Mplist, p);
374 M17N_OBJECT_UNREF (plist);
378 static MPlist *variable_list, *command_list;
379 static int check_variable_list (MPlist *plist);
380 static int check_command_list (MPlist *plist);
381 static MPlist *load_partial_im_info (MSymbol language, MSymbol name,
382 MSymbol extra, MSymbol key);
385 get_nested_list (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
388 int (*check_func) (MPlist *);
389 MPlist *plist, *global;
391 if (key == M_variable)
394 variable_list = mplist ();
395 total_list = variable_list;
396 check_func = check_variable_list;
401 command_list = mplist ();
402 total_list = command_list;
403 check_func = check_command_list;
406 if (MPLIST_TAIL_P (total_list))
408 plist = load_partial_im_info (Mt, Mnil, key, key);
410 global = parse_nested_list_value (plist, NULL, key, check_func);
413 set_nested_list (total_list, Mt, Mnil, key, global);
416 global = lookup_nested_list (total_list, Mt, Mnil, key);
421 plist = lookup_nested_list (total_list, language, name, extra);
425 plist = load_partial_im_info (language, name, extra, key);
427 plist = parse_nested_list_value (plist, global, key, check_func);
430 set_nested_list (total_list, language, name, extra, plist);
435 marker_code (MSymbol sym)
441 name = MSYMBOL_NAME (sym);
442 return ((name[0] == '@'
443 && ((name[1] >= '0' && name[1] <= '9')
444 || name[1] == '<' || name[1] == '>'
445 || name[1] == '=' || name[1] == '+' || name[1] == '-'
446 || name[1] == '[' || name[1] == ']'
454 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
458 MPLIST_DO (p, ic_info->vars)
460 if (MPLIST_SYMBOL (p) == var)
464 if (MPLIST_TAIL_P (p))
467 mplist_push (p, Minteger, (void *) 0);
468 mplist_push (p, Msymbol, var);
470 return (MPLIST_NEXT (p));
474 get_surrounding_text (MInputContext *ic, int len)
478 mplist_push (ic->plist, Minteger, (void *) len);
479 minput__callback (ic, Minput_get_surrounding_text);
480 if (MPLIST_MTEXT_P (ic->plist))
482 mt = MPLIST_MTEXT (ic->plist);
483 mplist_pop (ic->plist);
489 delete_surrounding_text (MInputContext *ic, int pos)
491 mplist_push (ic->plist, Minteger, (void *) pos);
492 minput__callback (ic, Minput_delete_surrounding_text);
493 mplist_pop (ic->plist);
497 get_preceding_char (MInputContext *ic, int pos)
499 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
503 if (ic_info->preceding_text)
505 len = mtext_nchars (ic_info->preceding_text);
507 return mtext_ref_char (ic_info->preceding_text, len - pos);
509 mt = get_surrounding_text (ic, - pos);
512 len = mtext_nchars (mt);
513 if (ic_info->preceding_text)
515 if (mtext_nchars (ic_info->preceding_text) < len)
517 M17N_OBJECT_UNREF (ic_info->preceding_text);
518 ic_info->preceding_text = mt;
522 ic_info->preceding_text = mt;
525 return mtext_ref_char (ic_info->preceding_text, len - pos);
529 get_following_char (MInputContext *ic, int pos)
531 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
535 if (ic_info->following_text)
537 len = mtext_nchars (ic_info->following_text);
539 return mtext_ref_char (ic_info->following_text, pos - 1);
541 mt = get_surrounding_text (ic, pos);
544 len = mtext_nchars (mt);
545 if (ic_info->following_text)
547 if (mtext_nchars (ic_info->following_text) < len)
549 M17N_OBJECT_UNREF (ic_info->following_text);
550 ic_info->following_text = mt;
554 ic_info->following_text = mt;
557 return mtext_ref_char (ic_info->following_text, pos - 1);
561 surrounding_pos (MSymbol sym)
567 name = MSYMBOL_NAME (sym);
568 if ((name[1] == '-' || name[1] == '+')
569 && name[2] >= '1' && name[2] <= '9')
570 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
575 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
577 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
579 MText *preedit = ic->preedit;
580 int len = mtext_nchars (preedit);
584 if (MPLIST_INTEGER_P (arg))
585 return MPLIST_INTEGER (arg);
587 && (surrounding = surrounding_pos (MPLIST_SYMBOL (arg))) != 0)
588 return (surrounding < 0
589 ? get_preceding_char (ic, - surrounding)
590 : get_following_char (ic, surrounding));
591 code = marker_code (MPLIST_SYMBOL (arg));
594 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
598 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
601 return ic_info->key_head;
602 if (code >= '0' && code <= '9')
604 else if (code == '=')
605 code = ic->cursor_pos;
606 else if (code == '-' || code == '[')
607 code = ic->cursor_pos - 1;
608 else if (code == '+' || code == ']')
609 code = ic->cursor_pos + 1;
610 else if (code == '<')
612 else if (code == '>')
614 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
618 /* Parse PLIST as an action list. PLIST should have this form:
619 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
620 Return 0 if successfully parsed, otherwise return -1. */
623 parse_action_list (MPlist *plist, MPlist *macros)
625 MPLIST_DO (plist, plist)
627 if (MPLIST_MTEXT_P (plist))
629 /* This is a short form of (insert MTEXT). */
630 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
631 MERROR (MERROR_IM, -1); */
633 else if (MPLIST_PLIST_P (plist)
634 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
635 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
639 /* This is a short form of (insert (GROUPS *)). */
640 MPLIST_DO (pl, MPLIST_PLIST (plist))
642 if (MPLIST_PLIST_P (pl))
646 MPLIST_DO (elt, MPLIST_PLIST (pl))
647 if (! MPLIST_MTEXT_P (elt)
648 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
649 MERROR (MERROR_IM, -1);
653 if (! MPLIST_MTEXT_P (pl)
654 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
655 MERROR (MERROR_IM, -1);
659 else if (MPLIST_INTEGER_P (plist))
661 int c = MPLIST_INTEGER (plist);
663 if (c < 0 || c > MCHAR_MAX)
664 MERROR (MERROR_IM, -1);
666 else if (MPLIST_PLIST_P (plist)
667 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
669 MPlist *pl = MPLIST_PLIST (plist);
670 MSymbol action_name = MPLIST_SYMBOL (pl);
672 pl = MPLIST_NEXT (pl);
674 if (action_name == Minsert)
676 if (MPLIST_MTEXT_P (pl))
678 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
679 MERROR (MERROR_IM, -1);
681 else if (MPLIST_PLIST_P (pl))
685 if (MPLIST_PLIST_P (pl))
689 MPLIST_DO (elt, MPLIST_PLIST (pl))
690 if (! MPLIST_MTEXT_P (elt)
691 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
692 MERROR (MERROR_IM, -1);
696 if (! MPLIST_MTEXT_P (pl)
697 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
698 MERROR (MERROR_IM, -1);
702 else if (! MPLIST_SYMBOL_P (pl))
703 MERROR (MERROR_IM, -1);
705 else if (action_name == Mselect
706 || action_name == Mdelete
707 || action_name == Mmove)
709 if (! MPLIST_SYMBOL_P (pl)
710 && ! MPLIST_INTEGER_P (pl))
711 MERROR (MERROR_IM, -1);
713 else if (action_name == Mmark
714 || action_name == Mcall
715 || action_name == Mshift)
717 if (! MPLIST_SYMBOL_P (pl))
718 MERROR (MERROR_IM, -1);
720 else if (action_name == Mundo)
722 if (! MPLIST_TAIL_P (pl))
724 if (! MPLIST_SYMBOL_P (pl)
725 && (! MPLIST_INTEGER_P (pl)
726 || MPLIST_INTEGER (pl) == 0))
727 MERROR (MERROR_IM, -1);
730 else if (action_name == Mpushback)
732 if (MPLIST_MTEXT_P (pl))
734 MText *mt = MPLIST_MTEXT (pl);
736 if (mtext_nchars (mt) != mtext_nbytes (mt))
737 MERROR (MERROR_IM, -1);
739 else if (MPLIST_PLIST_P (pl))
743 MPLIST_DO (p, MPLIST_PLIST (pl))
744 if (! MPLIST_SYMBOL_P (p))
745 MERROR (MERROR_IM, -1);
747 else if (! MPLIST_INTEGER_P (pl))
748 MERROR (MERROR_IM, -1);
750 else if (action_name == Mset || action_name == Madd
751 || action_name == Msub || action_name == Mmul
752 || action_name == Mdiv)
754 if (! (MPLIST_SYMBOL_P (pl)
755 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
756 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
757 MERROR (MERROR_IM, -1);
759 else if (action_name == Mequal || action_name == Mless
760 || action_name == Mgreater)
762 if (! ((MPLIST_INTEGER_P (pl) || MPLIST_SYMBOL_P (pl))
763 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
764 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
765 MERROR (MERROR_IM, -1);
766 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
767 if (! MPLIST_PLIST_P (pl))
768 MERROR (MERROR_IM, -1);
769 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
770 MERROR (MERROR_IM, -1);
771 pl = MPLIST_NEXT (pl);
772 if (MPLIST_PLIST_P (pl)
773 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
774 MERROR (MERROR_IM, -1);
776 else if (action_name == Mshow || action_name == Mhide
777 || action_name == Mcommit || action_name == Munhandle)
779 else if (! macros || ! mplist_get (macros, action_name))
780 MERROR (MERROR_IM, -1);
783 MERROR (MERROR_IM, -1);
790 resolve_command (MSymbol language, MSymbol name, MSymbol command)
792 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
795 || ! (plist = mplist_get (plist, command)))
797 plist = MPLIST_NEXT (plist);
798 if (! MPLIST_PLIST_P (plist))
805 /* Load a translation into MAP from PLIST.
807 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
810 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
811 MPlist *branch_actions, MPlist *macros)
816 if (MPLIST_MTEXT_P (keylist))
818 MText *mt = MPLIST_MTEXT (keylist);
820 len = mtext_nchars (mt);
821 if (len == 0 || len != mtext_nbytes (mt))
822 MERROR (MERROR_IM, -1);
823 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
824 for (i = 0; i < len; i++)
825 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
827 else if (MPLIST_PLIST_P (keylist))
829 MPlist *elt = MPLIST_PLIST (keylist);
831 len = MPLIST_LENGTH (elt);
833 MERROR (MERROR_IM, -1);
834 keyseq = (MSymbol *) alloca (sizeof (int) * len);
835 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
837 if (MPLIST_INTEGER_P (elt))
839 int c = MPLIST_INTEGER (elt);
841 if (c < 0 || c >= 0x100)
842 MERROR (MERROR_IM, -1);
843 keyseq[i] = one_char_symbol[c];
845 else if (MPLIST_SYMBOL_P (elt))
846 keyseq[i] = MPLIST_SYMBOL (elt);
848 MERROR (MERROR_IM, -1);
852 MERROR (MERROR_IM, -1);
854 for (i = 0; i < len; i++)
856 MIMMap *deeper = NULL;
859 deeper = mplist_get (map->submaps, keyseq[i]);
861 map->submaps = mplist ();
864 /* Fixme: It is better to make all deeper maps at once. */
865 MSTRUCT_CALLOC (deeper, MERROR_IM);
866 mplist_put (map->submaps, keyseq[i], deeper);
871 /* We reach a terminal map. */
873 || map->branch_actions)
874 /* This map is already defined. We avoid overriding it. */
877 if (! MPLIST_TAIL_P (map_actions))
879 if (parse_action_list (map_actions, macros) < 0)
880 MERROR (MERROR_IM, -1);
881 map->map_actions = map_actions;
885 map->branch_actions = branch_actions;
886 M17N_OBJECT_REF (branch_actions);
892 /* Load a branch from PLIST into MAP. PLIST has this form:
893 PLIST ::= ( MAP-NAME BRANCH-ACTION * )
894 MAPS is a plist of raw maps.
895 STATE is the current state. */
898 load_branch (MPlist *plist, MPlist *maps, MIMMap *map,
899 MSymbol language, MSymbol name, MPlist *macros)
902 MPlist *branch_actions;
904 if (! MPLIST_SYMBOL_P (plist))
905 MERROR (MERROR_IM, -1);
906 map_name = MPLIST_SYMBOL (plist);
907 plist = MPLIST_NEXT (plist);
908 if (MPLIST_TAIL_P (plist))
909 branch_actions = NULL;
910 else if (parse_action_list (plist, macros) < 0)
911 MERROR (MERROR_IM, -1);
913 branch_actions = plist;
914 if (map_name == Mnil)
916 map->branch_actions = branch_actions;
918 M17N_OBJECT_REF (branch_actions);
920 else if (map_name == Mt)
922 map->map_actions = branch_actions;
924 M17N_OBJECT_REF (branch_actions);
926 else if ((plist = (MPlist *) mplist_get (maps, map_name)))
928 MPLIST_DO (plist, plist)
930 MPlist *keylist, *map_actions;
932 if (! MPLIST_PLIST_P (plist))
933 MERROR (MERROR_IM, -1);
934 keylist = MPLIST_PLIST (plist);
935 map_actions = MPLIST_NEXT (keylist);
936 if (MPLIST_SYMBOL_P (keylist))
938 MSymbol command = MPLIST_SYMBOL (keylist);
939 MPlist *pl = resolve_command (language, name, command);
944 if (load_translation (map, pl, map_actions, branch_actions,
946 MERROR (MERROR_IM, -1);
949 if (load_translation (map, keylist, map_actions, branch_actions,
951 MERROR (MERROR_IM, -1);
958 /* Load a macro from PLIST into MACROS.
960 PLIST ::= ( MACRO-NAME ACTION * )
961 MACROS is a plist of macro names vs action list. */
963 load_macros (MPlist *plist, MPlist *macros)
967 if (! MPLIST_SYMBOL_P (plist))
968 MERROR (MERROR_IM, -1);
969 name = MPLIST_SYMBOL (plist);
970 plist = MPLIST_NEXT (plist);
971 if (MPLIST_TAIL_P (plist)
972 || parse_action_list (plist, macros) < 0)
973 MERROR (MERROR_IM, -1);
974 mplist_put (macros, name, plist);
975 M17N_OBJECT_REF (plist);
979 /* Load an external module from PLIST into EXTERNALS.
981 PLIST ::= ( MODULE-NAME FUNCTION * )
982 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
985 load_external_module (MPlist *plist, MPlist *externals)
990 MIMExternalModule *external;
994 if (MPLIST_MTEXT_P (plist))
995 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
996 else if (MPLIST_SYMBOL_P (plist))
997 module = MPLIST_SYMBOL (plist);
998 module_file = alloca (strlen (MSYMBOL_NAME (module))
999 + strlen (DLOPEN_SHLIB_EXT) + 1);
1000 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1002 handle = dlopen (module_file, RTLD_NOW);
1005 fprintf (stderr, "%s\n", dlerror ());
1006 MERROR (MERROR_IM, -1);
1008 func_list = mplist ();
1009 MPLIST_DO (plist, MPLIST_NEXT (plist))
1011 if (! MPLIST_SYMBOL_P (plist))
1012 MERROR_GOTO (MERROR_IM, err_label);
1013 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1015 MERROR_GOTO (MERROR_IM, err_label);
1016 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1019 MSTRUCT_MALLOC (external, MERROR_IM);
1020 external->handle = handle;
1021 external->func_list = func_list;
1022 mplist_add (externals, module, external);
1027 M17N_OBJECT_UNREF (func_list);
1032 free_map (MIMMap *map, int top)
1037 M17N_OBJECT_UNREF (map->map_actions);
1040 MPLIST_DO (plist, map->submaps)
1041 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1042 M17N_OBJECT_UNREF (map->submaps);
1044 M17N_OBJECT_UNREF (map->branch_actions);
1049 free_state (void *object)
1051 MIMState *state = object;
1054 M17N_OBJECT_UNREF (state->title);
1056 free_map (state->map, 1);
1060 /** Load a state from PLIST into a newly allocated state object.
1061 PLIST has this form:
1062 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1063 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1064 MAPS is a plist of defined maps.
1065 Return the state object. */
1068 load_state (MPlist *plist, MPlist *maps, MSymbol language, MSymbol name,
1073 if (! MPLIST_SYMBOL_P (plist))
1074 MERROR (MERROR_IM, NULL);
1075 M17N_OBJECT (state, free_state, MERROR_IM);
1076 state->name = MPLIST_SYMBOL (plist);
1077 plist = MPLIST_NEXT (plist);
1078 if (MPLIST_MTEXT_P (plist))
1080 state->title = MPLIST_MTEXT (plist);
1081 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1082 Mlanguage, language);
1083 M17N_OBJECT_REF (state->title);
1084 plist = MPLIST_NEXT (plist);
1086 MSTRUCT_CALLOC (state->map, MERROR_IM);
1087 MPLIST_DO (plist, plist)
1088 if (! MPLIST_PLIST_P (plist)
1089 || load_branch (MPLIST_PLIST (plist), maps, state->map, language, name,
1091 MERROR (MERROR_IM, NULL);
1096 static MPlist *im_info_list;
1099 free_im_info (MInputMethodInfo *im_info)
1104 M17N_OBJECT_UNREF (im_info->title);
1105 if (im_info->states)
1107 MPLIST_DO (plist, im_info->states)
1109 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1111 M17N_OBJECT_UNREF (state);
1113 M17N_OBJECT_UNREF (im_info->states);
1116 if (im_info->macros)
1118 MPLIST_DO (plist, im_info->macros)
1119 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1120 M17N_OBJECT_UNREF (im_info->macros);
1123 if (im_info->externals)
1125 MPLIST_DO (plist, im_info->externals)
1127 MIMExternalModule *external = MPLIST_VAL (plist);
1129 dlclose (external->handle);
1130 M17N_OBJECT_UNREF (external->func_list);
1132 MPLIST_KEY (plist) = Mt;
1134 M17N_OBJECT_UNREF (im_info->externals);
1138 MPLIST_DO (plist, im_info->maps)
1140 MPlist *p = MPLIST_PLIST (plist);
1142 M17N_OBJECT_UNREF (p);
1144 M17N_OBJECT_UNREF (im_info->maps);
1150 static MInputMethodInfo *get_im_info (MSymbol language, MSymbol name,
1153 static MInputMethodInfo *
1154 get_im_info_by_tags (MPlist *plist)
1159 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1160 i++, plist = MPLIST_NEXT (plist))
1161 tag[i] = MPLIST_SYMBOL (plist);
1166 return get_im_info (tag[0], tag[1], tag[2]);
1169 /* Load an input method from PLIST into IM_INTO, and return it. */
1171 static MInputMethodInfo *
1172 load_im_info (MSymbol language, MSymbol name, MPlist *plist)
1174 MInputMethodInfo *im_info;
1175 MText *title = NULL;
1176 MPlist *maps = NULL;
1177 MPlist *states = NULL;
1178 MPlist *externals = NULL;
1179 MPlist *macros = NULL;
1182 MSTRUCT_CALLOC (im_info, MERROR_IM);
1184 while (MPLIST_PLIST_P (plist))
1186 elt = MPLIST_PLIST (plist);
1187 if (! MPLIST_SYMBOL_P (elt))
1188 MERROR_GOTO (MERROR_IM, err);
1189 if (MPLIST_SYMBOL (elt) == Mtitle)
1191 elt = MPLIST_NEXT (elt);
1192 if (! MPLIST_MTEXT_P (elt))
1193 MERROR_GOTO (MERROR_IM, err);
1194 im_info->title = title = MPLIST_MTEXT (elt);
1195 M17N_OBJECT_REF (title);
1197 else if (MPLIST_SYMBOL (elt) == Mmap)
1199 MPlist *pl = mplist__from_alist (MPLIST_NEXT (elt));
1202 MERROR_GOTO (MERROR_IM, err);
1204 im_info->maps = maps = pl;
1206 maps = mplist__conc (maps, pl);
1208 else if (MPLIST_SYMBOL (elt) == Mmacro)
1211 im_info->macros = macros = mplist ();
1212 MPLIST_DO (elt, MPLIST_NEXT (elt))
1214 if (! MPLIST_PLIST_P (elt)
1215 || load_macros (MPLIST_PLIST (elt), macros) < 0)
1216 MERROR_GOTO (MERROR_IM, err);
1219 else if (MPLIST_SYMBOL (elt) == Mmodule)
1222 im_info->externals = externals = mplist ();
1223 MPLIST_DO (elt, MPLIST_NEXT (elt))
1225 if (! MPLIST_PLIST_P (elt)
1226 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
1227 MERROR_GOTO (MERROR_IM, err);
1230 else if (MPLIST_SYMBOL (elt) == Mstate)
1232 MPLIST_DO (elt, MPLIST_NEXT (elt))
1236 if (! MPLIST_PLIST_P (elt))
1237 MERROR_GOTO (MERROR_IM, err);
1238 state = load_state (MPLIST_PLIST (elt), maps, language, name,
1241 MERROR_GOTO (MERROR_IM, err);
1243 im_info->states = states = mplist ();
1244 mplist_put (states, state->name, state);
1247 else if (MPLIST_SYMBOL (elt) == Minclude)
1249 /* elt ::= include (tag1 tag2 ...) key item ... */
1251 MInputMethodInfo *temp;
1254 elt = MPLIST_NEXT (elt);
1255 if (! MPLIST_PLIST_P (elt))
1256 MERROR_GOTO (MERROR_IM, err);
1257 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
1259 MERROR_GOTO (MERROR_IM, err);
1260 elt = MPLIST_NEXT (elt);
1261 if (! MPLIST_SYMBOL_P (elt))
1262 MERROR_GOTO (MERROR_IM, err);
1263 key = MPLIST_SYMBOL (elt);
1264 elt = MPLIST_NEXT (elt);
1268 im_info->maps = maps = mplist ();
1269 MPLIST_DO (pl, temp->maps)
1271 p = MPLIST_VAL (pl);
1272 MPLIST_ADD_PLIST (maps, MPLIST_KEY (pl), p);
1273 M17N_OBJECT_REF (p);
1276 else if (key == Mmacro)
1279 im_info->macros = macros = mplist ();
1280 MPLIST_DO (pl, temp->macros)
1282 p = MPLIST_VAL (pl);
1283 MPLIST_ADD_PLIST (macros, MPLIST_KEY (pl), p);
1284 M17N_OBJECT_REF (p);
1287 else if (key == Mstate)
1290 im_info->states = states = mplist ();
1291 MPLIST_DO (pl, temp->states)
1293 MIMState *state = MPLIST_VAL (pl);
1295 mplist_add (states, MPLIST_KEY (pl), state);
1296 M17N_OBJECT_REF (state);
1300 MERROR_GOTO (MERROR_IM, err);
1302 plist = MPLIST_NEXT (plist);
1307 if (! title && name)
1309 = title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
1310 MTEXT_FORMAT_US_ASCII);
1314 free_im_info (im_info);
1320 static int take_action_list (MInputContext *ic, MPlist *action_list);
1321 static void preedit_commit (MInputContext *ic);
1324 shift_state (MInputContext *ic, MSymbol state_name)
1326 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1327 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1328 MIMState *orig_state = ic_info->state, *state;
1330 /* Find a state to shift to. If not found, shift to the initial
1332 if (state_name == Mt)
1334 if (! ic_info->prev_state)
1336 state = ic_info->prev_state;
1340 state = (MIMState *) mplist_get (im_info->states, state_name);
1342 state = (MIMState *) MPLIST_VAL (im_info->states);
1345 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
1347 /* Enter the new state. */
1348 ic_info->state = state;
1349 ic_info->map = state->map;
1350 ic_info->state_key_head = ic_info->key_head;
1351 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1352 /* We have shifted to the initial state. */
1353 preedit_commit (ic);
1354 mtext_cpy (ic_info->preedit_saved, ic->preedit);
1355 ic_info->state_pos = ic->cursor_pos;
1356 if (state != orig_state )
1358 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1359 ic_info->prev_state = NULL;
1361 ic_info->prev_state = orig_state;
1364 ic->status = state->title;
1366 ic->status = im_info->title;
1367 ic->status_changed = 1;
1368 if (ic_info->map == ic_info->state->map
1369 && ic_info->map->map_actions)
1371 MDEBUG_PRINT (" init-actions:");
1372 take_action_list (ic, ic_info->map->map_actions);
1377 /* Find a candidate group that contains a candidate number INDEX from
1378 PLIST. Set START_INDEX to the first candidate number of the group,
1379 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
1380 candidate group number if they are non-NULL. If INDEX is -1, find
1381 the last candidate group. */
1384 find_candidates_group (MPlist *plist, int index,
1385 int *start_index, int *end_index, int *group_index)
1387 int i = 0, gidx = 0, len;
1389 MPLIST_DO (plist, plist)
1391 if (MPLIST_MTEXT_P (plist))
1392 len = mtext_nchars (MPLIST_MTEXT (plist));
1394 len = mplist_length (MPLIST_PLIST (plist));
1395 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
1401 *end_index = i + len;
1403 *group_index = gidx;
1413 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
1415 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1417 int nchars = mt ? mtext_nchars (mt) : 1;
1420 mtext_ins (ic->preedit, pos, mt);
1422 mtext_ins_char (ic->preedit, pos, c, 1);
1423 MPLIST_DO (markers, ic_info->markers)
1424 if (MPLIST_INTEGER (markers) > pos)
1425 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
1426 if (ic->cursor_pos >= pos)
1427 ic->cursor_pos += nchars;
1428 ic->preedit_changed = 1;
1433 preedit_delete (MInputContext *ic, int from, int to)
1435 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1438 mtext_del (ic->preedit, from, to);
1439 MPLIST_DO (markers, ic_info->markers)
1441 if (MPLIST_INTEGER (markers) > to)
1442 MPLIST_VAL (markers)
1443 = (void *) (MPLIST_INTEGER (markers) - (to - from));
1444 else if (MPLIST_INTEGER (markers) > from);
1445 MPLIST_VAL (markers) = (void *) from;
1447 if (ic->cursor_pos >= to)
1448 ic->cursor_pos -= to - from;
1449 else if (ic->cursor_pos > from)
1450 ic->cursor_pos = from;
1451 ic->preedit_changed = 1;
1455 preedit_commit (MInputContext *ic)
1457 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1458 int preedit_len = mtext_nchars (ic->preedit);
1460 if (preedit_len > 0)
1464 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1465 Mcandidate_list, NULL, 0);
1466 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1467 Mcandidate_index, NULL, 0);
1468 mtext_cat (ic->produced, ic->preedit);
1469 if ((mdebug__flag & mdebug_mask)
1470 && mtext_nchars (ic->produced) > 0)
1474 MDEBUG_PRINT (" (produced");
1475 for (i = 0; i < mtext_nchars (ic->produced); i++)
1476 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
1479 mtext_reset (ic->preedit);
1480 mtext_reset (ic_info->preedit_saved);
1481 MPLIST_DO (p, ic_info->markers)
1483 ic->cursor_pos = ic_info->state_pos = 0;
1484 ic->preedit_changed = 1;
1486 if (ic->candidate_list)
1488 M17N_OBJECT_UNREF (ic->candidate_list);
1489 ic->candidate_list = NULL;
1490 ic->candidate_show = 0;
1491 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
1492 if (ic->candidate_show)
1494 ic->candidate_show = 0;
1495 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
1499 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
1500 sizeof (int) * (ic_info->used - ic_info->key_head));
1501 ic_info->used -= ic_info->key_head;
1502 ic_info->state_key_head = ic_info->key_head = 0;
1506 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
1508 int code = marker_code (sym);
1510 if (mt && (code == '[' || code == ']'))
1514 if (code == '[' && current > 0)
1516 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
1520 else if (code == ']' && current < mtext_nchars (mt))
1522 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
1528 return (code == '<' ? 0
1529 : code == '>' ? limit
1530 : code == '-' ? current - 1
1531 : code == '+' ? current + 1
1532 : code == '=' ? current
1533 : code - '0' > limit ? limit
1537 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1541 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1543 int from = mtext_property_start (prop);
1544 int to = mtext_property_end (prop);
1546 MPlist *candidate_list = mtext_property_value (prop);
1547 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1549 int ingroup_index = idx - start;
1552 preedit_delete (ic, from, to);
1553 if (MPLIST_MTEXT_P (group))
1555 mt = MPLIST_MTEXT (group);
1556 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1564 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1565 i++, plist = MPLIST_NEXT (plist));
1566 mt = MPLIST_MTEXT (plist);
1567 preedit_insert (ic, from, mt, 0);
1568 to = from + mtext_nchars (mt);
1570 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1571 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1572 ic->cursor_pos = to;
1576 get_select_charset (MInputContextInfo * ic_info)
1578 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
1581 if (! MPLIST_VAL (plist))
1583 sym = MPLIST_SYMBOL (plist);
1586 return MCHARSET (sym);
1590 adjust_candidates (MPlist *plist, MCharset *charset)
1594 /* plist ::= MTEXT ... | PLIST ... */
1595 plist = mplist_copy (plist);
1596 if (MPLIST_MTEXT_P (plist))
1599 while (! MPLIST_TAIL_P (pl))
1601 /* pl ::= MTEXT ... */
1602 MText *mt = MPLIST_MTEXT (pl);
1606 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1608 c = mtext_ref_char (mt, i);
1609 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1613 mt = mtext_dup (mt);
1614 mplist_set (pl, Mtext, mt);
1615 M17N_OBJECT_UNREF (mt);
1618 mtext_del (mt, i, i + 1);
1621 if (mtext_len (mt) > 0)
1622 pl = MPLIST_NEXT (pl);
1626 M17N_OBJECT_UNREF (mt);
1630 else /* MPLIST_PLIST_P (plist) */
1633 while (! MPLIST_TAIL_P (pl))
1635 /* pl ::= (MTEXT ...) ... */
1636 MPlist *p = MPLIST_PLIST (pl);
1638 /* p ::= MTEXT ... */
1642 while (! MPLIST_TAIL_P (p0))
1644 MText *mt = MPLIST_MTEXT (p0);
1647 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1649 c = mtext_ref_char (mt, i);
1650 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1655 p0 = MPLIST_NEXT (p0);
1662 p = mplist_copy (p);
1663 mplist_set (pl, Mplist, p);
1664 M17N_OBJECT_UNREF (p);
1668 p0 = MPLIST_NEXT (p0);
1671 M17N_OBJECT_UNREF (mt);
1674 if (! MPLIST_TAIL_P (p))
1675 pl = MPLIST_NEXT (pl);
1679 M17N_OBJECT_UNREF (p);
1683 if (MPLIST_TAIL_P (plist))
1685 M17N_OBJECT_UNREF (plist);
1692 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
1694 MCharset *charset = get_select_charset (ic_info);
1699 plist = resolve_variable (ic_info, Mcandidates_group_size);
1700 column = MPLIST_INTEGER (plist);
1702 plist = MPLIST_PLIST (args);
1705 if (! (plist = adjust_candidates (plist, charset)))
1709 M17N_OBJECT_REF (plist);
1713 if (MPLIST_MTEXT_P (plist))
1715 MText *mt = MPLIST_MTEXT (plist);
1716 MPlist *next = MPLIST_NEXT (plist);
1718 if (MPLIST_TAIL_P (next))
1719 M17N_OBJECT_REF (mt);
1722 mt = mtext_dup (mt);
1723 while (! MPLIST_TAIL_P (next))
1725 mt = mtext_cat (mt, MPLIST_MTEXT (next));
1726 next = MPLIST_NEXT (next);
1729 M17N_OBJECT_UNREF (plist);
1731 len = mtext_nchars (mt);
1733 mplist_add (plist, Mtext, mt);
1736 for (i = 0; i < len; i += column)
1738 int to = (i + column < len ? i + column : len);
1739 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
1741 mplist_add (plist, Mtext, sub);
1742 M17N_OBJECT_UNREF (sub);
1745 M17N_OBJECT_UNREF (mt);
1747 else /* MPLIST_PLIST_P (plist) */
1749 MPlist *pl = MPLIST_PLIST (plist), *p;
1750 MPlist *next = MPLIST_NEXT (plist);
1753 if (MPLIST_TAIL_P (next))
1754 M17N_OBJECT_REF (pl);
1757 pl = mplist_copy (pl);
1758 while (! MPLIST_TAIL_P (next))
1760 p = mplist_copy (MPLIST_PLIST (next));
1761 pl = mplist__conc (pl, p);
1762 M17N_OBJECT_UNREF (p);
1763 next = MPLIST_NEXT (next);
1766 M17N_OBJECT_UNREF (plist);
1768 len = mplist_length (pl);
1770 mplist_add (plist, Mplist, pl);
1775 for (i = 0; i < len; i += column)
1778 mplist_add (plist, Mplist, p);
1779 M17N_OBJECT_UNREF (p);
1780 for (j = 0; j < column && i + j < len; j++)
1782 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
1783 p0 = MPLIST_NEXT (p0);
1787 M17N_OBJECT_UNREF (pl);
1796 regularize_action (MPlist *action_list)
1798 MPlist *action = NULL;
1802 if (MPLIST_PLIST_P (action_list))
1804 action = MPLIST_PLIST (action_list);
1805 if (MPLIST_SYMBOL_P (action))
1807 name = MPLIST_SYMBOL (action);
1808 args = MPLIST_NEXT (action);
1810 && MPLIST_PLIST_P (args))
1811 mplist_set (action, Msymbol, M_candidates);
1813 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
1816 mplist_push (action, Mplist, MPLIST_VAL (action_list));
1817 mplist_push (action, Msymbol, M_candidates);
1818 mplist_set (action_list, Mplist, action);
1819 M17N_OBJECT_UNREF (action);
1822 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
1825 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
1826 mplist_push (action, Msymbol, Minsert);
1827 mplist_set (action_list, Mplist, action);
1828 M17N_OBJECT_UNREF (action);
1834 take_action_list (MInputContext *ic, MPlist *action_list)
1836 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1837 MPlist *candidate_list = ic->candidate_list;
1838 int candidate_index = ic->candidate_index;
1839 int candidate_show = ic->candidate_show;
1840 MTextProperty *prop;
1842 MPLIST_DO (action_list, action_list)
1844 MPlist *action = regularize_action (action_list);
1850 name = MPLIST_SYMBOL (action);
1851 args = MPLIST_NEXT (action);
1853 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1854 if (name == Minsert)
1856 if (MPLIST_SYMBOL_P (args))
1858 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
1859 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
1862 if (MPLIST_MTEXT_P (args))
1863 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1864 else /* MPLIST_INTEGER_P (args)) */
1865 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1867 else if (name == M_candidates)
1869 MPlist *plist = get_candidate_list (ic_info, args);
1874 if (MPLIST_MTEXT_P (plist))
1876 preedit_insert (ic, ic->cursor_pos, NULL,
1877 mtext_ref_char (MPLIST_MTEXT (plist), 0));
1882 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
1884 preedit_insert (ic, ic->cursor_pos, mt, 0);
1885 len = mtext_nchars (mt);
1887 mtext_put_prop (ic->preedit,
1888 ic->cursor_pos - len, ic->cursor_pos,
1889 Mcandidate_list, plist);
1890 mtext_put_prop (ic->preedit,
1891 ic->cursor_pos - len, ic->cursor_pos,
1892 Mcandidate_index, (void *) 0);
1893 M17N_OBJECT_UNREF (plist);
1895 else if (name == Mselect)
1898 int code, idx, gindex;
1899 int pos = ic->cursor_pos;
1903 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1906 if (MPLIST_SYMBOL_P (args))
1908 code = marker_code (MPLIST_SYMBOL (args));
1914 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1915 group = find_candidates_group (mtext_property_value (prop), idx,
1916 &start, &end, &gindex);
1918 if (code != '[' && code != ']')
1922 ? new_index (NULL, ic->candidate_index - start,
1923 end - start - 1, MPLIST_SYMBOL (args),
1925 : MPLIST_INTEGER (args)));
1928 find_candidates_group (mtext_property_value (prop), -1,
1933 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1938 int ingroup_index = idx - start;
1941 group = mtext_property_value (prop);
1942 len = mplist_length (group);
1955 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1956 idx += (MPLIST_MTEXT_P (group)
1957 ? mtext_nchars (MPLIST_MTEXT (group))
1958 : mplist_length (MPLIST_PLIST (group)));
1959 len = (MPLIST_MTEXT_P (group)
1960 ? mtext_nchars (MPLIST_MTEXT (group))
1961 : mplist_length (MPLIST_PLIST (group)));
1962 if (ingroup_index >= len)
1963 ingroup_index = len - 1;
1964 idx += ingroup_index;
1966 update_candidate (ic, prop, idx);
1968 else if (name == Mshow)
1969 ic->candidate_show = 1;
1970 else if (name == Mhide)
1971 ic->candidate_show = 0;
1972 else if (name == Mdelete)
1974 int len = mtext_nchars (ic->preedit);
1978 if (MPLIST_SYMBOL_P (args)
1979 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
1981 delete_surrounding_text (ic, pos);
1985 to = (MPLIST_SYMBOL_P (args)
1986 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1988 : MPLIST_INTEGER (args));
1993 if (to < ic->cursor_pos)
1994 preedit_delete (ic, to, ic->cursor_pos);
1995 else if (to > ic->cursor_pos)
1996 preedit_delete (ic, ic->cursor_pos, to);
1999 else if (name == Mmove)
2001 int len = mtext_nchars (ic->preedit);
2003 = (MPLIST_SYMBOL_P (args)
2004 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2006 : MPLIST_INTEGER (args));
2012 if (pos != ic->cursor_pos)
2014 ic->cursor_pos = pos;
2015 ic->preedit_changed = 1;
2018 else if (name == Mmark)
2020 int code = marker_code (MPLIST_SYMBOL (args));
2023 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
2024 (void *) ic->cursor_pos);
2026 else if (name == Mpushback)
2028 if (MPLIST_INTEGER_P (args))
2030 int num = MPLIST_INTEGER (args);
2033 ic_info->key_head -= num;
2035 ic_info->key_head = num;
2036 if (ic_info->key_head > ic_info->used)
2037 ic_info->key_head = ic_info->used;
2039 else if (MPLIST_MTEXT_P (args))
2041 MText *mt = MPLIST_MTEXT (args);
2042 int i, len = mtext_nchars (mt);
2045 ic_info->key_head--;
2046 for (i = 0; i < len; i++)
2048 key = one_char_symbol[MTEXT_DATA (mt)[i]];
2049 if (ic_info->key_head + i < ic_info->used)
2050 ic_info->keys[ic_info->key_head + i] = key;
2052 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2057 MPlist *plist = MPLIST_PLIST (args), *pl;
2061 ic_info->key_head--;
2063 MPLIST_DO (pl, plist)
2065 key = MPLIST_SYMBOL (pl);
2066 if (ic_info->key_head < ic_info->used)
2067 ic_info->keys[ic_info->key_head + i] = key;
2069 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2074 else if (name == Mcall)
2076 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2077 MIMExternalFunc func = NULL;
2078 MSymbol module, func_name;
2079 MPlist *func_args, *val;
2082 module = MPLIST_SYMBOL (args);
2083 args = MPLIST_NEXT (args);
2084 func_name = MPLIST_SYMBOL (args);
2086 if (im_info->externals)
2088 MIMExternalModule *external
2089 = (MIMExternalModule *) mplist_get (im_info->externals,
2092 func = (MIMExternalFunc) mplist_get (external->func_list,
2097 func_args = mplist ();
2098 mplist_add (func_args, Mt, ic);
2099 MPLIST_DO (args, MPLIST_NEXT (args))
2103 if (MPLIST_KEY (args) == Msymbol
2104 && MPLIST_KEY (args) != Mnil
2105 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
2107 code = new_index (ic, ic->cursor_pos,
2108 mtext_nchars (ic->preedit),
2109 MPLIST_SYMBOL (args), ic->preedit);
2110 mplist_add (func_args, Minteger, (void *) code);
2113 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
2115 val = (func) (func_args);
2116 M17N_OBJECT_UNREF (func_args);
2117 if (val && ! MPLIST_TAIL_P (val))
2118 ret = take_action_list (ic, val);
2119 M17N_OBJECT_UNREF (val);
2123 else if (name == Mshift)
2125 shift_state (ic, MPLIST_SYMBOL (args));
2127 else if (name == Mundo)
2129 int intarg = (MPLIST_TAIL_P (args)
2131 : integer_value (ic, args, NULL, 0));
2133 mtext_reset (ic->preedit);
2134 mtext_reset (ic_info->preedit_saved);
2135 ic->cursor_pos = ic_info->state_pos = 0;
2136 ic_info->state_key_head = ic_info->key_head = 0;
2139 ic_info->used += intarg;
2141 ic_info->used = intarg;
2142 shift_state (ic, Mnil);
2145 else if (name == Mset || name == Madd || name == Msub
2146 || name == Mmul || name == Mdiv)
2148 MSymbol sym = MPLIST_SYMBOL (args);
2153 val1 = integer_value (ic, args, &value, 0);
2154 args = MPLIST_NEXT (args);
2155 val2 = integer_value (ic, args, NULL, 1);
2157 val1 = val2, op = "=";
2158 else if (name == Madd)
2159 val1 += val2, op = "+=";
2160 else if (name == Msub)
2161 val1 -= val2, op = "-=";
2162 else if (name == Mmul)
2163 val1 *= val2, op = "*=";
2165 val1 /= val2, op = "/=";
2166 MDEBUG_PRINT3 ("(%s %s %d)", MSYMBOL_NAME (sym), op, val1);
2168 mplist_set (value, Minteger, (void *) val1);
2170 else if (name == Mequal || name == Mless || name == Mgreater)
2173 MPlist *actions1, *actions2;
2176 val1 = integer_value (ic, args, NULL, 1);
2177 args = MPLIST_NEXT (args);
2178 val2 = integer_value (ic, args, NULL, 1);
2179 args = MPLIST_NEXT (args);
2180 actions1 = MPLIST_PLIST (args);
2181 args = MPLIST_NEXT (args);
2182 if (MPLIST_TAIL_P (args))
2185 actions2 = MPLIST_PLIST (args);
2186 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
2187 if (name == Mequal ? val1 == val2
2188 : name == Mless ? val1 < val2
2191 MDEBUG_PRINT ("ok");
2192 ret = take_action_list (ic, actions1);
2196 MDEBUG_PRINT ("no");
2198 ret = take_action_list (ic, actions2);
2203 else if (name == Mcommit)
2205 preedit_commit (ic);
2207 else if (name == Munhandle)
2209 preedit_commit (ic);
2214 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2218 && (actions = mplist_get (im_info->macros, name)))
2220 if (take_action_list (ic, actions) < 0)
2227 if (ic->candidate_list)
2229 M17N_OBJECT_UNREF (ic->candidate_list);
2230 ic->candidate_list = NULL;
2232 if (ic->cursor_pos > 0
2233 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
2236 ic->candidate_list = mtext_property_value (prop);
2237 M17N_OBJECT_REF (ic->candidate_list);
2239 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
2241 ic->candidate_from = mtext_property_start (prop);
2242 ic->candidate_to = mtext_property_end (prop);
2245 if (candidate_list != ic->candidate_list)
2246 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
2247 if (candidate_index != ic->candidate_index)
2248 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
2249 if (candidate_show != ic->candidate_show)
2250 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2255 /* Handle the input key KEY in the current state and map specified in
2256 the input context IC. If KEY is handled correctly, return 0.
2257 Otherwise, return -1. */
2260 handle_key (MInputContext *ic)
2262 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2263 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2264 MIMMap *map = ic_info->map;
2265 MIMMap *submap = NULL;
2266 MSymbol key = ic_info->keys[ic_info->key_head];
2269 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
2270 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
2276 submap = mplist_get (map->submaps, key);
2277 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
2278 submap = mplist_get (map->submaps, alias);
2283 MDEBUG_PRINT (" submap-found");
2284 mtext_cpy (ic->preedit, ic_info->preedit_saved);
2285 ic->preedit_changed = 1;
2286 ic->cursor_pos = ic_info->state_pos;
2287 ic_info->key_head++;
2288 ic_info->map = map = submap;
2289 if (map->map_actions)
2291 MDEBUG_PRINT (" map-actions:");
2292 if (take_action_list (ic, map->map_actions) < 0)
2294 MDEBUG_PRINT ("\n");
2298 else if (map->submaps)
2300 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
2302 MSymbol key = ic_info->keys[i];
2303 char *name = msymbol_name (key);
2305 if (! name[0] || ! name[1])
2306 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
2310 /* If this is the terminal map or we have shifted to another
2311 state, perform branch actions (if any). */
2312 if (! map->submaps || map != ic_info->map)
2314 if (map->branch_actions)
2316 MDEBUG_PRINT (" branch-actions:");
2317 if (take_action_list (ic, map->branch_actions) < 0)
2319 MDEBUG_PRINT ("\n");
2323 /* If MAP is still not the root map, shift to the current
2325 if (ic_info->map != ic_info->state->map)
2326 shift_state (ic, ic_info->state->name);
2331 /* MAP can not handle KEY. */
2333 /* If MAP is the root map of the initial state, it means that
2334 the current input method can not handle KEY. */
2335 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
2337 MDEBUG_PRINT (" unhandled\n");
2341 if (map != ic_info->state->map)
2343 /* If MAP is not the root map... */
2344 /* If MAP has branch actions, perform them. */
2345 if (map->branch_actions)
2347 MDEBUG_PRINT (" branch-actions:");
2348 if (take_action_list (ic, map->branch_actions) < 0)
2350 MDEBUG_PRINT ("\n");
2354 /* If MAP is still not the root map, shift to the current
2356 if (ic_info->map != ic_info->state->map)
2358 shift_state (ic, ic_info->state->name);
2359 /* If MAP has branch_actions, perform them. */
2360 if (ic_info->map->branch_actions)
2362 MDEBUG_PRINT (" brank-actions:");
2363 take_action_list (ic, ic_info->map->branch_actions);
2369 /* MAP is the root map, perform branch actions (if any) or
2370 shift to the initial state. */
2371 if (map->branch_actions)
2373 MDEBUG_PRINT (" branch-actions:");
2374 if (take_action_list (ic, map->branch_actions) < 0)
2376 MDEBUG_PRINT ("\n");
2381 shift_state (ic, Mnil);
2384 MDEBUG_PRINT ("\n");
2389 reset_ic (MInputContext *ic, MSymbol ignore)
2391 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2392 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2395 MDEBUG_PRINT ("\n [IM] reset\n");
2397 ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
2398 ic_info->prev_state = NULL;
2399 ic_info->map = ic_info->state->map;
2400 ic_info->state_key_head = ic_info->key_head;
2401 MLIST_RESET (ic_info);
2402 ic_info->key_unhandled = 0;
2404 if (mtext_nchars (ic->produced) > 0)
2405 mtext_reset (ic->produced);
2406 if (mtext_nchars (ic->preedit) > 0)
2410 mtext_reset (ic->preedit);
2411 MPLIST_DO (plist, ic_info->markers)
2412 MPLIST_VAL (plist) = 0;
2413 ic->preedit_changed = 1;
2415 if (ic->candidate_show)
2417 ic->candidate_show = 0;
2418 ic->candidates_changed = MINPUT_CANDIDATES_SHOW_CHANGED;
2419 if (ic->candidate_list)
2421 M17N_OBJECT_UNREF (ic->candidate_list);
2422 ic->candidate_list = NULL;
2423 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
2426 mtext_reset (ic_info->preedit_saved);
2427 ic_info->state_pos = ic->cursor_pos = 0;
2429 status = ic_info->state->title ? ic_info->state->title : im_info->title;
2430 if (ic->status != status)
2432 ic->status = status;
2433 ic->status_changed = 1;
2438 open_im (MInputMethod *im)
2440 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil);
2443 MERROR (MERROR_IM, -1);
2450 close_im (MInputMethod *im)
2456 create_ic (MInputContext *ic)
2458 MInputMethod *im = ic->im;
2459 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
2460 MInputContextInfo *ic_info;
2464 ic_info = (MInputContextInfo *) ic->info;
2467 MSTRUCT_CALLOC (ic_info, MERROR_IM);
2470 MLIST_INIT1 (ic_info, keys, 8);
2471 ic_info->markers = mplist ();
2472 ic_info->vars = mplist ();
2473 plist = get_nested_list (im->language, im->name, Mnil, M_variable);
2474 MPLIST_DO (plist, plist)
2476 MSymbol var = MPLIST_SYMBOL (plist);
2479 plist = MPLIST_NEXT (plist);
2480 pl = MPLIST_PLIST (plist);
2481 pl = MPLIST_NEXT (pl); /* Skip description. */
2482 mplist_push (ic_info->vars, MPLIST_KEY (pl), MPLIST_VAL (pl));
2483 mplist_push (ic_info->vars, Msymbol, var);
2486 ic_info->preedit_saved = mtext ();
2487 if (im_info->externals)
2489 MPlist *func_args = mplist (), *plist;
2491 mplist_add (func_args, Mt, ic);
2492 MPLIST_DO (plist, im_info->externals)
2494 MIMExternalModule *external = MPLIST_VAL (plist);
2495 MIMExternalFunc func
2496 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
2501 M17N_OBJECT_UNREF (func_args);
2503 reset_ic (ic, Mnil);
2508 destroy_ic (MInputContext *ic)
2510 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2511 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2513 if (im_info->externals)
2515 MPlist *func_args = mplist (), *plist;
2517 mplist_add (func_args, Mt, ic);
2518 MPLIST_DO (plist, im_info->externals)
2520 MIMExternalModule *external = MPLIST_VAL (plist);
2521 MIMExternalFunc func
2522 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
2527 M17N_OBJECT_UNREF (func_args);
2529 MLIST_FREE1 (ic_info, keys);
2530 M17N_OBJECT_UNREF (ic_info->preedit_saved);
2531 M17N_OBJECT_UNREF (ic_info->markers);
2532 M17N_OBJECT_UNREF (ic_info->vars);
2533 M17N_OBJECT_UNREF (ic_info->preceding_text);
2534 M17N_OBJECT_UNREF (ic_info->following_text);
2539 /** Handle the input key KEY in the current state and map of IC->info.
2540 If KEY is handled but no text is produced, return 0, otherwise
2546 filter (MInputContext *ic, MSymbol key, void *arg)
2548 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2549 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2552 if (! ic_info->state)
2554 ic_info->key_unhandled = 1;
2557 mtext_reset (ic->produced);
2558 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
2559 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2560 ic_info->key_unhandled = 0;
2562 if (handle_key (ic) < 0)
2564 /* KEY was not handled. Delete it from the current key sequence. */
2565 if (ic_info->used > 0)
2567 memmove (ic_info->keys, ic_info->keys + 1,
2568 sizeof (int) * (ic_info->used - 1));
2571 /* This forces returning 1. */
2572 ic_info->key_unhandled = 1;
2578 reset_ic (ic, Mnil);
2579 ic_info->key_unhandled = 1;
2582 /* Break the loop if all keys were handled. */
2583 } while (ic_info->key_head < ic_info->used);
2585 /* If the current map is the root of the initial state, we should
2586 produce any preedit text in ic->produced. */
2587 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2588 && mtext_nchars (ic->preedit) > 0)
2589 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2591 if (mtext_nchars (ic->produced) > 0)
2593 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2596 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2597 Mlanguage, ic->im->language);
2600 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2604 /** Return 1 if the last event or key was not handled, otherwise
2607 There is no need of looking up because ic->produced should already
2608 contain the produced text (if any).
2613 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2615 mtext_cat (mt, ic->produced);
2616 mtext_reset (ic->produced);
2617 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2620 static MPlist *load_im_info_keys;
2623 load_partial_im_info (MSymbol language, MSymbol name,
2624 MSymbol extra, MSymbol key)
2629 if (language == Mnil)
2630 MERROR (MERROR_IM, NULL);
2631 mdb = mdatabase_find (Minput_method, language, name, extra);
2633 MERROR (MERROR_IM, NULL);
2635 mplist_push (load_im_info_keys, key, Mt);
2636 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2637 mplist_pop (load_im_info_keys);
2642 static MInputMethodInfo *
2643 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2647 MInputMethodInfo *im_info = NULL;
2649 if (language == Mnil)
2650 MERROR (MERROR_IM, NULL);
2651 mdb = mdatabase_find (Minput_method, language, name, extra);
2653 MERROR (MERROR_IM, NULL);
2656 im_info_list = mplist ();
2657 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2659 if (mdatabase__check (mdb))
2661 plist = MPLIST_NEXT (plist);
2662 im_info = MPLIST_VAL (plist);
2666 free_im_info (MPLIST_VAL (plist));
2670 plist = mdatabase_load (mdb);
2672 MERROR (MERROR_IM, NULL);
2673 im_info = load_im_info (language, name, plist);
2674 M17N_OBJECT_UNREF (plist);
2676 MERROR (MERROR_IM, NULL);
2677 mplist_push (im_info_list, Mt, im_info);
2678 mplist_push (im_info_list, Mt, mdb);
2683 /* Input method command handler. */
2685 /* List of all (global and local) commands.
2686 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2687 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2688 Global commands are storead as (t (t COMMAND ...)) */
2690 /* Check if PLIST is a valid command key sequence.
2691 PLIST must be NULL or:
2692 [ symbol:KEY | integer:KEY ] ... */
2695 check_command_keyseq (MPlist *plist)
2699 MPLIST_DO (plist, plist)
2701 if (MPLIST_SYMBOL_P (plist))
2703 else if (MPLIST_INTEGER_P (plist))
2705 int n = MPLIST_INTEGER (plist);
2709 MPLIST_KEY (plist) = Msymbol;
2710 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2718 /* Check if PLIST has this form:
2719 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2721 If the form of PLIST matches, return 0, otherwise return -1. */
2724 check_command_list (MPlist *plist)
2726 MPLIST_DO (plist, plist)
2728 if (MPLIST_PLIST_P (plist))
2730 MPlist *pl = MPLIST_PLIST (plist);
2733 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2736 else if (! MPLIST_MTEXT_P (plist))
2744 /* Input method variable handler. */
2746 /* Check if PLIST has this form:
2747 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2750 If the form of PLIST matches, return 0, otherwise return -1. */
2753 check_variable_list (MPlist *plist)
2755 MSymbol type = MPLIST_KEY (plist);
2758 if (type != Minteger && type != Mtext && type != Msymbol)
2760 MPLIST_DO (plist, MPLIST_NEXT (plist))
2762 if (type == Minteger && MPLIST_PLIST_P (plist))
2764 MPLIST_DO (p, MPLIST_PLIST (plist))
2765 if (! MPLIST_INTEGER_P (p))
2768 else if (type != MPLIST_KEY (plist))
2774 /* Support functions for mdebug_dump_im. */
2777 dump_im_map (MPlist *map_list, int indent)
2780 MSymbol key = MPLIST_KEY (map_list);
2781 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2783 prefix = (char *) alloca (indent + 1);
2784 memset (prefix, 32, indent);
2785 prefix[indent] = '\0';
2787 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2788 if (map->map_actions)
2789 mdebug_dump_plist (map->map_actions, indent + 2);
2792 MPLIST_DO (map_list, map->submaps)
2794 fprintf (stderr, "\n%s ", prefix);
2795 dump_im_map (map_list, indent + 2);
2798 if (map->branch_actions)
2800 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2801 mdebug_dump_plist (map->branch_actions, indent + 4);
2802 fprintf (stderr, ")");
2804 fprintf (stderr, ")");
2809 dump_im_state (MIMState *state, int indent)
2814 prefix = (char *) alloca (indent + 1);
2815 memset (prefix, 32, indent);
2816 prefix[indent] = '\0';
2818 fprintf (stderr, "(%s", msymbol_name (state->name));
2819 if (state->map->submaps)
2821 MPLIST_DO (map_list, state->map->submaps)
2823 fprintf (stderr, "\n%s ", prefix);
2824 dump_im_map (map_list, indent + 2);
2827 fprintf (stderr, ")");
2836 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2837 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2838 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2839 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2840 char buf[6], buf2[256];
2844 Minput_method = msymbol ("input-method");
2845 Minput_driver = msymbol ("input-driver");
2846 Mtitle = msymbol ("title");
2847 Mmacro = msymbol ("macro");
2848 Mmodule = msymbol ("module");
2849 Mmap = msymbol ("map");
2850 Mstate = msymbol ("state");
2851 Minclude = msymbol ("include");
2852 Minsert = msymbol ("insert");
2853 M_candidates = msymbol (" candidates");
2854 Mdelete = msymbol ("delete");
2855 Mmove = msymbol ("move");
2856 Mmark = msymbol ("mark");
2857 Mpushback = msymbol ("pushback");
2858 Mundo = msymbol ("undo");
2859 Mcall = msymbol ("call");
2860 Mshift = msymbol ("shift");
2861 Mselect = msymbol ("select");
2862 Mshow = msymbol ("show");
2863 Mhide = msymbol ("hide");
2864 Mcommit = msymbol ("commit");
2865 Munhandle = msymbol ("unhandle");
2866 Mset = msymbol ("set");
2867 Madd = msymbol ("add");
2868 Msub = msymbol ("sub");
2869 Mmul = msymbol ("mul");
2870 Mdiv = msymbol ("div");
2871 Mequal = msymbol ("=");
2872 Mless = msymbol ("<");
2873 Mgreater = msymbol (">");
2875 Mcandidates_group_size = msymbol ("candidates-group-size");
2876 Mcandidates_charset = msymbol ("candidates-charset");
2878 Minput_preedit_start = msymbol ("input-preedit-start");
2879 Minput_preedit_done = msymbol ("input-preedit-done");
2880 Minput_preedit_draw = msymbol ("input-preedit-draw");
2881 Minput_status_start = msymbol ("input-status-start");
2882 Minput_status_done = msymbol ("input-status-done");
2883 Minput_status_draw = msymbol ("input-status-draw");
2884 Minput_candidates_start = msymbol ("input-candidates-start");
2885 Minput_candidates_done = msymbol ("input-candidates-done");
2886 Minput_candidates_draw = msymbol ("input-candidates-draw");
2887 Minput_set_spot = msymbol ("input-set-spot");
2888 Minput_focus_move = msymbol ("input-focus-move");
2889 Minput_focus_in = msymbol ("input-focus-in");
2890 Minput_focus_out = msymbol ("input-focus-out");
2891 Minput_toggle = msymbol ("input-toggle");
2892 Minput_reset = msymbol ("input-reset");
2893 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
2894 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
2896 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2897 Mcandidate_index = msymbol (" candidate-index");
2899 Minit = msymbol ("init");
2900 Mfini = msymbol ("fini");
2902 M_key_alias = msymbol (" key-alias");
2903 M_description = msymbol ("description");
2904 M_command = msymbol ("command");
2905 M_variable = msymbol ("variable");
2907 load_im_info_keys = mplist ();
2908 plist = mplist_add (load_im_info_keys, Mstate, Mnil);
2913 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2917 one_char_symbol[i] = msymbol (buf);
2920 alias = msymbol (key_names[i]);
2921 msymbol_put (one_char_symbol[i], M_key_alias, alias);
2924 alias = one_char_symbol[i];
2925 buf[2] += (i == 0) ? -32 : 32;
2926 msymbol_put (alias, M_key_alias, msymbol (buf));
2927 buf[2] -= (i == 0) ? -32 : 32;
2929 for (buf[2] = i; i < 127; i++, buf[2]++)
2930 one_char_symbol[i] = msymbol (buf + 2);
2931 one_char_symbol[i++] = msymbol ("Delete");
2937 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2939 one_char_symbol[i] = msymbol (buf);
2940 if (key_names[i - 128])
2942 strcpy (buf2 + 2, key_names[i - 128]);
2943 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2946 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2947 one_char_symbol[i] = msymbol (buf + 2);
2948 one_char_symbol[i] = msymbol ("M-Delete");
2950 command_list = variable_list = NULL;
2952 minput_default_driver.open_im = open_im;
2953 minput_default_driver.close_im = close_im;
2954 minput_default_driver.create_ic = create_ic;
2955 minput_default_driver.destroy_ic = destroy_ic;
2956 minput_default_driver.filter = filter;
2957 minput_default_driver.lookup = lookup;
2958 minput_default_driver.callback_list = mplist ();
2959 mplist_put (minput_default_driver.callback_list, Minput_reset,
2961 minput_driver = &minput_default_driver;
2970 M17N_OBJECT_UNREF (command_list);
2971 command_list = NULL;
2975 M17N_OBJECT_UNREF (variable_list);
2976 variable_list = NULL;
2979 if (minput_default_driver.callback_list)
2981 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2982 minput_default_driver.callback_list = NULL;
2984 if (minput_driver->callback_list)
2986 M17N_OBJECT_UNREF (minput_driver->callback_list);
2987 minput_driver->callback_list = NULL;
2992 while (! MPLIST_TAIL_P (im_info_list))
2995 mplist_pop (im_info_list);
2996 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
2997 /* Pop (t . im_info) */
2998 mplist_pop (im_info_list);
3000 M17N_OBJECT_UNREF (im_info_list);
3001 im_info_list = NULL;
3004 M17N_OBJECT_UNREF (load_im_info_keys);
3008 minput__callback (MInputContext *ic, MSymbol command)
3010 if (ic->im->driver.callback_list)
3012 MInputCallbackFunc func
3013 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3017 (func) (ic, command);
3022 minput__char_to_key (int c)
3024 if (c < 0 || c >= 0x100)
3027 return one_char_symbol[c];
3031 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3036 /*** @addtogroup m17nInputMethod */
3041 @name Variables: Predefined symbols for callback commands.
3043 These are the predefined symbols that are used as the @c COMMAND
3044 argument of callback functions of an input method driver (see
3045 #MInputDriver::callback_list ).
3047 Most of them don't require extra argument nor return any value;
3048 exceptions are these:
3050 Minput_get_surrounding_text: When a callback function assigned for
3051 this command is called, the first element of #MInputContext::plist
3052 has key #Msymbol and the value specifies which portion of the
3053 surrounding text should be retrieved. If the value is positive,
3054 it specifies the number of characters following the current cursor
3055 position. If the value is negative, the absolute value specifies
3056 the number of characters preceding the current cursor position.
3057 The callback function must set the key of this element to #Mtext
3058 and the value to the retrived M-text (whose length may be shorter
3059 than the requested number of characters if the available text is
3060 not that long, or it may be longer if an application thinks it's
3061 more efficient to return that length).
3063 Minput_delete_surrounding_text: When a callback function assigned
3064 for this command is called, the first element of
3065 #MInputContext::plist has key #Msymbol and the value specifies
3066 which portion of the surrounding text should be deleted in the
3067 same way as the case of Minput_get_surrounding_text. The callback
3068 function must delete the specified text. It should not alter
3069 #MInputContext::plist. */
3072 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3074 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3075 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3080 MSymbol Minput_preedit_start;
3081 MSymbol Minput_preedit_done;
3082 MSymbol Minput_preedit_draw;
3083 MSymbol Minput_status_start;
3084 MSymbol Minput_status_done;
3085 MSymbol Minput_status_draw;
3086 MSymbol Minput_candidates_start;
3087 MSymbol Minput_candidates_done;
3088 MSymbol Minput_candidates_draw;
3089 MSymbol Minput_set_spot;
3090 MSymbol Minput_toggle;
3091 MSymbol Minput_reset;
3092 MSymbol Minput_get_surrounding_text;
3093 MSymbol Minput_delete_surrounding_text;
3099 @name Variables: Predefined symbols for special input events.
3101 These are the predefined symbols that are used as the @c KEY
3102 argument of minput_filter (). */
3107 MSymbol Minput_focus_out;
3108 MSymbol Minput_focus_in;
3109 MSymbol Minput_focus_move;
3116 @brief The default driver for internal input methods.
3118 The variable #minput_default_driver is the default driver for
3119 internal input methods.
3121 The member MInputDriver::open_im () searches the m17n database for
3122 an input method that matches the tag \< #Minput_method, $LANGUAGE,
3123 $NAME\> and loads it.
3125 The member MInputDriver::callback_list () is @c NULL. Thus, it is
3126 programmers responsibility to set it to a plist of proper callback
3127 functions. Otherwise, no feedback information (e.g. preedit text)
3128 can be shown to users.
3130 The macro M17N_INIT () sets the variable #minput_driver to the
3131 pointer to this driver so that all internal input methods use it.
3133 Therefore, unless @c minput_driver is set differently, the driver
3134 dependent arguments $ARG of the functions whose name begin with
3135 "minput_" are all ignored. */
3138 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
3140 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
3142 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
3143 \< #Minput_method, $LANGUAGE, $NAME\>
3144 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
3146 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
3147 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
3148 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
3149 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
3151 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
3152 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
3154 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
3155 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
3157 MInputDriver minput_default_driver;
3161 @brief The driver for internal input methods.
3163 The variable #minput_driver is a pointer to the input method
3164 driver that is used by internal input methods. The macro
3165 M17N_INIT () initializes it to a pointer to #minput_default_driver
3166 if <m17n<EM></EM>.h> is included. */
3168 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
3170 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
3171 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
3172 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
3173 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
3175 MInputDriver *minput_driver;
3177 MSymbol Minput_driver;
3182 @brief Open an input method.
3184 The minput_open_im () function opens an input method that matches
3185 language $LANGUAGE and name $NAME, and returns a pointer to the
3186 input method object newly allocated.
3188 This function at first decides an driver for the input method as
3191 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3192 #minput_driver is used.
3194 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
3195 driver pointed to by the property value is used to open the input
3196 method. If $NAME has no such property, @c NULL is returned.
3198 Then, the member MInputDriver::open_im () of the driver is
3201 $ARG is set in the member @c arg of the structure MInputMethod so
3202 that the driver can refer to it. */
3205 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3207 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3208 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3210 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3212 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3213 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3215 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3216 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3217 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3219 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3221 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3223 @latexonly \IPAlabel{minput_open} @endlatexonly
3228 minput_open_im (MSymbol language, MSymbol name, void *arg)
3231 MInputDriver *driver;
3233 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3234 msymbol_name (language), msymbol_name (name));
3236 driver = minput_driver;
3239 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3241 MERROR (MERROR_IM, NULL);
3244 MSTRUCT_CALLOC (im, MERROR_IM);
3245 im->language = language;
3248 im->driver = *driver;
3249 if ((*im->driver.open_im) (im) < 0)
3251 MDEBUG_PRINT (" failed\n");
3255 MDEBUG_PRINT (" ok\n");
3262 @brief Close an input method.
3264 The minput_close_im () function closes the input method $IM, which
3265 must have been created by minput_open_im (). */
3268 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3270 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3271 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3274 minput_close_im (MInputMethod *im)
3276 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3277 msymbol_name (im->name), msymbol_name (im->language));
3278 (*im->driver.close_im) (im);
3280 MDEBUG_PRINT (" done\n");
3286 @brief Create an input context.
3288 The minput_create_ic () function creates an input context object
3289 associated with input method $IM, and calls callback functions
3290 corresponding to #Minput_preedit_start, #Minput_status_start, and
3291 #Minput_status_draw in this order.
3295 If an input context is successfully created, minput_create_ic ()
3296 returns a pointer to it. Otherwise it returns @c NULL. */
3299 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3301 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3302 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3303 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3304 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3308 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3309 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3313 minput_create_ic (MInputMethod *im, void *arg)
3317 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3318 msymbol_name (im->name), msymbol_name (im->language));
3319 MSTRUCT_CALLOC (ic, MERROR_IM);
3322 ic->preedit = mtext ();
3323 ic->candidate_list = NULL;
3324 ic->produced = mtext ();
3325 ic->spot.x = ic->spot.y = 0;
3327 ic->plist = mplist ();
3328 if ((*im->driver.create_ic) (ic) < 0)
3330 MDEBUG_PRINT (" failed\n");
3331 M17N_OBJECT_UNREF (ic->preedit);
3332 M17N_OBJECT_UNREF (ic->produced);
3333 M17N_OBJECT_UNREF (ic->plist);
3338 if (im->driver.callback_list)
3340 minput__callback (ic, Minput_preedit_start);
3341 minput__callback (ic, Minput_status_start);
3342 minput__callback (ic, Minput_status_draw);
3345 MDEBUG_PRINT (" ok\n");
3352 @brief Destroy an input context.
3354 The minput_destroy_ic () function destroys the input context $IC,
3355 which must have been created by minput_create_ic (). It calls
3356 callback functions corresponding to #Minput_preedit_done,
3357 #Minput_status_done, and #Minput_candidates_done in this order. */
3360 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3362 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3363 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3364 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3365 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3366 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3370 minput_destroy_ic (MInputContext *ic)
3372 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3373 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3374 if (ic->im->driver.callback_list)
3376 minput__callback (ic, Minput_preedit_done);
3377 minput__callback (ic, Minput_status_done);
3378 minput__callback (ic, Minput_candidates_done);
3380 (*ic->im->driver.destroy_ic) (ic);
3381 M17N_OBJECT_UNREF (ic->preedit);
3382 M17N_OBJECT_UNREF (ic->produced);
3383 M17N_OBJECT_UNREF (ic->plist);
3384 MDEBUG_PRINT (" done\n");
3391 @brief Filter an input key.
3393 The minput_filter () function filters input key $KEY according to
3394 input context $IC, and calls callback functions corresponding to
3395 #Minput_preedit_draw, #Minput_status_draw, and
3396 #Minput_candidates_draw if the preedit text, the status, and the
3397 current candidate are changed respectively.
3399 To make the input method commit the current preedit text (if any)
3400 and shift to the initial state, call this function with #Mnil as
3403 To inform the input method about the focus-out event, call this
3404 function with #Minput_focus_out as $KEY.
3406 To inform the input method about the focus-in event, call this
3407 function with #Minput_focus_in as $KEY.
3409 To inform the input method about the focus-move event (i.e. input
3410 spot change within the same input context), call this function
3411 with #Minput_focus_move as $KEY.
3414 If $KEY is filtered out, this function returns 1. In that case,
3415 the caller should discard the key. Otherwise, it returns 0, and
3416 the caller should handle the key, for instance, by calling the
3417 function minput_lookup () with the same key. */
3420 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3422 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3423 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3424 #Minput_preedit_draw, #Minput_status_draw,
3425 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3428 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3429 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3430 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3431 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3433 @latexonly \IPAlabel{minput_filter} @endlatexonly
3437 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3444 ret = (*ic->im->driver.filter) (ic, key, arg);
3446 if (ic->im->driver.callback_list)
3448 if (ic->preedit_changed)
3449 minput__callback (ic, Minput_preedit_draw);
3450 if (ic->status_changed)
3451 minput__callback (ic, Minput_status_draw);
3452 if (ic->candidates_changed)
3453 minput__callback (ic, Minput_candidates_draw);
3462 @brief Look up a text produced in the input context.
3464 The minput_lookup () function looks up a text in the input context
3465 $IC. $KEY must be the same one provided to the previous call of
3468 If a text was produced by the input method, it is concatenated
3471 This function calls #MInputDriver::lookup .
3474 If $KEY was correctly handled by the input method, this function
3475 returns 0. Otherwise, returns -1, even in that case, some text
3476 may be produced in $MT. */
3479 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3481 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3482 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3484 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3487 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3490 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3491 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3492 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3494 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3497 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3499 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3504 @brief Set the spot of the input context.
3506 The minput_set_spot () function set the spot of input context $IC
3507 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3508 The semantics of these values depend on the input method driver.
3510 For instance, a driver designed to work in a CUI environment may
3511 use $X and $Y as column and row numbers, and ignore $ASCENT and
3512 $DESCENT . A driver designed to work in a window system may
3513 interpret $X and $Y as pixel offsets relative to the origin of the
3514 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3515 descent pixels of the line at ($X . $Y ).
3517 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3519 $MT and $POS is the M-text and the character position at the spot.
3520 $MT may be @c NULL, in which case, the input method cannot get
3521 information about the text around the spot. */
3524 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3526 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3527 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3528 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3530 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3531 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3532 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3533 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3534 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3535 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3537 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3539 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3540 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3544 minput_set_spot (MInputContext *ic, int x, int y,
3545 int ascent, int descent, int fontsize,
3550 ic->spot.ascent = ascent;
3551 ic->spot.descent = descent;
3552 ic->spot.fontsize = fontsize;
3555 if (ic->im->driver.callback_list)
3556 minput__callback (ic, Minput_set_spot);
3561 @brief Toggle input method.
3563 The minput_toggle () function toggles the input method associated
3564 with input context $IC. */
3566 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3568 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3569 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3573 minput_toggle (MInputContext *ic)
3575 if (ic->im->driver.callback_list)
3576 minput__callback (ic, Minput_toggle);
3577 ic->active = ! ic->active;
3581 @brief Reset an input context.
3583 The minput_reset_ic () function resets input context $IC by
3584 calling a callback function corresponding to #Minput_reset. It
3585 resets the status of $IC to the one of just after created. As the
3586 current preedit text is deleted without commitment, if necessary,
3587 call minput_filter () with the arg @r key #Mnil to force the input
3588 method to commit the preedit in advance. */
3591 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3593 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3594 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3595 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3596 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3597 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3598 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3601 minput_reset_ic (MInputContext *ic)
3603 if (ic->im->driver.callback_list)
3604 minput__callback (ic, Minput_reset);
3608 @brief Get description text of an input method.
3610 The minput_get_description () function returns an M-text that
3611 describes the input method specified by $LANGUAGE and $NAME.
3614 If the specified input method has a description text, a pointer to
3615 #MText is returned. A caller have to free it by m17n_object_unref ().
3616 If the input method does not have a description text, @c NULL is
3619 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3621 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3622 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3624 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3625 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3626 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3627 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3630 minput_get_description (MSymbol language, MSymbol name)
3632 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3638 pl = MPLIST_PLIST (plist);
3639 pl = MPLIST_NEXT (pl);
3640 if (MPLIST_MTEXT_P (pl))
3642 mt = MPLIST_MTEXT (pl);
3643 M17N_OBJECT_REF (mt);
3645 M17N_OBJECT_UNREF (plist);
3650 @brief Get information about input method commands.
3652 The minput_get_commands () function returns information about
3653 input method commands of the input method specified by $LANGUAGE
3654 and $NAME. An input method command is a pseudo key event to which
3655 one or more actual input key sequences are assigned.
3657 There are two kinds of commands, global and local. Global
3658 commands are used by multiple input methods for the same purpose,
3659 and have global key assignments. Local commands are used only in
3660 a specific input method, and have only local key assignments.
3662 Each input method may locally change key assignments for global
3663 commands. A global key assignment for a global command are
3664 effective only when the current input method does not have local
3665 key assignments for that command.
3667 If $NAME is #Mnil, information about global commands is returned.
3668 In this case $LANGUAGE is ignored.
3670 If $NAME is not #Mnil, information about those commands that have
3671 local key assignments in the input method specified by $LANGUAGE
3672 and $NAME is returned.
3675 If no input method commands are found, this function returns @c NULL.
3677 Otherwise, a pointer to a plist is returned. The key of each
3678 element in the plist is a symbol representing a command, and the
3679 value is a plist of the form COMMAND-INFO described below.
3681 The first element of COMMAND-INFO has the key #Mtext, and the
3682 value is an M-text describing the command.
3684 If there are no more elements, that means no key sequences are
3685 assigned to the command. Otherwise, each of the remaining
3686 elements has the key #Mplist, and the value is a plist whose keys are
3687 #Msymbol and values are symbols representing input keys, which are
3688 currently assigned to the command.
3690 As the returned plist is kept in the library, the caller must not
3691 modify nor free it. */
3693 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3695 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3696 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3697 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3698 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3700 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3701 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3702 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3703 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3705 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3706 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3707 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3710 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3711 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3713 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3714 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3718 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3720 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3721 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3722 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3724 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3725 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3726 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3729 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3730 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3731 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3732 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3733 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3735 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3736 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3739 minput_get_commands (MSymbol language, MSymbol name)
3741 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
3743 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3747 @brief Assign a key sequence to an input method command.
3749 The minput_assign_command_keys () function assigns input key
3750 sequence $KEYSEQ to input method command $COMMAND for the input
3751 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3752 key sequence is assigned globally no matter what $LANGUAGE is.
3753 Otherwise the key sequence is assigned locally.
3755 Each element of $KEYSEQ must have the key $Msymbol and the value
3756 must be a symbol representing an input key.
3758 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3759 globally or locally.
3761 This assignment gets effective in a newly opened input method.
3764 If the operation was successful, 0 is returned. Otherwise -1 is
3765 returned, and #merror_code is set to #MERROR_IM. */
3767 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3769 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
3770 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
3771 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
3772 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
3773 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3775 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
3776 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3778 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
3779 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3781 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
3784 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3785 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3788 minput_assign_command_keys (MSymbol language, MSymbol name,
3789 MSymbol command, MPlist *keyseq)
3791 MPlist *plist, *pl, *p;
3793 if (check_command_keyseq (keyseq) < 0
3794 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
3795 MERROR (MERROR_IM, -1);
3796 pl = mplist_get (plist, command);
3799 pl = MPLIST_NEXT (pl);
3801 while ((p = mplist_pop (pl)))
3802 M17N_OBJECT_UNREF (p);
3805 keyseq = mplist_copy (keyseq);
3806 mplist_push (pl, Mplist, keyseq);
3807 M17N_OBJECT_UNREF (keyseq);
3813 MERROR (MERROR_IM, -1);
3816 /* Get global commands. */
3817 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
3818 pl = mplist_get (pl, command);
3820 MERROR (MERROR_IM, -1);
3822 mplist_add (p, Mtext, mplist_value (pl));
3823 keyseq = mplist_copy (keyseq);
3824 mplist_add (p, Mplist, keyseq);
3825 M17N_OBJECT_UNREF (keyseq);
3826 mplist_push (plist, command, p);
3832 @brief Get a list of variables of an input method.
3834 The minput_get_variables () function returns a plist (#MPlist) of
3835 variables used to control the behavior of the input method
3836 specified by $LANGUAGE and $NAME. The key of an element of the
3837 plist is a symbol representing a variable, and the value is a
3838 plist of the form VAR-INFO (described below) that carries the
3839 information about the variable.
3841 The first element of VAR-INFO has the key #Mtext or #Msymbol. If
3842 the key is #Mtext, the value is an M-text describing the variable.
3843 If the key is #Msymbol, that value is #Mnil which means the
3844 variable has no description text.
3846 The second element of VAR-INFO is for the value of the variable.
3847 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3848 integer, a symbol, or an M-text, respectively. The variable is
3849 set to this value when an input context is created for the input
3852 If there are no more elements, the variable can take any value
3853 that matches with the above type. Otherwise, the remaining
3854 elements of VAR-INFO are to specify valid values of the variable.
3856 If the type of the variable is integer, the following elements
3857 have the key #Minteger or #Mplist. If it is #Minteger, the value
3858 is a valid integer value. If it is #Mplist, the value is a plist
3859 of two of elements. Both of them have the key #Minteger, and
3860 values are the minimum and maximum bounds of the valid value
3863 If the type of the variable is symbol or M-text, the following
3864 elements of the plist have the key #Msymbol or #Mtext,
3865 respectively, and the value must be a valid one.
3867 For instance, suppose an input method has the variables:
3869 @li name:intvar, description:"value is an integer",
3870 initial value:0, value-range:0..3,10,20
3872 @li name:symvar, description:"value is a symbol",
3873 initial value:nil, value-range:a, b, c, nil
3875 @li name:txtvar, description:"value is an M-text",
3876 initial value:empty text, no value-range (i.e. any text)
3878 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3879 a value, and '(...)' means a plist):
3882 plist:(intvar:(mtext:"value is an integer"
3884 plist:(integer:0 integer:3)
3887 symvar:(mtext:"value is a symbol"
3893 txtvar:(mtext:"value is an M-text"
3898 If the input method uses any variables, a pointer to #MPlist is
3899 returned. As the plist is kept in the library, a caller must not
3900 modify nor free it. If the input method does not use any
3901 variable, @c NULL is returned. */
3903 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3905 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3906 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3907 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3908 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3909 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3911 VAR-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼¤¬
3912 #Mtext ¤Ê¤é¡¢ÃͤϤ½¤ÎÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬ #Msymbol
3913 ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤ÎÊÑ¿ô¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê¤¤¤³¤È¤Ë¤Ê¤ë¡£
3915 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3916 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3917 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3919 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3920 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3922 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3923 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3924 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3925 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3927 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3928 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3930 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3932 @li name:intvar, ÀâÌÀ:"value is an integer",
3933 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3935 @li name:symvar, ÀâÌÀ:"value is a symbol",
3936 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3938 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3939 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3941 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3942 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3945 plist:(intvar:(mtext:"value is an integer"
3947 plist:(integer:0 integer:3)
3950 symvar:(mtext:"value is a symbol"
3956 txtvar:(mtext:"value is an M-text"
3961 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3962 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3963 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3966 minput_get_variables (MSymbol language, MSymbol name)
3968 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
3970 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3974 @brief Set the initial value of an input method variable.
3976 The minput_set_variable () function sets the initial value of
3977 input method variable $VARIABLE to $VALUE for the input method
3978 specified by $LANGUAGE and $NAME.
3980 By default, the initial value is 0.
3982 This setting gets effective in a newly opened input method.
3985 If the operation was successful, 0 is returned. Otherwise -1 is
3986 returned, and #merror_code is set to #MERROR_IM. */
3988 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3990 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3991 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3992 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3994 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3996 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
3999 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
4000 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
4003 minput_set_variable (MSymbol language, MSymbol name,
4004 MSymbol variable, void *value)
4006 MPlist *plist, *val_element, *range_element;
4009 plist = get_nested_list (language, name, Mnil, M_variable);
4011 MERROR (MERROR_IM, -1);
4012 plist = mplist_find_by_value (plist, variable);
4014 MERROR (MERROR_IM, -1);
4015 plist = MPLIST_PLIST (MPLIST_NEXT (plist));
4016 val_element = MPLIST_NEXT (plist);
4017 type = MPLIST_KEY (val_element);
4018 range_element = MPLIST_NEXT (val_element);
4020 if (! MPLIST_TAIL_P (range_element))
4022 if (type == Minteger)
4024 int val = (int) value, this_val;
4026 MPLIST_DO (plist, range_element)
4028 this_val = (int) MPLIST_VAL (plist);
4029 if (MPLIST_PLIST_P (plist))
4031 int min_bound, max_bound;
4032 MPlist *pl = MPLIST_PLIST (plist);
4034 min_bound = (int) MPLIST_VAL (pl);
4035 pl = MPLIST_NEXT (pl);
4036 max_bound = (int) MPLIST_VAL (pl);
4037 if (val >= min_bound && val <= max_bound)
4040 else if (val == this_val)
4043 if (MPLIST_TAIL_P (plist))
4044 MERROR (MERROR_IM, -1);
4046 else if (type == Msymbol)
4048 MPLIST_DO (plist, range_element)
4049 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
4051 if (MPLIST_TAIL_P (plist))
4052 MERROR (MERROR_IM, -1);
4054 else /* type == Mtext */
4056 MPLIST_DO (plist, range_element)
4057 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
4059 if (MPLIST_TAIL_P (plist))
4060 MERROR (MERROR_IM, -1);
4061 M17N_OBJECT_REF (value);
4065 mplist_set (val_element, type, value);
4071 /*** @addtogroup m17nDebug */
4077 @brief Dump an input method.
4079 The mdebug_dump_im () function prints the input method $IM in a
4080 human readable way to the stderr. $INDENT specifies how many
4081 columns to indent the lines but the first one.
4084 This function returns $IM. */
4086 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
4088 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
4089 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
4092 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
4095 mdebug_dump_im (MInputMethod *im, int indent)
4097 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
4100 prefix = (char *) alloca (indent + 1);
4101 memset (prefix, 32, indent);
4102 prefix[indent] = '\0';
4104 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
4105 msymbol_name (im->name));
4106 mdebug_dump_mtext (im_info->title, 0, 0);
4107 if (im->name != Mnil)
4111 MPLIST_DO (state, im_info->states)
4113 fprintf (stderr, "\n%s ", prefix);
4114 dump_im_state (MPLIST_VAL (state), indent + 2);
4117 fprintf (stderr, ")");