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 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
493 mplist_push (ic->plist, Minteger, (void *) pos);
494 minput__callback (ic, Minput_delete_surrounding_text);
495 mplist_pop (ic->plist);
497 M17N_OBJECT_UNREF (ic_info->preceding_text);
499 M17N_OBJECT_UNREF (ic_info->following_text);
503 get_preceding_char (MInputContext *ic, int pos)
505 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
509 if (ic_info->preceding_text)
511 len = mtext_nchars (ic_info->preceding_text);
513 return mtext_ref_char (ic_info->preceding_text, len - pos);
515 mt = get_surrounding_text (ic, - pos);
518 len = mtext_nchars (mt);
519 if (ic_info->preceding_text)
521 if (mtext_nchars (ic_info->preceding_text) < len)
523 M17N_OBJECT_UNREF (ic_info->preceding_text);
524 ic_info->preceding_text = mt;
528 ic_info->preceding_text = mt;
531 return mtext_ref_char (ic_info->preceding_text, len - pos);
535 get_following_char (MInputContext *ic, int pos)
537 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
541 if (ic_info->following_text)
543 len = mtext_nchars (ic_info->following_text);
545 return mtext_ref_char (ic_info->following_text, pos - 1);
547 mt = get_surrounding_text (ic, pos);
550 len = mtext_nchars (mt);
551 if (ic_info->following_text)
553 if (mtext_nchars (ic_info->following_text) < len)
555 M17N_OBJECT_UNREF (ic_info->following_text);
556 ic_info->following_text = mt;
560 ic_info->following_text = mt;
563 return mtext_ref_char (ic_info->following_text, pos - 1);
567 surrounding_pos (MSymbol sym)
573 name = MSYMBOL_NAME (sym);
574 if ((name[1] == '-' || name[1] == '+')
575 && name[2] >= '1' && name[2] <= '9')
576 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
581 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
583 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
585 MText *preedit = ic->preedit;
586 int len = mtext_nchars (preedit);
590 if (MPLIST_INTEGER_P (arg))
591 return MPLIST_INTEGER (arg);
593 && (surrounding = surrounding_pos (MPLIST_SYMBOL (arg))) != 0)
594 return (surrounding < 0
595 ? get_preceding_char (ic, - surrounding)
596 : get_following_char (ic, surrounding));
597 code = marker_code (MPLIST_SYMBOL (arg));
600 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
604 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
607 return ic_info->key_head;
608 if (code >= '0' && code <= '9')
610 else if (code == '=')
611 code = ic->cursor_pos;
612 else if (code == '-' || code == '[')
613 code = ic->cursor_pos - 1;
614 else if (code == '+' || code == ']')
615 code = ic->cursor_pos + 1;
616 else if (code == '<')
618 else if (code == '>')
620 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
624 /* Parse PLIST as an action list. PLIST should have this form:
625 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
626 Return 0 if successfully parsed, otherwise return -1. */
629 parse_action_list (MPlist *plist, MPlist *macros)
631 MPLIST_DO (plist, plist)
633 if (MPLIST_MTEXT_P (plist))
635 /* This is a short form of (insert MTEXT). */
636 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
637 MERROR (MERROR_IM, -1); */
639 else if (MPLIST_PLIST_P (plist)
640 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
641 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
645 /* This is a short form of (insert (GROUPS *)). */
646 MPLIST_DO (pl, MPLIST_PLIST (plist))
648 if (MPLIST_PLIST_P (pl))
652 MPLIST_DO (elt, MPLIST_PLIST (pl))
653 if (! MPLIST_MTEXT_P (elt)
654 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
655 MERROR (MERROR_IM, -1);
659 if (! MPLIST_MTEXT_P (pl)
660 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
661 MERROR (MERROR_IM, -1);
665 else if (MPLIST_INTEGER_P (plist))
667 int c = MPLIST_INTEGER (plist);
669 if (c < 0 || c > MCHAR_MAX)
670 MERROR (MERROR_IM, -1);
672 else if (MPLIST_PLIST_P (plist)
673 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
675 MPlist *pl = MPLIST_PLIST (plist);
676 MSymbol action_name = MPLIST_SYMBOL (pl);
678 pl = MPLIST_NEXT (pl);
680 if (action_name == Minsert)
682 if (MPLIST_MTEXT_P (pl))
684 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
685 MERROR (MERROR_IM, -1);
687 else if (MPLIST_PLIST_P (pl))
691 if (MPLIST_PLIST_P (pl))
695 MPLIST_DO (elt, MPLIST_PLIST (pl))
696 if (! MPLIST_MTEXT_P (elt)
697 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
698 MERROR (MERROR_IM, -1);
702 if (! MPLIST_MTEXT_P (pl)
703 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
704 MERROR (MERROR_IM, -1);
708 else if (! MPLIST_SYMBOL_P (pl))
709 MERROR (MERROR_IM, -1);
711 else if (action_name == Mselect
712 || action_name == Mdelete
713 || action_name == Mmove)
715 if (! MPLIST_SYMBOL_P (pl)
716 && ! MPLIST_INTEGER_P (pl))
717 MERROR (MERROR_IM, -1);
719 else if (action_name == Mmark
720 || action_name == Mcall
721 || action_name == Mshift)
723 if (! MPLIST_SYMBOL_P (pl))
724 MERROR (MERROR_IM, -1);
726 else if (action_name == Mundo)
728 if (! MPLIST_TAIL_P (pl))
730 if (! MPLIST_SYMBOL_P (pl)
731 && (! MPLIST_INTEGER_P (pl)
732 || MPLIST_INTEGER (pl) == 0))
733 MERROR (MERROR_IM, -1);
736 else if (action_name == Mpushback)
738 if (MPLIST_MTEXT_P (pl))
740 MText *mt = MPLIST_MTEXT (pl);
742 if (mtext_nchars (mt) != mtext_nbytes (mt))
743 MERROR (MERROR_IM, -1);
745 else if (MPLIST_PLIST_P (pl))
749 MPLIST_DO (p, MPLIST_PLIST (pl))
750 if (! MPLIST_SYMBOL_P (p))
751 MERROR (MERROR_IM, -1);
753 else if (! MPLIST_INTEGER_P (pl))
754 MERROR (MERROR_IM, -1);
756 else if (action_name == Mset || action_name == Madd
757 || action_name == Msub || action_name == Mmul
758 || action_name == Mdiv)
760 if (! (MPLIST_SYMBOL_P (pl)
761 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
762 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
763 MERROR (MERROR_IM, -1);
765 else if (action_name == Mequal || action_name == Mless
766 || action_name == Mgreater)
768 if (! ((MPLIST_INTEGER_P (pl) || MPLIST_SYMBOL_P (pl))
769 && (MPLIST_INTEGER_P (MPLIST_NEXT (pl))
770 || MPLIST_SYMBOL_P (MPLIST_NEXT (pl)))))
771 MERROR (MERROR_IM, -1);
772 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
773 if (! MPLIST_PLIST_P (pl))
774 MERROR (MERROR_IM, -1);
775 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
776 MERROR (MERROR_IM, -1);
777 pl = MPLIST_NEXT (pl);
778 if (MPLIST_PLIST_P (pl)
779 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
780 MERROR (MERROR_IM, -1);
782 else if (action_name == Mshow || action_name == Mhide
783 || action_name == Mcommit || action_name == Munhandle)
785 else if (! macros || ! mplist_get (macros, action_name))
786 MERROR (MERROR_IM, -1);
789 MERROR (MERROR_IM, -1);
796 resolve_command (MSymbol language, MSymbol name, MSymbol command)
798 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
801 || ! (plist = mplist_get (plist, command)))
803 plist = MPLIST_NEXT (plist);
804 if (! MPLIST_PLIST_P (plist))
811 /* Load a translation into MAP from PLIST.
813 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
816 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
817 MPlist *branch_actions, MPlist *macros)
822 if (MPLIST_MTEXT_P (keylist))
824 MText *mt = MPLIST_MTEXT (keylist);
826 len = mtext_nchars (mt);
827 if (len == 0 || len != mtext_nbytes (mt))
828 MERROR (MERROR_IM, -1);
829 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
830 for (i = 0; i < len; i++)
831 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
833 else if (MPLIST_PLIST_P (keylist))
835 MPlist *elt = MPLIST_PLIST (keylist);
837 len = MPLIST_LENGTH (elt);
839 MERROR (MERROR_IM, -1);
840 keyseq = (MSymbol *) alloca (sizeof (int) * len);
841 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
843 if (MPLIST_INTEGER_P (elt))
845 int c = MPLIST_INTEGER (elt);
847 if (c < 0 || c >= 0x100)
848 MERROR (MERROR_IM, -1);
849 keyseq[i] = one_char_symbol[c];
851 else if (MPLIST_SYMBOL_P (elt))
852 keyseq[i] = MPLIST_SYMBOL (elt);
854 MERROR (MERROR_IM, -1);
858 MERROR (MERROR_IM, -1);
860 for (i = 0; i < len; i++)
862 MIMMap *deeper = NULL;
865 deeper = mplist_get (map->submaps, keyseq[i]);
867 map->submaps = mplist ();
870 /* Fixme: It is better to make all deeper maps at once. */
871 MSTRUCT_CALLOC (deeper, MERROR_IM);
872 mplist_put (map->submaps, keyseq[i], deeper);
877 /* We reach a terminal map. */
879 || map->branch_actions)
880 /* This map is already defined. We avoid overriding it. */
883 if (! MPLIST_TAIL_P (map_actions))
885 if (parse_action_list (map_actions, macros) < 0)
886 MERROR (MERROR_IM, -1);
887 map->map_actions = map_actions;
891 map->branch_actions = branch_actions;
892 M17N_OBJECT_REF (branch_actions);
898 /* Load a branch from PLIST into MAP. PLIST has this form:
899 PLIST ::= ( MAP-NAME BRANCH-ACTION * )
900 MAPS is a plist of raw maps.
901 STATE is the current state. */
904 load_branch (MPlist *plist, MPlist *maps, MIMMap *map,
905 MSymbol language, MSymbol name, MPlist *macros)
908 MPlist *branch_actions;
910 if (! MPLIST_SYMBOL_P (plist))
911 MERROR (MERROR_IM, -1);
912 map_name = MPLIST_SYMBOL (plist);
913 plist = MPLIST_NEXT (plist);
914 if (MPLIST_TAIL_P (plist))
915 branch_actions = NULL;
916 else if (parse_action_list (plist, macros) < 0)
917 MERROR (MERROR_IM, -1);
919 branch_actions = plist;
920 if (map_name == Mnil)
922 map->branch_actions = branch_actions;
924 M17N_OBJECT_REF (branch_actions);
926 else if (map_name == Mt)
928 map->map_actions = branch_actions;
930 M17N_OBJECT_REF (branch_actions);
932 else if ((plist = (MPlist *) mplist_get (maps, map_name)))
934 MPLIST_DO (plist, plist)
936 MPlist *keylist, *map_actions;
938 if (! MPLIST_PLIST_P (plist))
939 MERROR (MERROR_IM, -1);
940 keylist = MPLIST_PLIST (plist);
941 map_actions = MPLIST_NEXT (keylist);
942 if (MPLIST_SYMBOL_P (keylist))
944 MSymbol command = MPLIST_SYMBOL (keylist);
945 MPlist *pl = resolve_command (language, name, command);
950 if (load_translation (map, pl, map_actions, branch_actions,
952 MERROR (MERROR_IM, -1);
955 if (load_translation (map, keylist, map_actions, branch_actions,
957 MERROR (MERROR_IM, -1);
964 /* Load a macro from PLIST into MACROS.
966 PLIST ::= ( MACRO-NAME ACTION * )
967 MACROS is a plist of macro names vs action list. */
969 load_macros (MPlist *plist, MPlist *macros)
973 if (! MPLIST_SYMBOL_P (plist))
974 MERROR (MERROR_IM, -1);
975 name = MPLIST_SYMBOL (plist);
976 plist = MPLIST_NEXT (plist);
977 if (MPLIST_TAIL_P (plist)
978 || parse_action_list (plist, macros) < 0)
979 MERROR (MERROR_IM, -1);
980 mplist_put (macros, name, plist);
981 M17N_OBJECT_REF (plist);
985 /* Load an external module from PLIST into EXTERNALS.
987 PLIST ::= ( MODULE-NAME FUNCTION * )
988 EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */
991 load_external_module (MPlist *plist, MPlist *externals)
996 MIMExternalModule *external;
1000 if (MPLIST_MTEXT_P (plist))
1001 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1002 else if (MPLIST_SYMBOL_P (plist))
1003 module = MPLIST_SYMBOL (plist);
1004 module_file = alloca (strlen (MSYMBOL_NAME (module))
1005 + strlen (DLOPEN_SHLIB_EXT) + 1);
1006 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1008 handle = dlopen (module_file, RTLD_NOW);
1011 fprintf (stderr, "%s\n", dlerror ());
1012 MERROR (MERROR_IM, -1);
1014 func_list = mplist ();
1015 MPLIST_DO (plist, MPLIST_NEXT (plist))
1017 if (! MPLIST_SYMBOL_P (plist))
1018 MERROR_GOTO (MERROR_IM, err_label);
1019 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1021 MERROR_GOTO (MERROR_IM, err_label);
1022 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1025 MSTRUCT_MALLOC (external, MERROR_IM);
1026 external->handle = handle;
1027 external->func_list = func_list;
1028 mplist_add (externals, module, external);
1033 M17N_OBJECT_UNREF (func_list);
1038 free_map (MIMMap *map, int top)
1043 M17N_OBJECT_UNREF (map->map_actions);
1046 MPLIST_DO (plist, map->submaps)
1047 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1048 M17N_OBJECT_UNREF (map->submaps);
1050 M17N_OBJECT_UNREF (map->branch_actions);
1055 free_state (void *object)
1057 MIMState *state = object;
1060 M17N_OBJECT_UNREF (state->title);
1062 free_map (state->map, 1);
1066 /** Load a state from PLIST into a newly allocated state object.
1067 PLIST has this form:
1068 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1069 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1070 MAPS is a plist of defined maps.
1071 Return the state object. */
1074 load_state (MPlist *plist, MPlist *maps, MSymbol language, MSymbol name,
1079 if (! MPLIST_SYMBOL_P (plist))
1080 MERROR (MERROR_IM, NULL);
1081 M17N_OBJECT (state, free_state, MERROR_IM);
1082 state->name = MPLIST_SYMBOL (plist);
1083 plist = MPLIST_NEXT (plist);
1084 if (MPLIST_MTEXT_P (plist))
1086 state->title = MPLIST_MTEXT (plist);
1087 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1088 Mlanguage, language);
1089 M17N_OBJECT_REF (state->title);
1090 plist = MPLIST_NEXT (plist);
1092 MSTRUCT_CALLOC (state->map, MERROR_IM);
1093 MPLIST_DO (plist, plist)
1094 if (! MPLIST_PLIST_P (plist)
1095 || load_branch (MPLIST_PLIST (plist), maps, state->map, language, name,
1097 MERROR (MERROR_IM, NULL);
1102 static MPlist *im_info_list;
1105 free_im_info (MInputMethodInfo *im_info)
1110 M17N_OBJECT_UNREF (im_info->title);
1111 if (im_info->states)
1113 MPLIST_DO (plist, im_info->states)
1115 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1117 M17N_OBJECT_UNREF (state);
1119 M17N_OBJECT_UNREF (im_info->states);
1122 if (im_info->macros)
1124 MPLIST_DO (plist, im_info->macros)
1125 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1126 M17N_OBJECT_UNREF (im_info->macros);
1129 if (im_info->externals)
1131 MPLIST_DO (plist, im_info->externals)
1133 MIMExternalModule *external = MPLIST_VAL (plist);
1135 dlclose (external->handle);
1136 M17N_OBJECT_UNREF (external->func_list);
1138 MPLIST_KEY (plist) = Mt;
1140 M17N_OBJECT_UNREF (im_info->externals);
1144 MPLIST_DO (plist, im_info->maps)
1146 MPlist *p = MPLIST_PLIST (plist);
1148 M17N_OBJECT_UNREF (p);
1150 M17N_OBJECT_UNREF (im_info->maps);
1156 static MInputMethodInfo *get_im_info (MSymbol language, MSymbol name,
1159 static MInputMethodInfo *
1160 get_im_info_by_tags (MPlist *plist)
1165 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1166 i++, plist = MPLIST_NEXT (plist))
1167 tag[i] = MPLIST_SYMBOL (plist);
1172 return get_im_info (tag[0], tag[1], tag[2]);
1175 /* Load an input method from PLIST into IM_INTO, and return it. */
1177 static MInputMethodInfo *
1178 load_im_info (MSymbol language, MSymbol name, MPlist *plist)
1180 MInputMethodInfo *im_info;
1181 MText *title = NULL;
1182 MPlist *maps = NULL;
1183 MPlist *states = NULL;
1184 MPlist *externals = NULL;
1185 MPlist *macros = NULL;
1188 MSTRUCT_CALLOC (im_info, MERROR_IM);
1190 while (MPLIST_PLIST_P (plist))
1192 elt = MPLIST_PLIST (plist);
1193 if (! MPLIST_SYMBOL_P (elt))
1194 MERROR_GOTO (MERROR_IM, err);
1195 if (MPLIST_SYMBOL (elt) == Mtitle)
1197 elt = MPLIST_NEXT (elt);
1198 if (! MPLIST_MTEXT_P (elt))
1199 MERROR_GOTO (MERROR_IM, err);
1200 im_info->title = title = MPLIST_MTEXT (elt);
1201 M17N_OBJECT_REF (title);
1203 else if (MPLIST_SYMBOL (elt) == Mmap)
1205 MPlist *pl = mplist__from_alist (MPLIST_NEXT (elt));
1208 MERROR_GOTO (MERROR_IM, err);
1210 im_info->maps = maps = pl;
1212 maps = mplist__conc (maps, pl);
1214 else if (MPLIST_SYMBOL (elt) == Mmacro)
1217 im_info->macros = macros = mplist ();
1218 MPLIST_DO (elt, MPLIST_NEXT (elt))
1220 if (! MPLIST_PLIST_P (elt)
1221 || load_macros (MPLIST_PLIST (elt), macros) < 0)
1222 MERROR_GOTO (MERROR_IM, err);
1225 else if (MPLIST_SYMBOL (elt) == Mmodule)
1228 im_info->externals = externals = mplist ();
1229 MPLIST_DO (elt, MPLIST_NEXT (elt))
1231 if (! MPLIST_PLIST_P (elt)
1232 || load_external_module (MPLIST_PLIST (elt), externals) < 0)
1233 MERROR_GOTO (MERROR_IM, err);
1236 else if (MPLIST_SYMBOL (elt) == Mstate)
1238 MPLIST_DO (elt, MPLIST_NEXT (elt))
1242 if (! MPLIST_PLIST_P (elt))
1243 MERROR_GOTO (MERROR_IM, err);
1244 state = load_state (MPLIST_PLIST (elt), maps, language, name,
1247 MERROR_GOTO (MERROR_IM, err);
1249 im_info->states = states = mplist ();
1250 mplist_put (states, state->name, state);
1253 else if (MPLIST_SYMBOL (elt) == Minclude)
1255 /* elt ::= include (tag1 tag2 ...) key item ... */
1257 MInputMethodInfo *temp;
1260 elt = MPLIST_NEXT (elt);
1261 if (! MPLIST_PLIST_P (elt))
1262 MERROR_GOTO (MERROR_IM, err);
1263 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
1265 MERROR_GOTO (MERROR_IM, err);
1266 elt = MPLIST_NEXT (elt);
1267 if (! MPLIST_SYMBOL_P (elt))
1268 MERROR_GOTO (MERROR_IM, err);
1269 key = MPLIST_SYMBOL (elt);
1270 elt = MPLIST_NEXT (elt);
1274 im_info->maps = maps = mplist ();
1275 MPLIST_DO (pl, temp->maps)
1277 p = MPLIST_VAL (pl);
1278 MPLIST_ADD_PLIST (maps, MPLIST_KEY (pl), p);
1279 M17N_OBJECT_REF (p);
1282 else if (key == Mmacro)
1285 im_info->macros = macros = mplist ();
1286 MPLIST_DO (pl, temp->macros)
1288 p = MPLIST_VAL (pl);
1289 MPLIST_ADD_PLIST (macros, MPLIST_KEY (pl), p);
1290 M17N_OBJECT_REF (p);
1293 else if (key == Mstate)
1296 im_info->states = states = mplist ();
1297 MPLIST_DO (pl, temp->states)
1299 MIMState *state = MPLIST_VAL (pl);
1301 mplist_add (states, MPLIST_KEY (pl), state);
1302 M17N_OBJECT_REF (state);
1306 MERROR_GOTO (MERROR_IM, err);
1308 plist = MPLIST_NEXT (plist);
1313 if (! title && name)
1315 = title = mtext_from_data (MSYMBOL_NAME (name), MSYMBOL_NAMELEN (name),
1316 MTEXT_FORMAT_US_ASCII);
1320 free_im_info (im_info);
1326 static int take_action_list (MInputContext *ic, MPlist *action_list);
1327 static void preedit_commit (MInputContext *ic);
1330 shift_state (MInputContext *ic, MSymbol state_name)
1332 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
1333 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1334 MIMState *orig_state = ic_info->state, *state;
1336 /* Find a state to shift to. If not found, shift to the initial
1338 if (state_name == Mt)
1340 if (! ic_info->prev_state)
1342 state = ic_info->prev_state;
1346 state = (MIMState *) mplist_get (im_info->states, state_name);
1348 state = (MIMState *) MPLIST_VAL (im_info->states);
1351 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
1353 /* Enter the new state. */
1354 ic_info->state = state;
1355 ic_info->map = state->map;
1356 ic_info->state_key_head = ic_info->key_head;
1357 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1358 /* We have shifted to the initial state. */
1359 preedit_commit (ic);
1360 mtext_cpy (ic_info->preedit_saved, ic->preedit);
1361 ic_info->state_pos = ic->cursor_pos;
1362 if (state != orig_state )
1364 if (state == (MIMState *) MPLIST_VAL (im_info->states))
1365 ic_info->prev_state = NULL;
1367 ic_info->prev_state = orig_state;
1370 ic->status = state->title;
1372 ic->status = im_info->title;
1373 ic->status_changed = 1;
1374 if (ic_info->map == ic_info->state->map
1375 && ic_info->map->map_actions)
1377 MDEBUG_PRINT (" init-actions:");
1378 take_action_list (ic, ic_info->map->map_actions);
1383 /* Find a candidate group that contains a candidate number INDEX from
1384 PLIST. Set START_INDEX to the first candidate number of the group,
1385 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
1386 candidate group number if they are non-NULL. If INDEX is -1, find
1387 the last candidate group. */
1390 find_candidates_group (MPlist *plist, int index,
1391 int *start_index, int *end_index, int *group_index)
1393 int i = 0, gidx = 0, len;
1395 MPLIST_DO (plist, plist)
1397 if (MPLIST_MTEXT_P (plist))
1398 len = mtext_nchars (MPLIST_MTEXT (plist));
1400 len = mplist_length (MPLIST_PLIST (plist));
1401 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
1407 *end_index = i + len;
1409 *group_index = gidx;
1419 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
1421 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1423 int nchars = mt ? mtext_nchars (mt) : 1;
1426 mtext_ins (ic->preedit, pos, mt);
1428 mtext_ins_char (ic->preedit, pos, c, 1);
1429 MPLIST_DO (markers, ic_info->markers)
1430 if (MPLIST_INTEGER (markers) > pos)
1431 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
1432 if (ic->cursor_pos >= pos)
1433 ic->cursor_pos += nchars;
1434 ic->preedit_changed = 1;
1439 preedit_delete (MInputContext *ic, int from, int to)
1441 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
1444 mtext_del (ic->preedit, from, to);
1445 MPLIST_DO (markers, ic_info->markers)
1447 if (MPLIST_INTEGER (markers) > to)
1448 MPLIST_VAL (markers)
1449 = (void *) (MPLIST_INTEGER (markers) - (to - from));
1450 else if (MPLIST_INTEGER (markers) > from);
1451 MPLIST_VAL (markers) = (void *) from;
1453 if (ic->cursor_pos >= to)
1454 ic->cursor_pos -= to - from;
1455 else if (ic->cursor_pos > from)
1456 ic->cursor_pos = from;
1457 ic->preedit_changed = 1;
1461 preedit_commit (MInputContext *ic)
1463 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1464 int preedit_len = mtext_nchars (ic->preedit);
1466 if (preedit_len > 0)
1470 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1471 Mcandidate_list, NULL, 0);
1472 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
1473 Mcandidate_index, NULL, 0);
1474 mtext_cat (ic->produced, ic->preedit);
1475 if ((mdebug__flag & mdebug_mask)
1476 && mtext_nchars (ic->produced) > 0)
1480 MDEBUG_PRINT (" (produced");
1481 for (i = 0; i < mtext_nchars (ic->produced); i++)
1482 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
1485 mtext_reset (ic->preedit);
1486 mtext_reset (ic_info->preedit_saved);
1487 MPLIST_DO (p, ic_info->markers)
1489 ic->cursor_pos = ic_info->state_pos = 0;
1490 ic->preedit_changed = 1;
1492 if (ic->candidate_list)
1494 M17N_OBJECT_UNREF (ic->candidate_list);
1495 ic->candidate_list = NULL;
1496 ic->candidate_show = 0;
1497 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
1498 if (ic->candidate_show)
1500 ic->candidate_show = 0;
1501 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
1505 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
1506 sizeof (int) * (ic_info->used - ic_info->key_head));
1507 ic_info->used -= ic_info->key_head;
1508 ic_info->state_key_head = ic_info->key_head = 0;
1512 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
1514 int code = marker_code (sym);
1516 if (mt && (code == '[' || code == ']'))
1520 if (code == '[' && current > 0)
1522 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
1526 else if (code == ']' && current < mtext_nchars (mt))
1528 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
1534 return (code == '<' ? 0
1535 : code == '>' ? limit
1536 : code == '-' ? current - 1
1537 : code == '+' ? current + 1
1538 : code == '=' ? current
1539 : code - '0' > limit ? limit
1543 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
1547 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
1549 int from = mtext_property_start (prop);
1550 int to = mtext_property_end (prop);
1552 MPlist *candidate_list = mtext_property_value (prop);
1553 MPlist *group = find_candidates_group (candidate_list, idx, &start,
1555 int ingroup_index = idx - start;
1558 preedit_delete (ic, from, to);
1559 if (MPLIST_MTEXT_P (group))
1561 mt = MPLIST_MTEXT (group);
1562 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
1570 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
1571 i++, plist = MPLIST_NEXT (plist));
1572 mt = MPLIST_MTEXT (plist);
1573 preedit_insert (ic, from, mt, 0);
1574 to = from + mtext_nchars (mt);
1576 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
1577 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
1578 ic->cursor_pos = to;
1582 get_select_charset (MInputContextInfo * ic_info)
1584 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
1587 if (! MPLIST_VAL (plist))
1589 sym = MPLIST_SYMBOL (plist);
1592 return MCHARSET (sym);
1596 adjust_candidates (MPlist *plist, MCharset *charset)
1600 /* plist ::= MTEXT ... | PLIST ... */
1601 plist = mplist_copy (plist);
1602 if (MPLIST_MTEXT_P (plist))
1605 while (! MPLIST_TAIL_P (pl))
1607 /* pl ::= MTEXT ... */
1608 MText *mt = MPLIST_MTEXT (pl);
1612 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1614 c = mtext_ref_char (mt, i);
1615 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1619 mt = mtext_dup (mt);
1620 mplist_set (pl, Mtext, mt);
1621 M17N_OBJECT_UNREF (mt);
1624 mtext_del (mt, i, i + 1);
1627 if (mtext_len (mt) > 0)
1628 pl = MPLIST_NEXT (pl);
1632 M17N_OBJECT_UNREF (mt);
1636 else /* MPLIST_PLIST_P (plist) */
1639 while (! MPLIST_TAIL_P (pl))
1641 /* pl ::= (MTEXT ...) ... */
1642 MPlist *p = MPLIST_PLIST (pl);
1644 /* p ::= MTEXT ... */
1648 while (! MPLIST_TAIL_P (p0))
1650 MText *mt = MPLIST_MTEXT (p0);
1653 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
1655 c = mtext_ref_char (mt, i);
1656 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
1661 p0 = MPLIST_NEXT (p0);
1668 p = mplist_copy (p);
1669 mplist_set (pl, Mplist, p);
1670 M17N_OBJECT_UNREF (p);
1674 p0 = MPLIST_NEXT (p0);
1677 M17N_OBJECT_UNREF (mt);
1680 if (! MPLIST_TAIL_P (p))
1681 pl = MPLIST_NEXT (pl);
1685 M17N_OBJECT_UNREF (p);
1689 if (MPLIST_TAIL_P (plist))
1691 M17N_OBJECT_UNREF (plist);
1698 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
1700 MCharset *charset = get_select_charset (ic_info);
1705 plist = resolve_variable (ic_info, Mcandidates_group_size);
1706 column = MPLIST_INTEGER (plist);
1708 plist = MPLIST_PLIST (args);
1711 if (! (plist = adjust_candidates (plist, charset)))
1715 M17N_OBJECT_REF (plist);
1719 if (MPLIST_MTEXT_P (plist))
1721 MText *mt = MPLIST_MTEXT (plist);
1722 MPlist *next = MPLIST_NEXT (plist);
1724 if (MPLIST_TAIL_P (next))
1725 M17N_OBJECT_REF (mt);
1728 mt = mtext_dup (mt);
1729 while (! MPLIST_TAIL_P (next))
1731 mt = mtext_cat (mt, MPLIST_MTEXT (next));
1732 next = MPLIST_NEXT (next);
1735 M17N_OBJECT_UNREF (plist);
1737 len = mtext_nchars (mt);
1739 mplist_add (plist, Mtext, mt);
1742 for (i = 0; i < len; i += column)
1744 int to = (i + column < len ? i + column : len);
1745 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
1747 mplist_add (plist, Mtext, sub);
1748 M17N_OBJECT_UNREF (sub);
1751 M17N_OBJECT_UNREF (mt);
1753 else /* MPLIST_PLIST_P (plist) */
1755 MPlist *pl = MPLIST_PLIST (plist), *p;
1756 MPlist *next = MPLIST_NEXT (plist);
1759 if (MPLIST_TAIL_P (next))
1760 M17N_OBJECT_REF (pl);
1763 pl = mplist_copy (pl);
1764 while (! MPLIST_TAIL_P (next))
1766 p = mplist_copy (MPLIST_PLIST (next));
1767 pl = mplist__conc (pl, p);
1768 M17N_OBJECT_UNREF (p);
1769 next = MPLIST_NEXT (next);
1772 M17N_OBJECT_UNREF (plist);
1774 len = mplist_length (pl);
1776 mplist_add (plist, Mplist, pl);
1781 for (i = 0; i < len; i += column)
1784 mplist_add (plist, Mplist, p);
1785 M17N_OBJECT_UNREF (p);
1786 for (j = 0; j < column && i + j < len; j++)
1788 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
1789 p0 = MPLIST_NEXT (p0);
1793 M17N_OBJECT_UNREF (pl);
1802 regularize_action (MPlist *action_list)
1804 MPlist *action = NULL;
1808 if (MPLIST_PLIST_P (action_list))
1810 action = MPLIST_PLIST (action_list);
1811 if (MPLIST_SYMBOL_P (action))
1813 name = MPLIST_SYMBOL (action);
1814 args = MPLIST_NEXT (action);
1816 && MPLIST_PLIST_P (args))
1817 mplist_set (action, Msymbol, M_candidates);
1819 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
1822 mplist_push (action, Mplist, MPLIST_VAL (action_list));
1823 mplist_push (action, Msymbol, M_candidates);
1824 mplist_set (action_list, Mplist, action);
1825 M17N_OBJECT_UNREF (action);
1828 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
1831 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
1832 mplist_push (action, Msymbol, Minsert);
1833 mplist_set (action_list, Mplist, action);
1834 M17N_OBJECT_UNREF (action);
1840 take_action_list (MInputContext *ic, MPlist *action_list)
1842 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
1843 MPlist *candidate_list = ic->candidate_list;
1844 int candidate_index = ic->candidate_index;
1845 int candidate_show = ic->candidate_show;
1846 MTextProperty *prop;
1848 MPLIST_DO (action_list, action_list)
1850 MPlist *action = regularize_action (action_list);
1856 name = MPLIST_SYMBOL (action);
1857 args = MPLIST_NEXT (action);
1859 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
1860 if (name == Minsert)
1862 if (MPLIST_SYMBOL_P (args))
1864 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
1865 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
1868 if (MPLIST_MTEXT_P (args))
1869 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
1870 else /* MPLIST_INTEGER_P (args)) */
1871 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
1873 else if (name == M_candidates)
1875 MPlist *plist = get_candidate_list (ic_info, args);
1880 if (MPLIST_MTEXT_P (plist))
1882 preedit_insert (ic, ic->cursor_pos, NULL,
1883 mtext_ref_char (MPLIST_MTEXT (plist), 0));
1888 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
1890 preedit_insert (ic, ic->cursor_pos, mt, 0);
1891 len = mtext_nchars (mt);
1893 mtext_put_prop (ic->preedit,
1894 ic->cursor_pos - len, ic->cursor_pos,
1895 Mcandidate_list, plist);
1896 mtext_put_prop (ic->preedit,
1897 ic->cursor_pos - len, ic->cursor_pos,
1898 Mcandidate_index, (void *) 0);
1899 M17N_OBJECT_UNREF (plist);
1901 else if (name == Mselect)
1904 int code, idx, gindex;
1905 int pos = ic->cursor_pos;
1909 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
1912 if (MPLIST_SYMBOL_P (args))
1914 code = marker_code (MPLIST_SYMBOL (args));
1920 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
1921 group = find_candidates_group (mtext_property_value (prop), idx,
1922 &start, &end, &gindex);
1924 if (code != '[' && code != ']')
1928 ? new_index (NULL, ic->candidate_index - start,
1929 end - start - 1, MPLIST_SYMBOL (args),
1931 : MPLIST_INTEGER (args)));
1934 find_candidates_group (mtext_property_value (prop), -1,
1939 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
1944 int ingroup_index = idx - start;
1947 group = mtext_property_value (prop);
1948 len = mplist_length (group);
1961 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
1962 idx += (MPLIST_MTEXT_P (group)
1963 ? mtext_nchars (MPLIST_MTEXT (group))
1964 : mplist_length (MPLIST_PLIST (group)));
1965 len = (MPLIST_MTEXT_P (group)
1966 ? mtext_nchars (MPLIST_MTEXT (group))
1967 : mplist_length (MPLIST_PLIST (group)));
1968 if (ingroup_index >= len)
1969 ingroup_index = len - 1;
1970 idx += ingroup_index;
1972 update_candidate (ic, prop, idx);
1974 else if (name == Mshow)
1975 ic->candidate_show = 1;
1976 else if (name == Mhide)
1977 ic->candidate_show = 0;
1978 else if (name == Mdelete)
1980 int len = mtext_nchars (ic->preedit);
1984 if (MPLIST_SYMBOL_P (args)
1985 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
1987 delete_surrounding_text (ic, pos);
1991 to = (MPLIST_SYMBOL_P (args)
1992 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
1994 : MPLIST_INTEGER (args));
1999 if (to < ic->cursor_pos)
2000 preedit_delete (ic, to, ic->cursor_pos);
2001 else if (to > ic->cursor_pos)
2002 preedit_delete (ic, ic->cursor_pos, to);
2005 else if (name == Mmove)
2007 int len = mtext_nchars (ic->preedit);
2009 = (MPLIST_SYMBOL_P (args)
2010 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2012 : MPLIST_INTEGER (args));
2018 if (pos != ic->cursor_pos)
2020 ic->cursor_pos = pos;
2021 ic->preedit_changed = 1;
2024 else if (name == Mmark)
2026 int code = marker_code (MPLIST_SYMBOL (args));
2029 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
2030 (void *) ic->cursor_pos);
2032 else if (name == Mpushback)
2034 if (MPLIST_INTEGER_P (args))
2036 int num = MPLIST_INTEGER (args);
2039 ic_info->key_head -= num;
2041 ic_info->key_head = num;
2042 if (ic_info->key_head > ic_info->used)
2043 ic_info->key_head = ic_info->used;
2045 else if (MPLIST_MTEXT_P (args))
2047 MText *mt = MPLIST_MTEXT (args);
2048 int i, len = mtext_nchars (mt);
2051 ic_info->key_head--;
2052 for (i = 0; i < len; i++)
2054 key = one_char_symbol[MTEXT_DATA (mt)[i]];
2055 if (ic_info->key_head + i < ic_info->used)
2056 ic_info->keys[ic_info->key_head + i] = key;
2058 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2063 MPlist *plist = MPLIST_PLIST (args), *pl;
2067 ic_info->key_head--;
2069 MPLIST_DO (pl, plist)
2071 key = MPLIST_SYMBOL (pl);
2072 if (ic_info->key_head < ic_info->used)
2073 ic_info->keys[ic_info->key_head + i] = key;
2075 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2080 else if (name == Mcall)
2082 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2083 MIMExternalFunc func = NULL;
2084 MSymbol module, func_name;
2085 MPlist *func_args, *val;
2088 module = MPLIST_SYMBOL (args);
2089 args = MPLIST_NEXT (args);
2090 func_name = MPLIST_SYMBOL (args);
2092 if (im_info->externals)
2094 MIMExternalModule *external
2095 = (MIMExternalModule *) mplist_get (im_info->externals,
2098 func = (MIMExternalFunc) mplist_get (external->func_list,
2103 func_args = mplist ();
2104 mplist_add (func_args, Mt, ic);
2105 MPLIST_DO (args, MPLIST_NEXT (args))
2109 if (MPLIST_KEY (args) == Msymbol
2110 && MPLIST_KEY (args) != Mnil
2111 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
2113 code = new_index (ic, ic->cursor_pos,
2114 mtext_nchars (ic->preedit),
2115 MPLIST_SYMBOL (args), ic->preedit);
2116 mplist_add (func_args, Minteger, (void *) code);
2119 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
2121 val = (func) (func_args);
2122 M17N_OBJECT_UNREF (func_args);
2123 if (val && ! MPLIST_TAIL_P (val))
2124 ret = take_action_list (ic, val);
2125 M17N_OBJECT_UNREF (val);
2129 else if (name == Mshift)
2131 shift_state (ic, MPLIST_SYMBOL (args));
2133 else if (name == Mundo)
2135 int intarg = (MPLIST_TAIL_P (args)
2137 : integer_value (ic, args, NULL, 0));
2139 mtext_reset (ic->preedit);
2140 mtext_reset (ic_info->preedit_saved);
2141 ic->cursor_pos = ic_info->state_pos = 0;
2142 ic_info->state_key_head = ic_info->key_head = 0;
2145 ic_info->used += intarg;
2147 ic_info->used = intarg;
2148 shift_state (ic, Mnil);
2151 else if (name == Mset || name == Madd || name == Msub
2152 || name == Mmul || name == Mdiv)
2154 MSymbol sym = MPLIST_SYMBOL (args);
2159 val1 = integer_value (ic, args, &value, 0);
2160 args = MPLIST_NEXT (args);
2161 val2 = integer_value (ic, args, NULL, 1);
2163 val1 = val2, op = "=";
2164 else if (name == Madd)
2165 val1 += val2, op = "+=";
2166 else if (name == Msub)
2167 val1 -= val2, op = "-=";
2168 else if (name == Mmul)
2169 val1 *= val2, op = "*=";
2171 val1 /= val2, op = "/=";
2172 MDEBUG_PRINT3 ("(%s %s %d)", MSYMBOL_NAME (sym), op, val1);
2174 mplist_set (value, Minteger, (void *) val1);
2176 else if (name == Mequal || name == Mless || name == Mgreater)
2179 MPlist *actions1, *actions2;
2182 val1 = integer_value (ic, args, NULL, 1);
2183 args = MPLIST_NEXT (args);
2184 val2 = integer_value (ic, args, NULL, 1);
2185 args = MPLIST_NEXT (args);
2186 actions1 = MPLIST_PLIST (args);
2187 args = MPLIST_NEXT (args);
2188 if (MPLIST_TAIL_P (args))
2191 actions2 = MPLIST_PLIST (args);
2192 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
2193 if (name == Mequal ? val1 == val2
2194 : name == Mless ? val1 < val2
2197 MDEBUG_PRINT ("ok");
2198 ret = take_action_list (ic, actions1);
2202 MDEBUG_PRINT ("no");
2204 ret = take_action_list (ic, actions2);
2209 else if (name == Mcommit)
2211 preedit_commit (ic);
2213 else if (name == Munhandle)
2215 preedit_commit (ic);
2220 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2224 && (actions = mplist_get (im_info->macros, name)))
2226 if (take_action_list (ic, actions) < 0)
2233 if (ic->candidate_list)
2235 M17N_OBJECT_UNREF (ic->candidate_list);
2236 ic->candidate_list = NULL;
2238 if (ic->cursor_pos > 0
2239 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
2242 ic->candidate_list = mtext_property_value (prop);
2243 M17N_OBJECT_REF (ic->candidate_list);
2245 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
2247 ic->candidate_from = mtext_property_start (prop);
2248 ic->candidate_to = mtext_property_end (prop);
2251 if (candidate_list != ic->candidate_list)
2252 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
2253 if (candidate_index != ic->candidate_index)
2254 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
2255 if (candidate_show != ic->candidate_show)
2256 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2261 /* Handle the input key KEY in the current state and map specified in
2262 the input context IC. If KEY is handled correctly, return 0.
2263 Otherwise, return -1. */
2266 handle_key (MInputContext *ic)
2268 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2269 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2270 MIMMap *map = ic_info->map;
2271 MIMMap *submap = NULL;
2272 MSymbol key = ic_info->keys[ic_info->key_head];
2275 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
2276 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
2282 submap = mplist_get (map->submaps, key);
2283 if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
2284 submap = mplist_get (map->submaps, alias);
2289 MDEBUG_PRINT (" submap-found");
2290 mtext_cpy (ic->preedit, ic_info->preedit_saved);
2291 ic->preedit_changed = 1;
2292 ic->cursor_pos = ic_info->state_pos;
2293 ic_info->key_head++;
2294 ic_info->map = map = submap;
2295 if (map->map_actions)
2297 MDEBUG_PRINT (" map-actions:");
2298 if (take_action_list (ic, map->map_actions) < 0)
2300 MDEBUG_PRINT ("\n");
2304 else if (map->submaps)
2306 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
2308 MSymbol key = ic_info->keys[i];
2309 char *name = msymbol_name (key);
2311 if (! name[0] || ! name[1])
2312 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
2316 /* If this is the terminal map or we have shifted to another
2317 state, perform branch actions (if any). */
2318 if (! map->submaps || map != ic_info->map)
2320 if (map->branch_actions)
2322 MDEBUG_PRINT (" branch-actions:");
2323 if (take_action_list (ic, map->branch_actions) < 0)
2325 MDEBUG_PRINT ("\n");
2329 /* If MAP is still not the root map, shift to the current
2331 if (ic_info->map != ic_info->state->map)
2332 shift_state (ic, ic_info->state->name);
2337 /* MAP can not handle KEY. */
2339 /* If MAP is the root map of the initial state, it means that
2340 the current input method can not handle KEY. */
2341 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
2343 MDEBUG_PRINT (" unhandled\n");
2347 if (map != ic_info->state->map)
2349 /* If MAP is not the root map... */
2350 /* If MAP has branch actions, perform them. */
2351 if (map->branch_actions)
2353 MDEBUG_PRINT (" branch-actions:");
2354 if (take_action_list (ic, map->branch_actions) < 0)
2356 MDEBUG_PRINT ("\n");
2360 /* If MAP is still not the root map, shift to the current
2362 if (ic_info->map != ic_info->state->map)
2364 shift_state (ic, ic_info->state->name);
2365 /* If MAP has branch_actions, perform them. */
2366 if (ic_info->map->branch_actions)
2368 MDEBUG_PRINT (" brank-actions:");
2369 take_action_list (ic, ic_info->map->branch_actions);
2375 /* MAP is the root map, perform branch actions (if any) or
2376 shift to the initial state. */
2377 if (map->branch_actions)
2379 MDEBUG_PRINT (" branch-actions:");
2380 if (take_action_list (ic, map->branch_actions) < 0)
2382 MDEBUG_PRINT ("\n");
2387 shift_state (ic, Mnil);
2390 MDEBUG_PRINT ("\n");
2395 reset_ic (MInputContext *ic, MSymbol ignore)
2397 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2398 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2401 MDEBUG_PRINT ("\n [IM] reset\n");
2403 ic_info->state = (MIMState *) MPLIST_VAL (im_info->states);
2404 ic_info->prev_state = NULL;
2405 ic_info->map = ic_info->state->map;
2406 ic_info->state_key_head = ic_info->key_head;
2407 MLIST_RESET (ic_info);
2408 ic_info->key_unhandled = 0;
2410 if (mtext_nchars (ic->produced) > 0)
2411 mtext_reset (ic->produced);
2412 if (mtext_nchars (ic->preedit) > 0)
2416 mtext_reset (ic->preedit);
2417 MPLIST_DO (plist, ic_info->markers)
2418 MPLIST_VAL (plist) = 0;
2419 ic->preedit_changed = 1;
2421 if (ic->candidate_show)
2423 ic->candidate_show = 0;
2424 ic->candidates_changed = MINPUT_CANDIDATES_SHOW_CHANGED;
2425 if (ic->candidate_list)
2427 M17N_OBJECT_UNREF (ic->candidate_list);
2428 ic->candidate_list = NULL;
2429 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
2432 mtext_reset (ic_info->preedit_saved);
2433 ic_info->state_pos = ic->cursor_pos = 0;
2435 status = ic_info->state->title ? ic_info->state->title : im_info->title;
2436 if (ic->status != status)
2438 ic->status = status;
2439 ic->status_changed = 1;
2444 open_im (MInputMethod *im)
2446 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil);
2449 MERROR (MERROR_IM, -1);
2456 close_im (MInputMethod *im)
2462 create_ic (MInputContext *ic)
2464 MInputMethod *im = ic->im;
2465 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
2466 MInputContextInfo *ic_info;
2470 ic_info = (MInputContextInfo *) ic->info;
2473 MSTRUCT_CALLOC (ic_info, MERROR_IM);
2476 MLIST_INIT1 (ic_info, keys, 8);
2477 ic_info->markers = mplist ();
2478 ic_info->vars = mplist ();
2479 plist = get_nested_list (im->language, im->name, Mnil, M_variable);
2480 MPLIST_DO (plist, plist)
2482 MSymbol var = MPLIST_SYMBOL (plist);
2485 plist = MPLIST_NEXT (plist);
2486 pl = MPLIST_PLIST (plist);
2487 pl = MPLIST_NEXT (pl); /* Skip description. */
2488 mplist_push (ic_info->vars, MPLIST_KEY (pl), MPLIST_VAL (pl));
2489 mplist_push (ic_info->vars, Msymbol, var);
2492 ic_info->preedit_saved = mtext ();
2493 if (im_info->externals)
2495 MPlist *func_args = mplist (), *plist;
2497 mplist_add (func_args, Mt, ic);
2498 MPLIST_DO (plist, im_info->externals)
2500 MIMExternalModule *external = MPLIST_VAL (plist);
2501 MIMExternalFunc func
2502 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
2507 M17N_OBJECT_UNREF (func_args);
2509 reset_ic (ic, Mnil);
2514 destroy_ic (MInputContext *ic)
2516 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2517 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2519 if (im_info->externals)
2521 MPlist *func_args = mplist (), *plist;
2523 mplist_add (func_args, Mt, ic);
2524 MPLIST_DO (plist, im_info->externals)
2526 MIMExternalModule *external = MPLIST_VAL (plist);
2527 MIMExternalFunc func
2528 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
2533 M17N_OBJECT_UNREF (func_args);
2535 MLIST_FREE1 (ic_info, keys);
2536 M17N_OBJECT_UNREF (ic_info->preedit_saved);
2537 M17N_OBJECT_UNREF (ic_info->markers);
2538 M17N_OBJECT_UNREF (ic_info->vars);
2539 M17N_OBJECT_UNREF (ic_info->preceding_text);
2540 M17N_OBJECT_UNREF (ic_info->following_text);
2545 /** Handle the input key KEY in the current state and map of IC->info.
2546 If KEY is handled but no text is produced, return 0, otherwise
2552 filter (MInputContext *ic, MSymbol key, void *arg)
2554 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2555 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2558 if (! ic_info->state)
2560 ic_info->key_unhandled = 1;
2563 mtext_reset (ic->produced);
2564 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
2565 M17N_OBJECT_UNREF (ic_info->preceding_text);
2566 M17N_OBJECT_UNREF (ic_info->following_text);
2567 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2568 ic_info->key_unhandled = 0;
2570 if (handle_key (ic) < 0)
2572 /* KEY was not handled. Delete it from the current key sequence. */
2573 if (ic_info->used > 0)
2575 memmove (ic_info->keys, ic_info->keys + 1,
2576 sizeof (int) * (ic_info->used - 1));
2579 /* This forces returning 1. */
2580 ic_info->key_unhandled = 1;
2586 reset_ic (ic, Mnil);
2587 ic_info->key_unhandled = 1;
2590 /* Break the loop if all keys were handled. */
2591 } while (ic_info->key_head < ic_info->used);
2593 /* If the current map is the root of the initial state, we should
2594 produce any preedit text in ic->produced. */
2595 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
2596 && mtext_nchars (ic->preedit) > 0)
2597 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
2599 if (mtext_nchars (ic->produced) > 0)
2601 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
2604 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2605 Mlanguage, ic->im->language);
2608 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
2612 /** Return 1 if the last event or key was not handled, otherwise
2615 There is no need of looking up because ic->produced should already
2616 contain the produced text (if any).
2621 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2623 mtext_cat (mt, ic->produced);
2624 mtext_reset (ic->produced);
2625 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
2628 static MPlist *load_im_info_keys;
2631 load_partial_im_info (MSymbol language, MSymbol name,
2632 MSymbol extra, MSymbol key)
2637 if (language == Mnil)
2638 MERROR (MERROR_IM, NULL);
2639 mdb = mdatabase_find (Minput_method, language, name, extra);
2641 MERROR (MERROR_IM, NULL);
2643 mplist_push (load_im_info_keys, key, Mt);
2644 plist = mdatabase__load_for_keys (mdb, load_im_info_keys);
2645 mplist_pop (load_im_info_keys);
2650 static MInputMethodInfo *
2651 get_im_info (MSymbol language, MSymbol name, MSymbol extra)
2655 MInputMethodInfo *im_info = NULL;
2657 if (language == Mnil)
2658 MERROR (MERROR_IM, NULL);
2659 mdb = mdatabase_find (Minput_method, language, name, extra);
2661 MERROR (MERROR_IM, NULL);
2664 im_info_list = mplist ();
2665 else if ((plist = mplist_find_by_value (im_info_list, mdb)))
2667 if (mdatabase__check (mdb))
2669 plist = MPLIST_NEXT (plist);
2670 im_info = MPLIST_VAL (plist);
2674 free_im_info (MPLIST_VAL (plist));
2678 plist = mdatabase_load (mdb);
2680 MERROR (MERROR_IM, NULL);
2681 im_info = load_im_info (language, name, plist);
2682 M17N_OBJECT_UNREF (plist);
2684 MERROR (MERROR_IM, NULL);
2685 mplist_push (im_info_list, Mt, im_info);
2686 mplist_push (im_info_list, Mt, mdb);
2691 /* Input method command handler. */
2693 /* List of all (global and local) commands.
2694 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
2695 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
2696 Global commands are storead as (t (t COMMAND ...)) */
2698 /* Check if PLIST is a valid command key sequence.
2699 PLIST must be NULL or:
2700 [ symbol:KEY | integer:KEY ] ... */
2703 check_command_keyseq (MPlist *plist)
2707 MPLIST_DO (plist, plist)
2709 if (MPLIST_SYMBOL_P (plist))
2711 else if (MPLIST_INTEGER_P (plist))
2713 int n = MPLIST_INTEGER (plist);
2717 MPLIST_KEY (plist) = Msymbol;
2718 MPLIST_VAL (plist) = one_char_symbol['0' + 9];
2726 /* Check if PLIST has this form:
2727 ([ plist:([ symbol:KEY | integer:KEY ]) | mtext:KEYSEQ ]
2729 If the form of PLIST matches, return 0, otherwise return -1. */
2732 check_command_list (MPlist *plist)
2734 MPLIST_DO (plist, plist)
2736 if (MPLIST_PLIST_P (plist))
2738 MPlist *pl = MPLIST_PLIST (plist);
2741 if (! MPLIST_SYMBOL_P (pl) && ! MPLIST_INTEGER_P (pl))
2744 else if (! MPLIST_MTEXT_P (plist))
2752 /* Input method variable handler. */
2754 /* Check if PLIST has this form:
2755 (TYPE:VAL ;; TYPE ::= integer | mtext | symbol
2758 If the form of PLIST matches, return 0, otherwise return -1. */
2761 check_variable_list (MPlist *plist)
2763 MSymbol type = MPLIST_KEY (plist);
2766 if (type != Minteger && type != Mtext && type != Msymbol)
2768 MPLIST_DO (plist, MPLIST_NEXT (plist))
2770 if (type == Minteger && MPLIST_PLIST_P (plist))
2772 MPLIST_DO (p, MPLIST_PLIST (plist))
2773 if (! MPLIST_INTEGER_P (p))
2776 else if (type != MPLIST_KEY (plist))
2782 /* Support functions for mdebug_dump_im. */
2785 dump_im_map (MPlist *map_list, int indent)
2788 MSymbol key = MPLIST_KEY (map_list);
2789 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
2791 prefix = (char *) alloca (indent + 1);
2792 memset (prefix, 32, indent);
2793 prefix[indent] = '\0';
2795 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
2796 if (map->map_actions)
2797 mdebug_dump_plist (map->map_actions, indent + 2);
2800 MPLIST_DO (map_list, map->submaps)
2802 fprintf (stderr, "\n%s ", prefix);
2803 dump_im_map (map_list, indent + 2);
2806 if (map->branch_actions)
2808 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
2809 mdebug_dump_plist (map->branch_actions, indent + 4);
2810 fprintf (stderr, ")");
2812 fprintf (stderr, ")");
2817 dump_im_state (MIMState *state, int indent)
2822 prefix = (char *) alloca (indent + 1);
2823 memset (prefix, 32, indent);
2824 prefix[indent] = '\0';
2826 fprintf (stderr, "(%s", msymbol_name (state->name));
2827 if (state->map->submaps)
2829 MPLIST_DO (map_list, state->map->submaps)
2831 fprintf (stderr, "\n%s ", prefix);
2832 dump_im_map (map_list, indent + 2);
2835 fprintf (stderr, ")");
2844 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2845 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
2846 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2847 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
2848 char buf[6], buf2[256];
2852 Minput_method = msymbol ("input-method");
2853 Minput_driver = msymbol ("input-driver");
2854 Mtitle = msymbol ("title");
2855 Mmacro = msymbol ("macro");
2856 Mmodule = msymbol ("module");
2857 Mmap = msymbol ("map");
2858 Mstate = msymbol ("state");
2859 Minclude = msymbol ("include");
2860 Minsert = msymbol ("insert");
2861 M_candidates = msymbol (" candidates");
2862 Mdelete = msymbol ("delete");
2863 Mmove = msymbol ("move");
2864 Mmark = msymbol ("mark");
2865 Mpushback = msymbol ("pushback");
2866 Mundo = msymbol ("undo");
2867 Mcall = msymbol ("call");
2868 Mshift = msymbol ("shift");
2869 Mselect = msymbol ("select");
2870 Mshow = msymbol ("show");
2871 Mhide = msymbol ("hide");
2872 Mcommit = msymbol ("commit");
2873 Munhandle = msymbol ("unhandle");
2874 Mset = msymbol ("set");
2875 Madd = msymbol ("add");
2876 Msub = msymbol ("sub");
2877 Mmul = msymbol ("mul");
2878 Mdiv = msymbol ("div");
2879 Mequal = msymbol ("=");
2880 Mless = msymbol ("<");
2881 Mgreater = msymbol (">");
2883 Mcandidates_group_size = msymbol ("candidates-group-size");
2884 Mcandidates_charset = msymbol ("candidates-charset");
2886 Minput_preedit_start = msymbol ("input-preedit-start");
2887 Minput_preedit_done = msymbol ("input-preedit-done");
2888 Minput_preedit_draw = msymbol ("input-preedit-draw");
2889 Minput_status_start = msymbol ("input-status-start");
2890 Minput_status_done = msymbol ("input-status-done");
2891 Minput_status_draw = msymbol ("input-status-draw");
2892 Minput_candidates_start = msymbol ("input-candidates-start");
2893 Minput_candidates_done = msymbol ("input-candidates-done");
2894 Minput_candidates_draw = msymbol ("input-candidates-draw");
2895 Minput_set_spot = msymbol ("input-set-spot");
2896 Minput_focus_move = msymbol ("input-focus-move");
2897 Minput_focus_in = msymbol ("input-focus-in");
2898 Minput_focus_out = msymbol ("input-focus-out");
2899 Minput_toggle = msymbol ("input-toggle");
2900 Minput_reset = msymbol ("input-reset");
2901 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
2902 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
2904 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
2905 Mcandidate_index = msymbol (" candidate-index");
2907 Minit = msymbol ("init");
2908 Mfini = msymbol ("fini");
2910 M_key_alias = msymbol (" key-alias");
2911 M_description = msymbol ("description");
2912 M_command = msymbol ("command");
2913 M_variable = msymbol ("variable");
2915 load_im_info_keys = mplist ();
2916 plist = mplist_add (load_im_info_keys, Mstate, Mnil);
2921 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
2925 one_char_symbol[i] = msymbol (buf);
2928 alias = msymbol (key_names[i]);
2929 msymbol_put (one_char_symbol[i], M_key_alias, alias);
2932 alias = one_char_symbol[i];
2933 buf[2] += (i == 0) ? -32 : 32;
2934 msymbol_put (alias, M_key_alias, msymbol (buf));
2935 buf[2] -= (i == 0) ? -32 : 32;
2937 for (buf[2] = i; i < 127; i++, buf[2]++)
2938 one_char_symbol[i] = msymbol (buf + 2);
2939 one_char_symbol[i++] = msymbol ("Delete");
2945 for (buf[4] = '@'; i < 160; i++, buf[4]++)
2947 one_char_symbol[i] = msymbol (buf);
2948 if (key_names[i - 128])
2950 strcpy (buf2 + 2, key_names[i - 128]);
2951 msymbol_put (one_char_symbol[i], M_key_alias, msymbol (buf2));
2954 for (buf[4] = i - 128; i < 255; i++, buf[4]++)
2955 one_char_symbol[i] = msymbol (buf + 2);
2956 one_char_symbol[i] = msymbol ("M-Delete");
2958 command_list = variable_list = NULL;
2960 minput_default_driver.open_im = open_im;
2961 minput_default_driver.close_im = close_im;
2962 minput_default_driver.create_ic = create_ic;
2963 minput_default_driver.destroy_ic = destroy_ic;
2964 minput_default_driver.filter = filter;
2965 minput_default_driver.lookup = lookup;
2966 minput_default_driver.callback_list = mplist ();
2967 mplist_put (minput_default_driver.callback_list, Minput_reset,
2969 minput_driver = &minput_default_driver;
2978 M17N_OBJECT_UNREF (command_list);
2979 command_list = NULL;
2983 M17N_OBJECT_UNREF (variable_list);
2984 variable_list = NULL;
2987 if (minput_default_driver.callback_list)
2989 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
2990 minput_default_driver.callback_list = NULL;
2992 if (minput_driver->callback_list)
2994 M17N_OBJECT_UNREF (minput_driver->callback_list);
2995 minput_driver->callback_list = NULL;
3000 while (! MPLIST_TAIL_P (im_info_list))
3003 mplist_pop (im_info_list);
3004 free_im_info ((MInputMethodInfo *) MPLIST_VAL (im_info_list));
3005 /* Pop (t . im_info) */
3006 mplist_pop (im_info_list);
3008 M17N_OBJECT_UNREF (im_info_list);
3009 im_info_list = NULL;
3012 M17N_OBJECT_UNREF (load_im_info_keys);
3016 minput__callback (MInputContext *ic, MSymbol command)
3018 if (ic->im->driver.callback_list)
3020 MInputCallbackFunc func
3021 = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3025 (func) (ic, command);
3030 minput__char_to_key (int c)
3032 if (c < 0 || c >= 0x100)
3035 return one_char_symbol[c];
3039 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3044 /*** @addtogroup m17nInputMethod */
3049 @name Variables: Predefined symbols for callback commands.
3051 These are the predefined symbols that are used as the @c COMMAND
3052 argument of callback functions of an input method driver (see
3053 #MInputDriver::callback_list ).
3055 Most of them don't require extra argument nor return any value;
3056 exceptions are these:
3058 Minput_get_surrounding_text: When a callback function assigned for
3059 this command is called, the first element of #MInputContext::plist
3060 has key #Msymbol and the value specifies which portion of the
3061 surrounding text should be retrieved. If the value is positive,
3062 it specifies the number of characters following the current cursor
3063 position. If the value is negative, the absolute value specifies
3064 the number of characters preceding the current cursor position.
3065 The callback function must set the key of this element to #Mtext
3066 and the value to the retrived M-text (whose length may be shorter
3067 than the requested number of characters if the available text is
3068 not that long, or it may be longer if an application thinks it's
3069 more efficient to return that length).
3071 Minput_delete_surrounding_text: When a callback function assigned
3072 for this command is called, the first element of
3073 #MInputContext::plist has key #Msymbol and the value specifies
3074 which portion of the surrounding text should be deleted in the
3075 same way as the case of Minput_get_surrounding_text. The callback
3076 function must delete the specified text. It should not alter
3077 #MInputContext::plist. */
3080 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3082 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3083 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3088 MSymbol Minput_preedit_start;
3089 MSymbol Minput_preedit_done;
3090 MSymbol Minput_preedit_draw;
3091 MSymbol Minput_status_start;
3092 MSymbol Minput_status_done;
3093 MSymbol Minput_status_draw;
3094 MSymbol Minput_candidates_start;
3095 MSymbol Minput_candidates_done;
3096 MSymbol Minput_candidates_draw;
3097 MSymbol Minput_set_spot;
3098 MSymbol Minput_toggle;
3099 MSymbol Minput_reset;
3100 MSymbol Minput_get_surrounding_text;
3101 MSymbol Minput_delete_surrounding_text;
3107 @name Variables: Predefined symbols for special input events.
3109 These are the predefined symbols that are used as the @c KEY
3110 argument of minput_filter (). */
3115 MSymbol Minput_focus_out;
3116 MSymbol Minput_focus_in;
3117 MSymbol Minput_focus_move;
3124 @brief The default driver for internal input methods.
3126 The variable #minput_default_driver is the default driver for
3127 internal input methods.
3129 The member MInputDriver::open_im () searches the m17n database for
3130 an input method that matches the tag \< #Minput_method, $LANGUAGE,
3131 $NAME\> and loads it.
3133 The member MInputDriver::callback_list () is @c NULL. Thus, it is
3134 programmers responsibility to set it to a plist of proper callback
3135 functions. Otherwise, no feedback information (e.g. preedit text)
3136 can be shown to users.
3138 The macro M17N_INIT () sets the variable #minput_driver to the
3139 pointer to this driver so that all internal input methods use it.
3141 Therefore, unless @c minput_driver is set differently, the driver
3142 dependent arguments $ARG of the functions whose name begin with
3143 "minput_" are all ignored. */
3146 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
3148 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
3150 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
3151 \< #Minput_method, $LANGUAGE, $NAME\>
3152 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
3154 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
3155 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
3156 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
3157 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
3159 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
3160 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
3162 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
3163 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
3165 MInputDriver minput_default_driver;
3169 @brief The driver for internal input methods.
3171 The variable #minput_driver is a pointer to the input method
3172 driver that is used by internal input methods. The macro
3173 M17N_INIT () initializes it to a pointer to #minput_default_driver
3174 if <m17n<EM></EM>.h> is included. */
3176 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
3178 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
3179 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
3180 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
3181 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
3183 MInputDriver *minput_driver;
3185 MSymbol Minput_driver;
3190 @brief Open an input method.
3192 The minput_open_im () function opens an input method that matches
3193 language $LANGUAGE and name $NAME, and returns a pointer to the
3194 input method object newly allocated.
3196 This function at first decides an driver for the input method as
3199 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3200 #minput_driver is used.
3202 If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the
3203 driver pointed to by the property value is used to open the input
3204 method. If $NAME has no such property, @c NULL is returned.
3206 Then, the member MInputDriver::open_im () of the driver is
3209 $ARG is set in the member @c arg of the structure MInputMethod so
3210 that the driver can refer to it. */
3213 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3215 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3216 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3218 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3220 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3221 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
3223 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
3224 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
3225 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3227 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
3229 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
3231 @latexonly \IPAlabel{minput_open} @endlatexonly
3236 minput_open_im (MSymbol language, MSymbol name, void *arg)
3239 MInputDriver *driver;
3241 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
3242 msymbol_name (language), msymbol_name (name));
3244 driver = minput_driver;
3247 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
3249 MERROR (MERROR_IM, NULL);
3252 MSTRUCT_CALLOC (im, MERROR_IM);
3253 im->language = language;
3256 im->driver = *driver;
3257 if ((*im->driver.open_im) (im) < 0)
3259 MDEBUG_PRINT (" failed\n");
3263 MDEBUG_PRINT (" ok\n");
3270 @brief Close an input method.
3272 The minput_close_im () function closes the input method $IM, which
3273 must have been created by minput_open_im (). */
3276 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
3278 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
3279 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
3282 minput_close_im (MInputMethod *im)
3284 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
3285 msymbol_name (im->name), msymbol_name (im->language));
3286 (*im->driver.close_im) (im);
3288 MDEBUG_PRINT (" done\n");
3294 @brief Create an input context.
3296 The minput_create_ic () function creates an input context object
3297 associated with input method $IM, and calls callback functions
3298 corresponding to #Minput_preedit_start, #Minput_status_start, and
3299 #Minput_status_draw in this order.
3303 If an input context is successfully created, minput_create_ic ()
3304 returns a pointer to it. Otherwise it returns @c NULL. */
3307 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
3309 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
3310 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
3311 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
3312 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3316 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
3317 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
3321 minput_create_ic (MInputMethod *im, void *arg)
3325 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
3326 msymbol_name (im->name), msymbol_name (im->language));
3327 MSTRUCT_CALLOC (ic, MERROR_IM);
3330 ic->preedit = mtext ();
3331 ic->candidate_list = NULL;
3332 ic->produced = mtext ();
3333 ic->spot.x = ic->spot.y = 0;
3335 ic->plist = mplist ();
3336 if ((*im->driver.create_ic) (ic) < 0)
3338 MDEBUG_PRINT (" failed\n");
3339 M17N_OBJECT_UNREF (ic->preedit);
3340 M17N_OBJECT_UNREF (ic->produced);
3341 M17N_OBJECT_UNREF (ic->plist);
3346 if (im->driver.callback_list)
3348 minput__callback (ic, Minput_preedit_start);
3349 minput__callback (ic, Minput_status_start);
3350 minput__callback (ic, Minput_status_draw);
3353 MDEBUG_PRINT (" ok\n");
3360 @brief Destroy an input context.
3362 The minput_destroy_ic () function destroys the input context $IC,
3363 which must have been created by minput_create_ic (). It calls
3364 callback functions corresponding to #Minput_preedit_done,
3365 #Minput_status_done, and #Minput_candidates_done in this order. */
3368 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
3370 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
3371 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
3372 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
3373 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
3374 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
3378 minput_destroy_ic (MInputContext *ic)
3380 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
3381 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
3382 if (ic->im->driver.callback_list)
3384 minput__callback (ic, Minput_preedit_done);
3385 minput__callback (ic, Minput_status_done);
3386 minput__callback (ic, Minput_candidates_done);
3388 (*ic->im->driver.destroy_ic) (ic);
3389 M17N_OBJECT_UNREF (ic->preedit);
3390 M17N_OBJECT_UNREF (ic->produced);
3391 M17N_OBJECT_UNREF (ic->plist);
3392 MDEBUG_PRINT (" done\n");
3399 @brief Filter an input key.
3401 The minput_filter () function filters input key $KEY according to
3402 input context $IC, and calls callback functions corresponding to
3403 #Minput_preedit_draw, #Minput_status_draw, and
3404 #Minput_candidates_draw if the preedit text, the status, and the
3405 current candidate are changed respectively.
3407 To make the input method commit the current preedit text (if any)
3408 and shift to the initial state, call this function with #Mnil as
3411 To inform the input method about the focus-out event, call this
3412 function with #Minput_focus_out as $KEY.
3414 To inform the input method about the focus-in event, call this
3415 function with #Minput_focus_in as $KEY.
3417 To inform the input method about the focus-move event (i.e. input
3418 spot change within the same input context), call this function
3419 with #Minput_focus_move as $KEY.
3422 If $KEY is filtered out, this function returns 1. In that case,
3423 the caller should discard the key. Otherwise, it returns 0, and
3424 the caller should handle the key, for instance, by calling the
3425 function minput_lookup () with the same key. */
3428 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
3430 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3431 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
3432 #Minput_preedit_draw, #Minput_status_draw,
3433 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
3436 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
3437 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
3438 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
3439 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
3441 @latexonly \IPAlabel{minput_filter} @endlatexonly
3445 minput_filter (MInputContext *ic, MSymbol key, void *arg)
3452 ret = (*ic->im->driver.filter) (ic, key, arg);
3454 if (ic->im->driver.callback_list)
3456 if (ic->preedit_changed)
3457 minput__callback (ic, Minput_preedit_draw);
3458 if (ic->status_changed)
3459 minput__callback (ic, Minput_status_draw);
3460 if (ic->candidates_changed)
3461 minput__callback (ic, Minput_candidates_draw);
3470 @brief Look up a text produced in the input context.
3472 The minput_lookup () function looks up a text in the input context
3473 $IC. $KEY must be the same one provided to the previous call of
3476 If a text was produced by the input method, it is concatenated
3479 This function calls #MInputDriver::lookup .
3482 If $KEY was correctly handled by the input method, this function
3483 returns 0. Otherwise, returns -1, even in that case, some text
3484 may be produced in $MT. */
3487 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
3489 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
3490 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3492 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
3495 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
3498 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
3499 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
3500 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
3502 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
3505 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3507 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
3512 @brief Set the spot of the input context.
3514 The minput_set_spot () function set the spot of input context $IC
3515 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
3516 The semantics of these values depend on the input method driver.
3518 For instance, a driver designed to work in a CUI environment may
3519 use $X and $Y as column and row numbers, and ignore $ASCENT and
3520 $DESCENT . A driver designed to work in a window system may
3521 interpret $X and $Y as pixel offsets relative to the origin of the
3522 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
3523 descent pixels of the line at ($X . $Y ).
3525 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
3527 $MT and $POS is the M-text and the character position at the spot.
3528 $MT may be @c NULL, in which case, the input method cannot get
3529 information about the text around the spot. */
3532 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
3534 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
3535 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
3536 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
3538 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
3539 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
3540 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
3541 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
3542 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
3543 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
3545 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
3547 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
3548 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
3552 minput_set_spot (MInputContext *ic, int x, int y,
3553 int ascent, int descent, int fontsize,
3558 ic->spot.ascent = ascent;
3559 ic->spot.descent = descent;
3560 ic->spot.fontsize = fontsize;
3563 if (ic->im->driver.callback_list)
3564 minput__callback (ic, Minput_set_spot);
3569 @brief Toggle input method.
3571 The minput_toggle () function toggles the input method associated
3572 with input context $IC. */
3574 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
3576 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3577 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
3581 minput_toggle (MInputContext *ic)
3583 if (ic->im->driver.callback_list)
3584 minput__callback (ic, Minput_toggle);
3585 ic->active = ! ic->active;
3589 @brief Reset an input context.
3591 The minput_reset_ic () function resets input context $IC by
3592 calling a callback function corresponding to #Minput_reset. It
3593 resets the status of $IC to the one of just after created. As the
3594 current preedit text is deleted without commitment, if necessary,
3595 call minput_filter () with the arg @r key #Mnil to force the input
3596 method to commit the preedit in advance. */
3599 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
3601 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset
3602 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
3603 ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ê¡¢¤·¤¿¤¬¤Ã¤Æ¡¢¤â¤·¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹¥È¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¡£
3604 ɬÍפʤé¤Ð¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï minput_lookup ()
3605 ¤òÆɤó¤Ç¤½¤Î¥³¥ß¥Ã¥È¤µ¤ì¤¿¥Æ¥¥¹¥È¤ò¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤¡¢¤½¤ÎºÝ¡¢
3606 minput_lookup () ¤Î°ú¿ô @c KEY ¤È @c ARG
3609 minput_reset_ic (MInputContext *ic)
3611 if (ic->im->driver.callback_list)
3612 minput__callback (ic, Minput_reset);
3616 @brief Get description text of an input method.
3618 The minput_get_description () function returns an M-text that
3619 describes the input method specified by $LANGUAGE and $NAME.
3622 If the specified input method has a description text, a pointer to
3623 #MText is returned. A caller have to free it by m17n_object_unref ().
3624 If the input method does not have a description text, @c NULL is
3627 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
3629 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
3630 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
3632 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
3633 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
3634 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
3635 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
3638 minput_get_description (MSymbol language, MSymbol name)
3640 MPlist *plist = load_partial_im_info (language, name, Mnil, M_description);
3646 pl = MPLIST_PLIST (plist);
3647 pl = MPLIST_NEXT (pl);
3648 if (MPLIST_MTEXT_P (pl))
3650 mt = MPLIST_MTEXT (pl);
3651 M17N_OBJECT_REF (mt);
3653 M17N_OBJECT_UNREF (plist);
3658 @brief Get information about input method commands.
3660 The minput_get_commands () function returns information about
3661 input method commands of the input method specified by $LANGUAGE
3662 and $NAME. An input method command is a pseudo key event to which
3663 one or more actual input key sequences are assigned.
3665 There are two kinds of commands, global and local. Global
3666 commands are used by multiple input methods for the same purpose,
3667 and have global key assignments. Local commands are used only in
3668 a specific input method, and have only local key assignments.
3670 Each input method may locally change key assignments for global
3671 commands. A global key assignment for a global command are
3672 effective only when the current input method does not have local
3673 key assignments for that command.
3675 If $NAME is #Mnil, information about global commands is returned.
3676 In this case $LANGUAGE is ignored.
3678 If $NAME is not #Mnil, information about those commands that have
3679 local key assignments in the input method specified by $LANGUAGE
3680 and $NAME is returned.
3683 If no input method commands are found, this function returns @c NULL.
3685 Otherwise, a pointer to a plist is returned. The key of each
3686 element in the plist is a symbol representing a command, and the
3687 value is a plist of the form COMMAND-INFO described below.
3689 The first element of COMMAND-INFO has the key #Mtext, and the
3690 value is an M-text describing the command.
3692 If there are no more elements, that means no key sequences are
3693 assigned to the command. Otherwise, each of the remaining
3694 elements has the key #Mplist, and the value is a plist whose keys are
3695 #Msymbol and values are symbols representing input keys, which are
3696 currently assigned to the command.
3698 As the returned plist is kept in the library, the caller must not
3699 modify nor free it. */
3701 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
3703 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
3704 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
3705 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
3706 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
3708 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
3709 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
3710 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
3711 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
3713 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
3714 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
3715 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
3718 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
3719 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
3721 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
3722 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
3726 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
3728 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
3729 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
3730 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
3732 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
3733 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
3734 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
3737 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
3738 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
3739 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
3740 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
3741 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3743 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
3744 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
3747 minput_get_commands (MSymbol language, MSymbol name)
3749 MPlist *plist = get_nested_list (language, name, Mnil, M_command);
3751 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3755 @brief Assign a key sequence to an input method command.
3757 The minput_assign_command_keys () function assigns input key
3758 sequence $KEYSEQ to input method command $COMMAND for the input
3759 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
3760 key sequence is assigned globally no matter what $LANGUAGE is.
3761 Otherwise the key sequence is assigned locally.
3763 Each element of $KEYSEQ must have the key $Msymbol and the value
3764 must be a symbol representing an input key.
3766 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
3767 globally or locally.
3769 This assignment gets effective in a newly opened input method.
3772 If the operation was successful, 0 is returned. Otherwise -1 is
3773 returned, and #merror_code is set to #MERROR_IM. */
3775 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
3777 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
3778 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
3779 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
3780 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
3781 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
3783 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
3784 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3786 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
3787 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
3789 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
3792 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
3793 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
3796 minput_assign_command_keys (MSymbol language, MSymbol name,
3797 MSymbol command, MPlist *keyseq)
3799 MPlist *plist, *pl, *p;
3801 if (check_command_keyseq (keyseq) < 0
3802 || ! (plist = get_nested_list (language, name, Mnil, M_command)))
3803 MERROR (MERROR_IM, -1);
3804 pl = mplist_get (plist, command);
3807 pl = MPLIST_NEXT (pl);
3809 while ((p = mplist_pop (pl)))
3810 M17N_OBJECT_UNREF (p);
3813 keyseq = mplist_copy (keyseq);
3814 mplist_push (pl, Mplist, keyseq);
3815 M17N_OBJECT_UNREF (keyseq);
3821 MERROR (MERROR_IM, -1);
3824 /* Get global commands. */
3825 pl = get_nested_list (Mnil, Mnil, Mnil, M_command);
3826 pl = mplist_get (pl, command);
3828 MERROR (MERROR_IM, -1);
3830 mplist_add (p, Mtext, mplist_value (pl));
3831 keyseq = mplist_copy (keyseq);
3832 mplist_add (p, Mplist, keyseq);
3833 M17N_OBJECT_UNREF (keyseq);
3834 mplist_push (plist, command, p);
3840 @brief Get a list of variables of an input method.
3842 The minput_get_variables () function returns a plist (#MPlist) of
3843 variables used to control the behavior of the input method
3844 specified by $LANGUAGE and $NAME. The key of an element of the
3845 plist is a symbol representing a variable, and the value is a
3846 plist of the form VAR-INFO (described below) that carries the
3847 information about the variable.
3849 The first element of VAR-INFO has the key #Mtext or #Msymbol. If
3850 the key is #Mtext, the value is an M-text describing the variable.
3851 If the key is #Msymbol, that value is #Mnil which means the
3852 variable has no description text.
3854 The second element of VAR-INFO is for the value of the variable.
3855 The key is #Minteger, #Msymbol, or #Mtext, and the value is an
3856 integer, a symbol, or an M-text, respectively. The variable is
3857 set to this value when an input context is created for the input
3860 If there are no more elements, the variable can take any value
3861 that matches with the above type. Otherwise, the remaining
3862 elements of VAR-INFO are to specify valid values of the variable.
3864 If the type of the variable is integer, the following elements
3865 have the key #Minteger or #Mplist. If it is #Minteger, the value
3866 is a valid integer value. If it is #Mplist, the value is a plist
3867 of two of elements. Both of them have the key #Minteger, and
3868 values are the minimum and maximum bounds of the valid value
3871 If the type of the variable is symbol or M-text, the following
3872 elements of the plist have the key #Msymbol or #Mtext,
3873 respectively, and the value must be a valid one.
3875 For instance, suppose an input method has the variables:
3877 @li name:intvar, description:"value is an integer",
3878 initial value:0, value-range:0..3,10,20
3880 @li name:symvar, description:"value is a symbol",
3881 initial value:nil, value-range:a, b, c, nil
3883 @li name:txtvar, description:"value is an M-text",
3884 initial value:empty text, no value-range (i.e. any text)
3886 Then, the returned plist has this form ('X:Y' means X is a key and Y is
3887 a value, and '(...)' means a plist):
3890 plist:(intvar:(mtext:"value is an integer"
3892 plist:(integer:0 integer:3)
3895 symvar:(mtext:"value is a symbol"
3901 txtvar:(mtext:"value is an M-text"
3906 If the input method uses any variables, a pointer to #MPlist is
3907 returned. As the plist is kept in the library, a caller must not
3908 modify nor free it. If the input method does not use any
3909 variable, @c NULL is returned. */
3911 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
3913 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME
3914 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
3915 (#MPlist) ¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤΥ¡¼¤ÏÊÑ¿ô¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
3916 ³ÆÍ×ÁǤÎÃͤϲ¼µ¤Î VAR-INFO
3917 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤·¤Æ¤¤¤ë¡£
3919 VAR-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼¤¬
3920 #Mtext ¤Ê¤é¡¢ÃͤϤ½¤ÎÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬ #Msymbol
3921 ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤ÎÊÑ¿ô¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê¤¤¤³¤È¤Ë¤Ê¤ë¡£
3923 VAR-INFO ¤ÎÂèÆóÍ×ÁǤÏÊÑ¿ô¤ÎÃͤò¼¨¤¹¡£¥¡¼¤Ï #Minteger, #Msymbol,
3924 #Mtext ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÀ°¿ôÃÍ¡¢¥·¥ó¥Ü¥ë¡¢M-text ¤Ç¤¢¤ë¡£
3925 ¤³¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎÏ¥³¥ó¥Æ¥¹¥È¤¬ºî¤é¤ì¤ë»þÅÀ¤Ç¤Ï¡¢ÊÑ¿ô¤Ï¤³¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¡£
3927 VAR-INFO ¤Ë¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï¾åµ¤Î·¿¤Ë¹çÃפ¹¤ë¸Â¤ê¤É¤Î¤è¤¦¤ÊÃͤò¤È¤ë¤³¤È¤â¤Ç¤¤ë¡£
3928 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢VAR-INFO ¤Î»Ä¤ê¤ÎÍ×ÁǤˤè¤Ã¤ÆÊÑ¿ô¤Î͸ú¤ÊÃͤ¬»ØÄꤵ¤ì¤ë¡£
3930 ÊÑ¿ô¤Î·¿¤¬À°¿ô¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁÇ¤Ï #Minteger ¤« #Mplist
3931 ¤ò¥¡¼¤È¤·¤Æ»ý¤Ä¡£ #Minteger ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏ͸ú¤ÊÃͤò¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
3932 #Mplist ¤Ç¤¢¤ì¤Ð¡¢ÃͤÏÆó¤Ä¤ÎÍ×ÁǤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ê¡¢³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ
3933 #Minteger ¤ò¡¢ÃͤȤ·¤Æ¤½¤ì¤¾¤ì͸ú¤ÊÃͤξå¸ÂÃͤȲ¼¸ÂÃͤò¤È¤ë¡£
3935 ÊÑ¿ô¤Î·¿¤¬¥·¥ó¥Ü¥ë¤« M-text ¤Ç¤¢¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÍ×ÁǤϥ¡¼¤È¤·¤Æ¤½¤ì¤¾¤ì
3936 #Msymbol ¤« #Mtext ¤ò»ý¤Á¡¢ÃͤϤ½¤Î·¿¤Ë¹çÃפ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
3938 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
3940 @li name:intvar, ÀâÌÀ:"value is an integer",
3941 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
3943 @li name:symvar, ÀâÌÀ:"value is a symbol",
3944 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
3946 @li name:txtvar, ÀâÌÀ:"value is an M-text",
3947 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
3949 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£¡Ê'X:Y' ¤È¤¤¤¦µË¡¤Ï X
3950 ¤¬¥¡¼¤Ç Y ¤¬ÃͤǤ¢¤ë¤³¤È¤ò¡¢¤Þ¤¿ '(...)' ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¼¨¤¹¡£¡Ë
3953 plist:(intvar:(mtext:"value is an integer"
3955 plist:(integer:0 integer:3)
3958 symvar:(mtext:"value is a symbol"
3964 txtvar:(mtext:"value is an M-text"
3969 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤ÎÊÑ¿ô¤òÊÖ¤¹¡£
3970 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
3971 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
3974 minput_get_variables (MSymbol language, MSymbol name)
3976 MPlist *plist = get_nested_list (language, name, Mnil, M_variable);
3978 return (MPLIST_TAIL_P (plist) ? NULL : plist);
3982 @brief Set the initial value of an input method variable.
3984 The minput_set_variable () function sets the initial value of
3985 input method variable $VARIABLE to $VALUE for the input method
3986 specified by $LANGUAGE and $NAME.
3988 By default, the initial value is 0.
3990 This setting gets effective in a newly opened input method.
3993 If the operation was successful, 0 is returned. Otherwise -1 is
3994 returned, and #merror_code is set to #MERROR_IM. */
3996 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
3998 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
3999 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
4000 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
4002 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
4004 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
4007 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
4008 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
4011 minput_set_variable (MSymbol language, MSymbol name,
4012 MSymbol variable, void *value)
4014 MPlist *plist, *val_element, *range_element;
4017 plist = get_nested_list (language, name, Mnil, M_variable);
4019 MERROR (MERROR_IM, -1);
4020 plist = mplist_find_by_value (plist, variable);
4022 MERROR (MERROR_IM, -1);
4023 plist = MPLIST_PLIST (MPLIST_NEXT (plist));
4024 val_element = MPLIST_NEXT (plist);
4025 type = MPLIST_KEY (val_element);
4026 range_element = MPLIST_NEXT (val_element);
4028 if (! MPLIST_TAIL_P (range_element))
4030 if (type == Minteger)
4032 int val = (int) value, this_val;
4034 MPLIST_DO (plist, range_element)
4036 this_val = (int) MPLIST_VAL (plist);
4037 if (MPLIST_PLIST_P (plist))
4039 int min_bound, max_bound;
4040 MPlist *pl = MPLIST_PLIST (plist);
4042 min_bound = (int) MPLIST_VAL (pl);
4043 pl = MPLIST_NEXT (pl);
4044 max_bound = (int) MPLIST_VAL (pl);
4045 if (val >= min_bound && val <= max_bound)
4048 else if (val == this_val)
4051 if (MPLIST_TAIL_P (plist))
4052 MERROR (MERROR_IM, -1);
4054 else if (type == Msymbol)
4056 MPLIST_DO (plist, range_element)
4057 if (MPLIST_SYMBOL (plist) == (MSymbol) value)
4059 if (MPLIST_TAIL_P (plist))
4060 MERROR (MERROR_IM, -1);
4062 else /* type == Mtext */
4064 MPLIST_DO (plist, range_element)
4065 if (mtext_cmp (MPLIST_MTEXT (plist), (MText *) value) == 0)
4067 if (MPLIST_TAIL_P (plist))
4068 MERROR (MERROR_IM, -1);
4069 M17N_OBJECT_REF (value);
4073 mplist_set (val_element, type, value);
4079 /*** @addtogroup m17nDebug */
4085 @brief Dump an input method.
4087 The mdebug_dump_im () function prints the input method $IM in a
4088 human readable way to the stderr. $INDENT specifies how many
4089 columns to indent the lines but the first one.
4092 This function returns $IM. */
4094 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
4096 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
4097 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
4100 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
4103 mdebug_dump_im (MInputMethod *im, int indent)
4105 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
4108 prefix = (char *) alloca (indent + 1);
4109 memset (prefix, 32, indent);
4110 prefix[indent] = '\0';
4112 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
4113 msymbol_name (im->name));
4114 mdebug_dump_mtext (im_info->title, 0, 0);
4115 if (im->name != Mnil)
4119 MPLIST_DO (state, im_info->states)
4121 fprintf (stderr, "\n%s ", prefix);
4122 dump_im_state (MPLIST_VAL (state), indent + 2);
4125 fprintf (stderr, ")");