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 M17N_OBJECT_UNREF (ic_info->preceding_text);
2560 M17N_OBJECT_UNREF (ic_info->following_text);
2561 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2562 ic_info->key_unhandled = 0;
2564 if (handle_key (ic) < 0)
2566 /* KEY was not handled. Delete it from the current key sequence. */
2567 if (ic_info->used > 0)
2569 memmove (ic_info->keys, ic_info->keys + 1,
2570 sizeof (int) * (ic_info->used - 1));
2573 /* This forces returning 1. */
2574 ic_info->key_unhandled = 1;
2580 reset_ic (ic, Mnil);
2581 ic_info->key_unhandled = 1;
2584 /* Break the loop if all keys were handled. */
2585 } while (ic_info->key_head < ic_info->used);
2587 /* If the current map is the root of the initial state, we should
2588 produce any preedit text in ic->produced. */
2589 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2590 && mtext_nchars (ic->preedit) > 0)
2591 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2593 if (mtext_nchars (ic->produced) > 0)
2595 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2598 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2599 Mlanguage, ic->im->language);
2602 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2606 /** Return 1 if the last event or key was not handled, otherwise
2609 There is no need of looking up because ic->produced should already
2610 contain the produced text (if any).
2615 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2617 mtext_cat (mt, ic->produced);
2618 mtext_reset (ic->produced);
2619 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2622 static MPlist *load_im_info_keys;
2625 load_partial_im_info (MSymbol language, MSymbol name,
2626 MSymbol extra, MSymbol key)
2631 if (language == Mnil)
2632 MERROR (MERROR_IM, NULL);
2633 mdb = mdatabase_find (Minput_method, language, name, extra);
2635 MERROR (MERROR_IM, NULL);
2637 mplist_push (load_im_info_keys, key, Mt);
2638 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2639 mplist_pop (load_im_info_keys);
2644 static MInputMethodInfo *
2645 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2649 MInputMethodInfo *im_info = NULL;
2651 if (language == Mnil)
2652 MERROR (MERROR_IM, NULL);
2653 mdb = mdatabase_find (Minput_method, language, name, extra);
2655 MERROR (MERROR_IM, NULL);
2658 im_info_list = mplist ();
2659 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2661 if (mdatabase__check (mdb))
2663 plist = MPLIST_NEXT (plist);
2664 im_info = MPLIST_VAL (plist);
2668 free_im_info (MPLIST_VAL (plist));
2672 plist = mdatabase_load (mdb);
2674 MERROR (MERROR_IM, NULL);
2675 im_info = load_im_info (language, name, plist);
2676 M17N_OBJECT_UNREF (plist);
2678 MERROR (MERROR_IM, NULL);
2679 mplist_push (im_info_list, Mt, im_info);
2680 mplist_push (im_info_list, Mt, mdb);
2685 /* Input method command handler. */
2687 /* List of all (global and local) commands.
2688 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2689 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2690 Global commands are storead as (t (t COMMAND ...)) */
2692 /* Check if PLIST is a valid command key sequence.
2693 PLIST must be NULL or:
2694 [ symbol:KEY | integer:KEY ] ... */
2697 check_command_keyseq (MPlist *plist)
2701 MPLIST_DO (plist, plist)
2703 if (MPLIST_SYMBOL_P (plist))
2705 else if (MPLIST_INTEGER_P (plist))
2707 int n = MPLIST_INTEGER (plist);
2711 MPLIST_KEY (plist) = Msymbol;
2712 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2720 /* Check if PLIST has this form:
2721 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2723 If the form of PLIST matches, return 0, otherwise return -1. */
2726 check_command_list (MPlist *plist)
2728 MPLIST_DO (plist, plist)
2730 if (MPLIST_PLIST_P (plist))
2732 MPlist *pl = MPLIST_PLIST (plist);
2735 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2738 else if (! MPLIST_MTEXT_P (plist))
2746 /* Input method variable handler. */
2748 /* Check if PLIST has this form:
2749 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2752 If the form of PLIST matches, return 0, otherwise return -1. */
2755 check_variable_list (MPlist *plist)
2757 MSymbol type = MPLIST_KEY (plist);
2760 if (type != Minteger && type != Mtext && type != Msymbol)
2762 MPLIST_DO (plist, MPLIST_NEXT (plist))
2764 if (type == Minteger && MPLIST_PLIST_P (plist))
2766 MPLIST_DO (p, MPLIST_PLIST (plist))
2767 if (! MPLIST_INTEGER_P (p))
2770 else if (type != MPLIST_KEY (plist))
2776 /* Support functions for mdebug_dump_im. */
2779 dump_im_map (MPlist *map_list, int indent)
2782 MSymbol key = MPLIST_KEY (map_list);
2783 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2785 prefix = (char *) alloca (indent + 1);
2786 memset (prefix, 32, indent);
2787 prefix[indent] = '\0';
2789 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2790 if (map->map_actions)
2791 mdebug_dump_plist (map->map_actions, indent + 2);
2794 MPLIST_DO (map_list, map->submaps)
2796 fprintf (stderr, "\n%s ", prefix);
2797 dump_im_map (map_list, indent + 2);
2800 if (map->branch_actions)
2802 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2803 mdebug_dump_plist (map->branch_actions, indent + 4);
2804 fprintf (stderr, ")");
2806 fprintf (stderr, ")");
2811 dump_im_state (MIMState *state, int indent)
2816 prefix = (char *) alloca (indent + 1);
2817 memset (prefix, 32, indent);
2818 prefix[indent] = '\0';
2820 fprintf (stderr, "(%s", msymbol_name (state->name));
2821 if (state->map->submaps)
2823 MPLIST_DO (map_list, state->map->submaps)
2825 fprintf (stderr, "\n%s ", prefix);
2826 dump_im_map (map_list, indent + 2);
2829 fprintf (stderr, ")");
2838 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2839 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2840 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2841 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2842 char buf[6], buf2[256];
2846 Minput_method = msymbol ("input-method");
2847 Minput_driver = msymbol ("input-driver");
2848 Mtitle = msymbol ("title");
2849 Mmacro = msymbol ("macro");
2850 Mmodule = msymbol ("module");
2851 Mmap = msymbol ("map");
2852 Mstate = msymbol ("state");
2853 Minclude = msymbol ("include");
2854 Minsert = msymbol ("insert");
2855 M_candidates = msymbol (" candidates");
2856 Mdelete = msymbol ("delete");
2857 Mmove = msymbol ("move");
2858 Mmark = msymbol ("mark");
2859 Mpushback = msymbol ("pushback");
2860 Mundo = msymbol ("undo");
2861 Mcall = msymbol ("call");
2862 Mshift = msymbol ("shift");
2863 Mselect = msymbol ("select");
2864 Mshow = msymbol ("show");
2865 Mhide = msymbol ("hide");
2866 Mcommit = msymbol ("commit");
2867 Munhandle = msymbol ("unhandle");
2868 Mset = msymbol ("set");
2869 Madd = msymbol ("add");
2870 Msub = msymbol ("sub");
2871 Mmul = msymbol ("mul");
2872 Mdiv = msymbol ("div");
2873 Mequal = msymbol ("=");
2874 Mless = msymbol ("<");
2875 Mgreater = msymbol (">");
2877 Mcandidates_group_size = msymbol ("candidates-group-size");
2878 Mcandidates_charset = msymbol ("candidates-charset");
2880 Minput_preedit_start = msymbol ("input-preedit-start");
2881 Minput_preedit_done = msymbol ("input-preedit-done");
2882 Minput_preedit_draw = msymbol ("input-preedit-draw");
2883 Minput_status_start = msymbol ("input-status-start");
2884 Minput_status_done = msymbol ("input-status-done");
2885 Minput_status_draw = msymbol ("input-status-draw");
2886 Minput_candidates_start = msymbol ("input-candidates-start");
2887 Minput_candidates_done = msymbol ("input-candidates-done");
2888 Minput_candidates_draw = msymbol ("input-candidates-draw");
2889 Minput_set_spot = msymbol ("input-set-spot");
2890 Minput_focus_move = msymbol ("input-focus-move");
2891 Minput_focus_in = msymbol ("input-focus-in");
2892 Minput_focus_out = msymbol ("input-focus-out");
2893 Minput_toggle = msymbol ("input-toggle");
2894 Minput_reset = msymbol ("input-reset");
2895 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
2896 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
2898 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2899 Mcandidate_index = msymbol (" candidate-index");
2901 Minit = msymbol ("init");
2902 Mfini = msymbol ("fini");
2904 M_key_alias = msymbol (" key-alias");
2905 M_description = msymbol ("description");
2906 M_command = msymbol ("command");
2907 M_variable = msymbol ("variable");
2909 load_im_info_keys = mplist ();
2910 plist = mplist_add (load_im_info_keys, Mstate, Mnil);
2915 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2919 one_char_symbol[i] = msymbol (buf);
2922 alias = msymbol (key_names[i]);
2923 msymbol_put (one_char_symbol[i], M_key_alias, alias);
2926 alias = one_char_symbol[i];
2927 buf[2] += (i == 0) ? -32 : 32;
2928 msymbol_put (alias, M_key_alias, msymbol (buf));
2929 buf[2] -= (i == 0) ? -32 : 32;
2931 for (buf[2] = i; i < 127; i++, buf[2]++)
2932 one_char_symbol[i] = msymbol (buf + 2);
2933 one_char_symbol[i++] = msymbol ("Delete");
2939 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2941 one_char_symbol[i] = msymbol (buf);
2942 if (key_names[i - 128])
2944 strcpy (buf2 + 2, key_names[i - 128]);
2945 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2948 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2949 one_char_symbol[i] = msymbol (buf + 2);
2950 one_char_symbol[i] = msymbol ("M-Delete");
2952 command_list = variable_list = NULL;
2954 minput_default_driver.open_im = open_im;
2955 minput_default_driver.close_im = close_im;
2956 minput_default_driver.create_ic = create_ic;
2957 minput_default_driver.destroy_ic = destroy_ic;
2958 minput_default_driver.filter = filter;
2959 minput_default_driver.lookup = lookup;
2960 minput_default_driver.callback_list = mplist ();
2961 mplist_put (minput_default_driver.callback_list, Minput_reset,
2963 minput_driver = &minput_default_driver;
2972 M17N_OBJECT_UNREF (command_list);
2973 command_list = NULL;
2977 M17N_OBJECT_UNREF (variable_list);
2978 variable_list = NULL;
2981 if (minput_default_driver.callback_list)
2983 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2984 minput_default_driver.callback_list = NULL;
2986 if (minput_driver->callback_list)
2988 M17N_OBJECT_UNREF (minput_driver->callback_list);
2989 minput_driver->callback_list = NULL;
2994 while (! MPLIST_TAIL_P (im_info_list))
2997 mplist_pop (im_info_list);
2998 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
2999 /* Pop (t . im_info) */
3000 mplist_pop (im_info_list);
3002 M17N_OBJECT_UNREF (im_info_list);
3003 im_info_list = NULL;
3006 M17N_OBJECT_UNREF (load_im_info_keys);
3010 minput__callback (MInputContext *ic, MSymbol command)
3012 if (ic->im->driver.callback_list)
3014 MInputCallbackFunc func
3015 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3019 (func) (ic, command);
3024 minput__char_to_key (int c)
3026 if (c < 0 || c >= 0x100)
3029 return one_char_symbol[c];
3033 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3038 /*** @addtogroup m17nInputMethod */
3043 @name Variables: Predefined symbols for callback commands.
3045 These are the predefined symbols that are used as the @c COMMAND
3046 argument of callback functions of an input method driver (see
3047 #MInputDriver::callback_list ).
3049 Most of them don't require extra argument nor return any value;
3050 exceptions are these:
3052 Minput_get_surrounding_text: When a callback function assigned for
3053 this command is called, the first element of #MInputContext::plist
3054 has key #Msymbol and the value specifies which portion of the
3055 surrounding text should be retrieved. If the value is positive,
3056 it specifies the number of characters following the current cursor
3057 position. If the value is negative, the absolute value specifies
3058 the number of characters preceding the current cursor position.
3059 The callback function must set the key of this element to #Mtext
3060 and the value to the retrived M-text (whose length may be shorter
3061 than the requested number of characters if the available text is
3062 not that long, or it may be longer if an application thinks it's
3063 more efficient to return that length).
3065 Minput_delete_surrounding_text: When a callback function assigned
3066 for this command is called, the first element of
3067 #MInputContext::plist has key #Msymbol and the value specifies
3068 which portion of the surrounding text should be deleted in the
3069 same way as the case of Minput_get_surrounding_text. The callback
3070 function must delete the specified text. It should not alter
3071 #MInputContext::plist. */
3074 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3076 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3077 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3082 MSymbol Minput_preedit_start;
3083 MSymbol Minput_preedit_done;
3084 MSymbol Minput_preedit_draw;
3085 MSymbol Minput_status_start;
3086 MSymbol Minput_status_done;
3087 MSymbol Minput_status_draw;
3088 MSymbol Minput_candidates_start;
3089 MSymbol Minput_candidates_done;
3090 MSymbol Minput_candidates_draw;
3091 MSymbol Minput_set_spot;
3092 MSymbol Minput_toggle;
3093 MSymbol Minput_reset;
3094 MSymbol Minput_get_surrounding_text;
3095 MSymbol Minput_delete_surrounding_text;
3101 @name Variables: Predefined symbols for special input events.
3103 These are the predefined symbols that are used as the @c KEY
3104 argument of minput_filter (). */
3109 MSymbol Minput_focus_out;
3110 MSymbol Minput_focus_in;
3111 MSymbol Minput_focus_move;
3118 @brief The default driver for internal input methods.
3120 The variable #minput_default_driver is the default driver for
3121 internal input methods.
3123 The member MInputDriver::open_im () searches the m17n database for
3124 an input method that matches the tag \< #Minput_method, $LANGUAGE,
3125 $NAME\> and loads it.
3127 The member MInputDriver::callback_list () is @c NULL. Thus, it is
3128 programmers responsibility to set it to a plist of proper callback
3129 functions. Otherwise, no feedback information (e.g. preedit text)
3130 can be shown to users.
3132 The macro M17N_INIT () sets the variable #minput_driver to the
3133 pointer to this driver so that all internal input methods use it.
3135 Therefore, unless @c minput_driver is set differently, the driver
3136 dependent arguments $ARG of the functions whose name begin with
3137 "minput_" are all ignored. */
3140 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
3142 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
3144 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
3145 \< #Minput_method, $LANGUAGE, $NAME\>
3146 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
3148 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
3149 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
3150 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
3151 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
3153 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
3154 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
3156 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
3157 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
3159 MInputDriver minput_default_driver;
3163 @brief The driver for internal input methods.
3165 The variable #minput_driver is a pointer to the input method
3166 driver that is used by internal input methods. The macro
3167 M17N_INIT () initializes it to a pointer to #minput_default_driver
3168 if <m17n<EM></EM>.h> is included. */
3170 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
3172 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
3173 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
3174 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
3175 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
3177 MInputDriver *minput_driver;
3179 MSymbol Minput_driver;
3184 @brief Open an input method.
3186 The minput_open_im () function opens an input method that matches
3187 language $LANGUAGE and name $NAME, and returns a pointer to the
3188 input method object newly allocated.
3190 This function at first decides an driver for the input method as
3193 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3194 #minput_driver is used.
3196 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
3197 driver pointed to by the property value is used to open the input
3198 method. If $NAME has no such property, @c NULL is returned.
3200 Then, the member MInputDriver::open_im () of the driver is
3203 $ARG is set in the member @c arg of the structure MInputMethod so
3204 that the driver can refer to it. */
3207 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3209 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3210 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3212 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3214 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3215 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3217 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3218 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3219 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3221 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3223 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3225 @latexonly \IPAlabel{minput_open} @endlatexonly
3230 minput_open_im (MSymbol language, MSymbol name, void *arg)
3233 MInputDriver *driver;
3235 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3236 msymbol_name (language), msymbol_name (name));
3238 driver = minput_driver;
3241 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3243 MERROR (MERROR_IM, NULL);
3246 MSTRUCT_CALLOC (im, MERROR_IM);
3247 im->language = language;
3250 im->driver = *driver;
3251 if ((*im->driver.open_im) (im) < 0)
3253 MDEBUG_PRINT (" failed\n");
3257 MDEBUG_PRINT (" ok\n");
3264 @brief Close an input method.
3266 The minput_close_im () function closes the input method $IM, which
3267 must have been created by minput_open_im (). */
3270 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3272 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3273 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3276 minput_close_im (MInputMethod *im)
3278 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3279 msymbol_name (im->name), msymbol_name (im->language));
3280 (*im->driver.close_im) (im);
3282 MDEBUG_PRINT (" done\n");
3288 @brief Create an input context.
3290 The minput_create_ic () function creates an input context object
3291 associated with input method $IM, and calls callback functions
3292 corresponding to #Minput_preedit_start, #Minput_status_start, and
3293 #Minput_status_draw in this order.
3297 If an input context is successfully created, minput_create_ic ()
3298 returns a pointer to it. Otherwise it returns @c NULL. */
3301 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3303 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3304 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3305 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3306 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3310 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3311 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3315 minput_create_ic (MInputMethod *im, void *arg)
3319 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3320 msymbol_name (im->name), msymbol_name (im->language));
3321 MSTRUCT_CALLOC (ic, MERROR_IM);
3324 ic->preedit = mtext ();
3325 ic->candidate_list = NULL;
3326 ic->produced = mtext ();
3327 ic->spot.x = ic->spot.y = 0;
3329 ic->plist = mplist ();
3330 if ((*im->driver.create_ic) (ic) < 0)
3332 MDEBUG_PRINT (" failed\n");
3333 M17N_OBJECT_UNREF (ic->preedit);
3334 M17N_OBJECT_UNREF (ic->produced);
3335 M17N_OBJECT_UNREF (ic->plist);
3340 if (im->driver.callback_list)
3342 minput__callback (ic, Minput_preedit_start);
3343 minput__callback (ic, Minput_status_start);
3344 minput__callback (ic, Minput_status_draw);
3347 MDEBUG_PRINT (" ok\n");
3354 @brief Destroy an input context.
3356 The minput_destroy_ic () function destroys the input context $IC,
3357 which must have been created by minput_create_ic (). It calls
3358 callback functions corresponding to #Minput_preedit_done,
3359 #Minput_status_done, and #Minput_candidates_done in this order. */
3362 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3364 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3365 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3366 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3367 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3368 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3372 minput_destroy_ic (MInputContext *ic)
3374 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3375 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3376 if (ic->im->driver.callback_list)
3378 minput__callback (ic, Minput_preedit_done);
3379 minput__callback (ic, Minput_status_done);
3380 minput__callback (ic, Minput_candidates_done);
3382 (*ic->im->driver.destroy_ic) (ic);
3383 M17N_OBJECT_UNREF (ic->preedit);
3384 M17N_OBJECT_UNREF (ic->produced);
3385 M17N_OBJECT_UNREF (ic->plist);
3386 MDEBUG_PRINT (" done\n");
3393 @brief Filter an input key.
3395 The minput_filter () function filters input key $KEY according to
3396 input context $IC, and calls callback functions corresponding to
3397 #Minput_preedit_draw, #Minput_status_draw, and
3398 #Minput_candidates_draw if the preedit text, the status, and the
3399 current candidate are changed respectively.
3401 To make the input method commit the current preedit text (if any)
3402 and shift to the initial state, call this function with #Mnil as
3405 To inform the input method about the focus-out event, call this
3406 function with #Minput_focus_out as $KEY.
3408 To inform the input method about the focus-in event, call this
3409 function with #Minput_focus_in as $KEY.
3411 To inform the input method about the focus-move event (i.e. input
3412 spot change within the same input context), call this function
3413 with #Minput_focus_move as $KEY.
3416 If $KEY is filtered out, this function returns 1. In that case,
3417 the caller should discard the key. Otherwise, it returns 0, and
3418 the caller should handle the key, for instance, by calling the
3419 function minput_lookup () with the same key. */
3422 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3424 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3425 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3426 #Minput_preedit_draw, #Minput_status_draw,
3427 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3430 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3431 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3432 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3433 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3435 @latexonly \IPAlabel{minput_filter} @endlatexonly
3439 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3446 ret = (*ic->im->driver.filter) (ic, key, arg);
3448 if (ic->im->driver.callback_list)
3450 if (ic->preedit_changed)
3451 minput__callback (ic, Minput_preedit_draw);
3452 if (ic->status_changed)
3453 minput__callback (ic, Minput_status_draw);
3454 if (ic->candidates_changed)
3455 minput__callback (ic, Minput_candidates_draw);
3464 @brief Look up a text produced in the input context.
3466 The minput_lookup () function looks up a text in the input context
3467 $IC. $KEY must be the same one provided to the previous call of
3470 If a text was produced by the input method, it is concatenated
3473 This function calls #MInputDriver::lookup .
3476 If $KEY was correctly handled by the input method, this function
3477 returns 0. Otherwise, returns -1, even in that case, some text
3478 may be produced in $MT. */
3481 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3483 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3484 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3486 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3489 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3492 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3493 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3494 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3496 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3499 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3501 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3506 @brief Set the spot of the input context.
3508 The minput_set_spot () function set the spot of input context $IC
3509 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3510 The semantics of these values depend on the input method driver.
3512 For instance, a driver designed to work in a CUI environment may
3513 use $X and $Y as column and row numbers, and ignore $ASCENT and
3514 $DESCENT . A driver designed to work in a window system may
3515 interpret $X and $Y as pixel offsets relative to the origin of the
3516 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3517 descent pixels of the line at ($X . $Y ).
3519 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3521 $MT and $POS is the M-text and the character position at the spot.
3522 $MT may be @c NULL, in which case, the input method cannot get
3523 information about the text around the spot. */
3526 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3528 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3529 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3530 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3532 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3533 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3534 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3535 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3536 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3537 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3539 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3541 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3542 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3546 minput_set_spot (MInputContext *ic, int x, int y,
3547 int ascent, int descent, int fontsize,
3552 ic->spot.ascent = ascent;
3553 ic->spot.descent = descent;
3554 ic->spot.fontsize = fontsize;
3557 if (ic->im->driver.callback_list)
3558 minput__callback (ic, Minput_set_spot);
3563 @brief Toggle input method.
3565 The minput_toggle () function toggles the input method associated
3566 with input context $IC. */
3568 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3570 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3571 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3575 minput_toggle (MInputContext *ic)
3577 if (ic->im->driver.callback_list)
3578 minput__callback (ic, Minput_toggle);
3579 ic->active = ! ic->active;
3583 @brief Reset an input context.
3585 The minput_reset_ic () function resets input context $IC by
3586 calling a callback function corresponding to #Minput_reset. It
3587 resets the status of $IC to the one of just after created. As the
3588 current preedit text is deleted without commitment, if necessary,
3589 call minput_filter () with the arg @r key #Mnil to force the input
3590 method to commit the preedit in advance. */
3593 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3595 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3596 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3597 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3598 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3599 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3600 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3603 minput_reset_ic (MInputContext *ic)
3605 if (ic->im->driver.callback_list)
3606 minput__callback (ic, Minput_reset);
3610 @brief Get description text of an input method.
3612 The minput_get_description () function returns an M-text that
3613 describes the input method specified by $LANGUAGE and $NAME.
3616 If the specified input method has a description text, a pointer to
3617 #MText is returned. A caller have to free it by m17n_object_unref ().
3618 If the input method does not have a description text, @c NULL is
3621 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3623 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3624 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3626 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3627 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3628 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3629 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3632 minput_get_description (MSymbol language, MSymbol name)
3634 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3640 pl = MPLIST_PLIST (plist);
3641 pl = MPLIST_NEXT (pl);
3642 if (MPLIST_MTEXT_P (pl))
3644 mt = MPLIST_MTEXT (pl);
3645 M17N_OBJECT_REF (mt);
3647 M17N_OBJECT_UNREF (plist);
3652 @brief Get information about input method commands.
3654 The minput_get_commands () function returns information about
3655 input method commands of the input method specified by $LANGUAGE
3656 and $NAME. An input method command is a pseudo key event to which
3657 one or more actual input key sequences are assigned.
3659 There are two kinds of commands, global and local. Global
3660 commands are used by multiple input methods for the same purpose,
3661 and have global key assignments. Local commands are used only in
3662 a specific input method, and have only local key assignments.
3664 Each input method may locally change key assignments for global
3665 commands. A global key assignment for a global command are
3666 effective only when the current input method does not have local
3667 key assignments for that command.
3669 If $NAME is #Mnil, information about global commands is returned.
3670 In this case $LANGUAGE is ignored.
3672 If $NAME is not #Mnil, information about those commands that have
3673 local key assignments in the input method specified by $LANGUAGE
3674 and $NAME is returned.
3677 If no input method commands are found, this function returns @c NULL.
3679 Otherwise, a pointer to a plist is returned. The key of each
3680 element in the plist is a symbol representing a command, and the
3681 value is a plist of the form COMMAND-INFO described below.
3683 The first element of COMMAND-INFO has the key #Mtext, and the
3684 value is an M-text describing the command.
3686 If there are no more elements, that means no key sequences are
3687 assigned to the command. Otherwise, each of the remaining
3688 elements has the key #Mplist, and the value is a plist whose keys are
3689 #Msymbol and values are symbols representing input keys, which are
3690 currently assigned to the command.
3692 As the returned plist is kept in the library, the caller must not
3693 modify nor free it. */
3695 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3697 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3698 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3699 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3700 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3702 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3703 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3704 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3705 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3707 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3708 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3709 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3712 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3713 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3715 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3716 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3720 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3722 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3723 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3724 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3726 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3727 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3728 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3731 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3732 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3733 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3734 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3735 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3737 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3738 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3741 minput_get_commands (MSymbol language, MSymbol name)
3743 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
3745 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3749 @brief Assign a key sequence to an input method command.
3751 The minput_assign_command_keys () function assigns input key
3752 sequence $KEYSEQ to input method command $COMMAND for the input
3753 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3754 key sequence is assigned globally no matter what $LANGUAGE is.
3755 Otherwise the key sequence is assigned locally.
3757 Each element of $KEYSEQ must have the key $Msymbol and the value
3758 must be a symbol representing an input key.
3760 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3761 globally or locally.
3763 This assignment gets effective in a newly opened input method.
3766 If the operation was successful, 0 is returned. Otherwise -1 is
3767 returned, and #merror_code is set to #MERROR_IM. */
3769 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3771 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
3772 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
3773 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
3774 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
3775 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3777 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
3778 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3780 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
3781 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3783 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
3786 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3787 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3790 minput_assign_command_keys (MSymbol language, MSymbol name,
3791 MSymbol command, MPlist *keyseq)
3793 MPlist *plist, *pl, *p;
3795 if (check_command_keyseq (keyseq) < 0
3796 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
3797 MERROR (MERROR_IM, -1);
3798 pl = mplist_get (plist, command);
3801 pl = MPLIST_NEXT (pl);
3803 while ((p = mplist_pop (pl)))
3804 M17N_OBJECT_UNREF (p);
3807 keyseq = mplist_copy (keyseq);
3808 mplist_push (pl, Mplist, keyseq);
3809 M17N_OBJECT_UNREF (keyseq);
3815 MERROR (MERROR_IM, -1);
3818 /* Get global commands. */
3819 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
3820 pl = mplist_get (pl, command);
3822 MERROR (MERROR_IM, -1);
3824 mplist_add (p, Mtext, mplist_value (pl));
3825 keyseq = mplist_copy (keyseq);
3826 mplist_add (p, Mplist, keyseq);
3827 M17N_OBJECT_UNREF (keyseq);
3828 mplist_push (plist, command, p);
3834 @brief Get a list of variables of an input method.
3836 The minput_get_variables () function returns a plist (#MPlist) of
3837 variables used to control the behavior of the input method
3838 specified by $LANGUAGE and $NAME. The key of an element of the
3839 plist is a symbol representing a variable, and the value is a
3840 plist of the form VAR-INFO (described below) that carries the
3841 information about the variable.
3843 The first element of VAR-INFO has the key #Mtext or #Msymbol. If
3844 the key is #Mtext, the value is an M-text describing the variable.
3845 If the key is #Msymbol, that value is #Mnil which means the
3846 variable has no description text.
3848 The second element of VAR-INFO is for the value of the variable.
3849 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3850 integer, a symbol, or an M-text, respectively. The variable is
3851 set to this value when an input context is created for the input
3854 If there are no more elements, the variable can take any value
3855 that matches with the above type. Otherwise, the remaining
3856 elements of VAR-INFO are to specify valid values of the variable.
3858 If the type of the variable is integer, the following elements
3859 have the key #Minteger or #Mplist. If it is #Minteger, the value
3860 is a valid integer value. If it is #Mplist, the value is a plist
3861 of two of elements. Both of them have the key #Minteger, and
3862 values are the minimum and maximum bounds of the valid value
3865 If the type of the variable is symbol or M-text, the following
3866 elements of the plist have the key #Msymbol or #Mtext,
3867 respectively, and the value must be a valid one.
3869 For instance, suppose an input method has the variables:
3871 @li name:intvar, description:"value is an integer",
3872 initial value:0, value-range:0..3,10,20
3874 @li name:symvar, description:"value is a symbol",
3875 initial value:nil, value-range:a, b, c, nil
3877 @li name:txtvar, description:"value is an M-text",
3878 initial value:empty text, no value-range (i.e. any text)
3880 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3881 a value, and '(...)' means a plist):
3884 plist:(intvar:(mtext:"value is an integer"
3886 plist:(integer:0 integer:3)
3889 symvar:(mtext:"value is a symbol"
3895 txtvar:(mtext:"value is an M-text"
3900 If the input method uses any variables, a pointer to #MPlist is
3901 returned. As the plist is kept in the library, a caller must not
3902 modify nor free it. If the input method does not use any
3903 variable, @c NULL is returned. */
3905 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3907 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3908 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3909 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3910 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3911 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3913 VAR-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼¤¬
3914 #Mtext ¤Ê¤é¡¢ÃͤϤ½¤ÎÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬ #Msymbol
3915 ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤ÎÊÑ¿ô¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê¤¤¤³¤È¤Ë¤Ê¤ë¡£
3917 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3918 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3919 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3921 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3922 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3924 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3925 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3926 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3927 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3929 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3930 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3932 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3934 @li name:intvar, ÀâÌÀ:"value is an integer",
3935 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3937 @li name:symvar, ÀâÌÀ:"value is a symbol",
3938 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3940 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3941 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3943 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3944 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3947 plist:(intvar:(mtext:"value is an integer"
3949 plist:(integer:0 integer:3)
3952 symvar:(mtext:"value is a symbol"
3958 txtvar:(mtext:"value is an M-text"
3963 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3964 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3965 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3968 minput_get_variables (MSymbol language, MSymbol name)
3970 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
3972 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3976 @brief Set the initial value of an input method variable.
3978 The minput_set_variable () function sets the initial value of
3979 input method variable $VARIABLE to $VALUE for the input method
3980 specified by $LANGUAGE and $NAME.
3982 By default, the initial value is 0.
3984 This setting gets effective in a newly opened input method.
3987 If the operation was successful, 0 is returned. Otherwise -1 is
3988 returned, and #merror_code is set to #MERROR_IM. */
3990 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3992 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3993 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
3994 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
3996 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
3998 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
4001 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
4002 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
4005 minput_set_variable (MSymbol language, MSymbol name,
4006 MSymbol variable, void *value)
4008 MPlist *plist, *val_element, *range_element;
4011 plist = get_nested_list (language, name, Mnil, M_variable);
4013 MERROR (MERROR_IM, -1);
4014 plist = mplist_find_by_value (plist, variable);
4016 MERROR (MERROR_IM, -1);
4017 plist = MPLIST_PLIST (MPLIST_NEXT (plist));
4018 val_element = MPLIST_NEXT (plist);
4019 type = MPLIST_KEY (val_element);
4020 range_element = MPLIST_NEXT (val_element);
4022 if (! MPLIST_TAIL_P (range_element))
4024 if (type == Minteger)
4026 int val = (int) value, this_val;
4028 MPLIST_DO (plist, range_element)
4030 this_val = (int) MPLIST_VAL (plist);
4031 if (MPLIST_PLIST_P (plist))
4033 int min_bound, max_bound;
4034 MPlist *pl = MPLIST_PLIST (plist);
4036 min_bound = (int) MPLIST_VAL (pl);
4037 pl = MPLIST_NEXT (pl);
4038 max_bound = (int) MPLIST_VAL (pl);
4039 if (val >= min_bound && val <= max_bound)
4042 else if (val == this_val)
4045 if (MPLIST_TAIL_P (plist))
4046 MERROR (MERROR_IM, -1);
4048 else if (type == Msymbol)
4050 MPLIST_DO (plist, range_element)
4051 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
4053 if (MPLIST_TAIL_P (plist))
4054 MERROR (MERROR_IM, -1);
4056 else /* type == Mtext */
4058 MPLIST_DO (plist, range_element)
4059 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
4061 if (MPLIST_TAIL_P (plist))
4062 MERROR (MERROR_IM, -1);
4063 M17N_OBJECT_REF (value);
4067 mplist_set (val_element, type, value);
4073 /*** @addtogroup m17nDebug */
4079 @brief Dump an input method.
4081 The mdebug_dump_im () function prints the input method $IM in a
4082 human readable way to the stderr. $INDENT specifies how many
4083 columns to indent the lines but the first one.
4086 This function returns $IM. */
4088 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
4090 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
4091 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
4094 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
4097 mdebug_dump_im (MInputMethod *im, int indent)
4099 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
4102 prefix = (char *) alloca (indent + 1);
4103 memset (prefix, 32, indent);
4104 prefix[indent] = '\0';
4106 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
4107 msymbol_name (im->name));
4108 mdebug_dump_mtext (im_info->title, 0, 0);
4109 if (im->name != Mnil)
4113 MPLIST_DO (state, im_info->states)
4115 fprintf (stderr, "\n%s ", prefix);
4116 dump_im_state (MPLIST_VAL (state), indent + 2);
4119 fprintf (stderr, ")");