1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
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., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mpop = msymbol ("pop");
406 Mundo = msymbol ("undo");
407 Mcall = msymbol ("call");
408 Mshift = msymbol ("shift");
409 Mselect = msymbol ("select");
410 Mshow = msymbol ("show");
411 Mhide = msymbol ("hide");
412 Mcommit = msymbol ("commit");
413 Munhandle = msymbol ("unhandle");
414 Mset = msymbol ("set");
415 Madd = msymbol ("add");
416 Msub = msymbol ("sub");
417 Mmul = msymbol ("mul");
418 Mdiv = msymbol ("div");
419 Mequal = msymbol ("=");
420 Mless = msymbol ("<");
421 Mgreater = msymbol (">");
422 Mless_equal = msymbol ("<=");
423 Mgreater_equal = msymbol (">=");
424 Mcond = msymbol ("cond");
425 Mplus = msymbol ("+");
426 Mminus = msymbol ("-");
427 Mstar = msymbol ("*");
428 Mslash = msymbol ("/");
429 Mand = msymbol ("&");
431 Mnot = msymbol ("!");
433 Mat_reload = msymbol ("@reload");
435 Mcandidates_group_size = msymbol ("candidates-group-size");
436 Mcandidates_charset = msymbol ("candidates-charset");
438 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
439 Mcandidate_index = msymbol (" candidate-index");
441 Minit = msymbol ("init");
442 Mfini = msymbol ("fini");
444 Mdescription = msymbol ("description");
445 Mcommand = msymbol ("command");
446 Mvariable = msymbol ("variable");
447 Mglobal = msymbol ("global");
448 Mconfig = msymbol ("config");
449 M_gettext = msymbol ("_");
451 load_im_info_keys = mplist ();
452 mplist_add (load_im_info_keys, Mstate, Mnil);
453 mplist_push (load_im_info_keys, Mmap, Mnil);
455 im_info_list = mplist ();
456 im_config_list = im_custom_list = NULL;
457 im_custom_mdb = NULL;
458 update_custom_info ();
460 update_global_info ();
462 fully_initialized = 1;
465 #define MINPUT__INIT() \
467 if (! fully_initialized) \
468 fully_initialize (); \
473 marker_code (MSymbol sym, int surrounding)
479 name = MSYMBOL_NAME (sym);
480 return (name[0] != '@' ? -1
481 : (((name[1] >= '0' && name[1] <= '9')
482 || name[1] == '<' || name[1] == '>' || name[1] == '='
483 || name[1] == '[' || name[1] == ']'
485 && name[2] == '\0') ? name[1]
486 : (name[1] != '+' && name[1] != '-') ? -1
487 : (name[2] == '\0' || surrounding) ? name[1]
493 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
495 MPlist *plist = mplist__assq (ic_info->vars, var);
499 plist = MPLIST_PLIST (plist);
500 return MPLIST_NEXT (plist);
504 mplist_push (ic_info->vars, Mplist, plist);
505 M17N_OBJECT_UNREF (plist);
506 plist = mplist_add (plist, Msymbol, var);
507 plist = mplist_add (plist, Minteger, (void *) 0);
512 get_surrounding_text (MInputContext *ic, int len)
516 mplist_push (ic->plist, Minteger, (void *) len);
517 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
518 && MPLIST_MTEXT_P (ic->plist))
519 mt = MPLIST_MTEXT (ic->plist);
520 mplist_pop (ic->plist);
525 delete_surrounding_text (MInputContext *ic, int pos)
527 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
529 mplist_push (ic->plist, Minteger, (void *) pos);
530 minput_callback (ic, Minput_delete_surrounding_text);
531 mplist_pop (ic->plist);
534 M17N_OBJECT_UNREF (ic_info->preceding_text);
535 ic_info->preceding_text = NULL;
539 M17N_OBJECT_UNREF (ic_info->following_text);
540 ic_info->following_text = NULL;
545 get_preceding_char (MInputContext *ic, int pos)
547 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
551 if (pos && ic_info->preceding_text)
553 len = mtext_nchars (ic_info->preceding_text);
555 return mtext_ref_char (ic_info->preceding_text, len - pos);
557 mt = get_surrounding_text (ic, - pos);
560 len = mtext_nchars (mt);
561 if (ic_info->preceding_text)
563 if (mtext_nchars (ic_info->preceding_text) < len)
565 M17N_OBJECT_UNREF (ic_info->preceding_text);
566 ic_info->preceding_text = mt;
569 M17N_OBJECT_UNREF (mt);
572 ic_info->preceding_text = mt;
575 return mtext_ref_char (ic_info->preceding_text, len - pos);
579 get_following_char (MInputContext *ic, int pos)
581 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
585 if (ic_info->following_text)
587 len = mtext_nchars (ic_info->following_text);
589 return mtext_ref_char (ic_info->following_text, pos);
591 mt = get_surrounding_text (ic, pos + 1);
594 len = mtext_nchars (mt);
595 if (ic_info->following_text)
597 if (mtext_nchars (ic_info->following_text) < len)
599 M17N_OBJECT_UNREF (ic_info->following_text);
600 ic_info->following_text = mt;
603 M17N_OBJECT_UNREF (mt);
606 ic_info->following_text = mt;
609 return mtext_ref_char (ic_info->following_text, pos);
613 surrounding_pos (MSymbol sym)
619 name = MSYMBOL_NAME (sym);
621 && (name[1] == '-' || name[1] == '+')
622 && name[2] >= '1' && name[2] <= '9')
623 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
628 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
630 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
632 MText *preedit = ic->preedit;
633 int len = mtext_nchars (preedit);
637 if (MPLIST_INTEGER_P (arg))
638 return MPLIST_INTEGER (arg);
640 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
643 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
647 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
650 return ic_info->key_head;
651 if ((code == '-' || code == '+'))
653 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
657 pos = atoi (name + 1);
659 return get_preceding_char (ic, 0);
660 pos = ic->cursor_pos + pos;
663 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
664 return mtext_ref_char (ic->produced,
665 mtext_len (ic->produced) + pos);
666 return get_preceding_char (ic, - pos);
671 return get_following_char (ic, pos - len);
674 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
676 else if (code >= '0' && code <= '9')
678 else if (code == '=')
679 pos = ic->cursor_pos;
680 else if (code == '[')
681 pos = ic->cursor_pos - 1;
682 else if (code == ']')
683 pos = ic->cursor_pos + 1;
684 else if (code == '<')
686 else if (code == '>')
688 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
692 parse_expression (MPlist *plist)
696 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
698 if (! MPLIST_PLIST_P (plist))
700 plist = MPLIST_PLIST (plist);
701 op = MPLIST_SYMBOL (plist);
702 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
703 && op != Mand && op != Mor && op != Mnot
704 && op != Mless && op != Mgreater && op != Mequal
705 && op != Mless_equal && op != Mgreater_equal)
706 MERROR (MERROR_IM, -1);
707 MPLIST_DO (plist, MPLIST_NEXT (plist))
708 if (parse_expression (plist) < 0)
714 resolve_expression (MInputContext *ic, MPlist *plist)
719 if (MPLIST_INTEGER_P (plist))
720 return MPLIST_INTEGER (plist);
721 if (MPLIST_SYMBOL_P (plist))
722 return integer_value (ic, plist, NULL, 1);
723 if (! MPLIST_PLIST_P (plist))
725 plist = MPLIST_PLIST (plist);
726 if (! MPLIST_SYMBOL_P (plist))
728 op = MPLIST_SYMBOL (plist);
729 plist = MPLIST_NEXT (plist);
730 val = resolve_expression (ic, plist);
732 MPLIST_DO (plist, MPLIST_NEXT (plist))
733 val += resolve_expression (ic, plist);
734 else if (op == Mminus)
735 MPLIST_DO (plist, MPLIST_NEXT (plist))
736 val -= resolve_expression (ic, plist);
737 else if (op == Mstar)
738 MPLIST_DO (plist, MPLIST_NEXT (plist))
739 val *= resolve_expression (ic, plist);
740 else if (op == Mslash)
741 MPLIST_DO (plist, MPLIST_NEXT (plist))
742 val /= resolve_expression (ic, plist);
744 MPLIST_DO (plist, MPLIST_NEXT (plist))
745 val &= resolve_expression (ic, plist);
747 MPLIST_DO (plist, MPLIST_NEXT (plist))
748 val |= resolve_expression (ic, plist);
751 else if (op == Mless)
752 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
753 else if (op == Mequal)
754 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
755 else if (op == Mgreater)
756 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
757 else if (op == Mless_equal)
758 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
759 else if (op == Mgreater_equal)
760 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
764 /* Parse PLIST as an action list. PLIST should have this form:
765 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
766 Return 0 if successfully parsed, otherwise return -1. */
769 parse_action_list (MPlist *plist, MPlist *macros)
771 MPLIST_DO (plist, plist)
773 if (MPLIST_MTEXT_P (plist))
775 /* This is a short form of (insert MTEXT). */
776 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
777 MERROR (MERROR_IM, -1); */
779 else if (MPLIST_PLIST_P (plist)
780 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
781 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
785 /* This is a short form of (insert (GROUPS *)). */
786 MPLIST_DO (pl, MPLIST_PLIST (plist))
788 if (MPLIST_PLIST_P (pl))
792 MPLIST_DO (elt, MPLIST_PLIST (pl))
793 if (! MPLIST_MTEXT_P (elt)
794 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
795 MERROR (MERROR_IM, -1);
799 if (! MPLIST_MTEXT_P (pl)
800 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
801 MERROR (MERROR_IM, -1);
805 else if (MPLIST_INTEGER_P (plist))
807 int c = MPLIST_INTEGER (plist);
809 if (c < 0 || c > MCHAR_MAX)
810 MERROR (MERROR_IM, -1);
812 else if (MPLIST_PLIST_P (plist)
813 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
815 MPlist *pl = MPLIST_PLIST (plist);
816 MSymbol action_name = MPLIST_SYMBOL (pl);
818 pl = MPLIST_NEXT (pl);
820 if (action_name == Minsert)
822 if (MPLIST_MTEXT_P (pl))
824 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
825 MERROR (MERROR_IM, -1);
827 else if (MPLIST_PLIST_P (pl))
829 MPLIST_DO (pl, MPLIST_PLIST (pl))
831 if (MPLIST_PLIST_P (pl))
835 MPLIST_DO (elt, MPLIST_PLIST (pl))
836 if (! MPLIST_MTEXT_P (elt)
837 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
838 MERROR (MERROR_IM, -1);
842 if (! MPLIST_MTEXT_P (pl)
843 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
844 MERROR (MERROR_IM, -1);
848 else if (! MPLIST_SYMBOL_P (pl))
849 MERROR (MERROR_IM, -1);
851 else if (action_name == Mselect
852 || action_name == Mdelete
853 || action_name == Mmove)
855 if (parse_expression (pl) < 0)
858 else if (action_name == Mmark
859 || action_name == Mcall
860 || action_name == Mshift)
862 if (! MPLIST_SYMBOL_P (pl))
863 MERROR (MERROR_IM, -1);
865 else if (action_name == Mundo)
867 if (! MPLIST_TAIL_P (pl))
869 if (! MPLIST_SYMBOL_P (pl)
870 && ! MPLIST_INTEGER_P (pl))
871 MERROR (MERROR_IM, -1);
874 else if (action_name == Mpushback)
876 if (MPLIST_MTEXT_P (pl))
878 MText *mt = MPLIST_MTEXT (pl);
880 if (mtext_nchars (mt) != mtext_nbytes (mt))
881 MERROR (MERROR_IM, -1);
883 else if (MPLIST_PLIST_P (pl))
887 MPLIST_DO (p, MPLIST_PLIST (pl))
888 if (! MPLIST_SYMBOL_P (p))
889 MERROR (MERROR_IM, -1);
891 else if (! MPLIST_INTEGER_P (pl))
892 MERROR (MERROR_IM, -1);
894 else if (action_name == Mset || action_name == Madd
895 || action_name == Msub || action_name == Mmul
896 || action_name == Mdiv)
898 if (! MPLIST_SYMBOL_P (pl))
899 MERROR (MERROR_IM, -1);
900 if (parse_expression (MPLIST_NEXT (pl)) < 0)
903 else if (action_name == Mequal || action_name == Mless
904 || action_name == Mgreater || action_name == Mless_equal
905 || action_name == Mgreater_equal)
907 if (parse_expression (pl) < 0
908 || parse_expression (MPLIST_NEXT (pl)) < 0)
910 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
911 if (! MPLIST_PLIST_P (pl))
912 MERROR (MERROR_IM, -1);
913 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
914 MERROR (MERROR_IM, -1);
915 pl = MPLIST_NEXT (pl);
916 if (MPLIST_PLIST_P (pl)
917 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
918 MERROR (MERROR_IM, -1);
920 else if (action_name == Mshow || action_name == Mhide
921 || action_name == Mcommit || action_name == Munhandle
922 || action_name == Mpop)
924 else if (action_name == Mcond)
927 if (! MPLIST_PLIST_P (pl))
928 MERROR (MERROR_IM, -1);
930 else if (! macros || ! mplist_get (macros, action_name))
931 MERROR (MERROR_IM, -1);
933 else if (! MPLIST_SYMBOL_P (plist))
934 MERROR (MERROR_IM, -1);
941 resolve_command (MPlist *cmds, MSymbol command)
945 if (! cmds || ! (plist = mplist__assq (cmds, command)))
947 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
948 plist = MPLIST_NEXT (plist);
949 plist = MPLIST_NEXT (plist);
950 plist = MPLIST_NEXT (plist);
954 /* Load a translation into MAP from PLIST.
956 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
959 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
960 MPlist *branch_actions, MPlist *macros)
965 if (MPLIST_MTEXT_P (keylist))
967 MText *mt = MPLIST_MTEXT (keylist);
969 len = mtext_nchars (mt);
970 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
972 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
973 for (i = 0; i < len; i++)
974 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
980 if (MFAILP (MPLIST_PLIST_P (keylist)))
982 elt = MPLIST_PLIST (keylist);
983 len = MPLIST_LENGTH (elt);
984 if (MFAILP (len > 0))
986 keyseq = (MSymbol *) alloca (sizeof (int) * len);
987 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
989 if (MPLIST_INTEGER_P (elt))
991 int c = MPLIST_INTEGER (elt);
993 if (MFAILP (c >= 0 && c < 0x100))
995 keyseq[i] = one_char_symbol[c];
999 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1001 keyseq[i] = MPLIST_SYMBOL (elt);
1006 for (i = 0; i < len; i++)
1008 MIMMap *deeper = NULL;
1011 deeper = mplist_get (map->submaps, keyseq[i]);
1013 map->submaps = mplist ();
1016 /* Fixme: It is better to make all deeper maps at once. */
1017 MSTRUCT_CALLOC (deeper, MERROR_IM);
1018 mplist_put (map->submaps, keyseq[i], deeper);
1023 /* We reach a terminal map. */
1024 if (map->map_actions
1025 || map->branch_actions)
1026 /* This map is already defined. We avoid overriding it. */
1029 if (! MPLIST_TAIL_P (map_actions))
1031 if (parse_action_list (map_actions, macros) < 0)
1032 MERROR (MERROR_IM, -1);
1033 map->map_actions = map_actions;
1037 map->branch_actions = branch_actions;
1038 M17N_OBJECT_REF (branch_actions);
1044 /* Load a branch from PLIST into MAP. PLIST has this form:
1045 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1048 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1051 MPlist *branch_actions;
1053 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1055 map_name = MPLIST_SYMBOL (plist);
1056 plist = MPLIST_NEXT (plist);
1057 if (MPLIST_TAIL_P (plist))
1058 branch_actions = NULL;
1059 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1062 branch_actions = plist;
1063 if (map_name == Mnil)
1065 map->branch_actions = branch_actions;
1067 M17N_OBJECT_REF (branch_actions);
1069 else if (map_name == Mt)
1071 map->map_actions = branch_actions;
1073 M17N_OBJECT_REF (branch_actions);
1075 else if (im_info->maps)
1077 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1078 if (! plist && im_info->configured_vars)
1080 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1082 if (p && MPLIST_PLIST_P (p))
1084 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1085 if (MPLIST_SYMBOL_P (p))
1086 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1091 MPLIST_DO (plist, plist)
1093 MPlist *keylist, *map_actions;
1095 if (! MPLIST_PLIST_P (plist))
1096 MERROR (MERROR_IM, -1);
1097 keylist = MPLIST_PLIST (plist);
1098 map_actions = MPLIST_NEXT (keylist);
1099 if (MPLIST_SYMBOL_P (keylist))
1101 MSymbol command = MPLIST_SYMBOL (keylist);
1104 if (MFAILP (command != Mat_reload))
1106 pl = resolve_command (im_info->configured_cmds, command);
1110 load_translation (map, pl, map_actions, branch_actions,
1114 load_translation (map, keylist, map_actions, branch_actions,
1123 /* Load a macro from PLIST into IM_INFO->macros.
1124 PLIST has this from:
1125 PLIST ::= ( MACRO-NAME ACTION * )
1126 IM_INFO->macros is a plist of macro names vs action list. */
1129 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1134 if (! MPLIST_SYMBOL_P (plist))
1135 MERROR (MERROR_IM, -1);
1136 name = MPLIST_SYMBOL (plist);
1137 plist = MPLIST_NEXT (plist);
1138 if (MPLIST_TAIL_P (plist)
1139 || parse_action_list (plist, im_info->macros) < 0)
1140 MERROR (MERROR_IM, -1);
1141 pl = mplist_get (im_info->macros, name);
1142 M17N_OBJECT_UNREF (pl);
1143 mplist_put (im_info->macros, name, plist);
1144 M17N_OBJECT_REF (plist);
1148 /* Load an external module from PLIST into IM_INFO->externals.
1149 PLIST has this form:
1150 PLIST ::= ( MODULE-NAME FUNCTION * )
1151 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1154 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1159 MIMExternalModule *external;
1163 if (MPLIST_MTEXT_P (plist))
1164 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1165 else if (MPLIST_SYMBOL_P (plist))
1166 module = MPLIST_SYMBOL (plist);
1167 module_file = alloca (strlen (MSYMBOL_NAME (module))
1168 + strlen (DLOPEN_SHLIB_EXT) + 1);
1169 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1171 handle = dlopen (module_file, RTLD_NOW);
1172 if (MFAILP (handle))
1174 fprintf (stderr, "%s\n", dlerror ());
1177 func_list = mplist ();
1178 MPLIST_DO (plist, MPLIST_NEXT (plist))
1180 if (! MPLIST_SYMBOL_P (plist))
1181 MERROR_GOTO (MERROR_IM, err_label);
1182 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1185 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1188 MSTRUCT_MALLOC (external, MERROR_IM);
1189 external->handle = handle;
1190 external->func_list = func_list;
1191 mplist_add (im_info->externals, module, external);
1196 M17N_OBJECT_UNREF (func_list);
1201 free_map (MIMMap *map, int top)
1206 M17N_OBJECT_UNREF (map->map_actions);
1209 MPLIST_DO (plist, map->submaps)
1210 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1211 M17N_OBJECT_UNREF (map->submaps);
1213 M17N_OBJECT_UNREF (map->branch_actions);
1218 free_state (void *object)
1220 MIMState *state = object;
1222 M17N_OBJECT_UNREF (state->title);
1224 free_map (state->map, 1);
1228 /** Load a state from PLIST into a newly allocated state object.
1229 PLIST has this form:
1230 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1231 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1232 Return the state object. */
1235 load_state (MInputMethodInfo *im_info, MPlist *plist)
1239 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1241 M17N_OBJECT (state, free_state, MERROR_IM);
1242 state->name = MPLIST_SYMBOL (plist);
1243 plist = MPLIST_NEXT (plist);
1244 if (MPLIST_MTEXT_P (plist))
1246 state->title = MPLIST_MTEXT (plist);
1247 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1248 Mlanguage, im_info->language);
1249 M17N_OBJECT_REF (state->title);
1250 plist = MPLIST_NEXT (plist);
1252 MSTRUCT_CALLOC (state->map, MERROR_IM);
1253 MPLIST_DO (plist, plist)
1255 if (MFAILP (MPLIST_PLIST_P (plist)))
1257 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1262 /* Return a newly created IM_INFO for an input method specified by
1263 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1265 static MInputMethodInfo *
1266 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1269 MInputMethodInfo *im_info;
1272 if (name == Mnil && extra == Mnil)
1273 language = Mt, extra = Mglobal;
1274 MSTRUCT_CALLOC (im_info, MERROR_IM);
1276 im_info->language = language;
1277 im_info->name = name;
1278 im_info->extra = extra;
1281 mplist_add (plist, Mplist, elt);
1282 M17N_OBJECT_UNREF (elt);
1283 elt = mplist_add (elt, Msymbol, language);
1284 elt = mplist_add (elt, Msymbol, name);
1285 elt = mplist_add (elt, Msymbol, extra);
1286 mplist_add (elt, Mt, im_info);
1292 fini_im_info (MInputMethodInfo *im_info)
1296 M17N_OBJECT_UNREF (im_info->cmds);
1297 M17N_OBJECT_UNREF (im_info->configured_cmds);
1298 M17N_OBJECT_UNREF (im_info->bc_cmds);
1299 M17N_OBJECT_UNREF (im_info->vars);
1300 M17N_OBJECT_UNREF (im_info->configured_vars);
1301 M17N_OBJECT_UNREF (im_info->bc_vars);
1302 M17N_OBJECT_UNREF (im_info->description);
1303 M17N_OBJECT_UNREF (im_info->title);
1304 if (im_info->states)
1306 MPLIST_DO (plist, im_info->states)
1308 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1310 M17N_OBJECT_UNREF (state);
1312 M17N_OBJECT_UNREF (im_info->states);
1315 if (im_info->macros)
1317 MPLIST_DO (plist, im_info->macros)
1318 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1319 M17N_OBJECT_UNREF (im_info->macros);
1322 if (im_info->externals)
1324 MPLIST_DO (plist, im_info->externals)
1326 MIMExternalModule *external = MPLIST_VAL (plist);
1328 dlclose (external->handle);
1329 M17N_OBJECT_UNREF (external->func_list);
1331 MPLIST_KEY (plist) = Mt;
1333 M17N_OBJECT_UNREF (im_info->externals);
1337 MPLIST_DO (plist, im_info->maps)
1339 MPlist *p = MPLIST_PLIST (plist);
1341 M17N_OBJECT_UNREF (p);
1343 M17N_OBJECT_UNREF (im_info->maps);
1350 free_im_info (MInputMethodInfo *im_info)
1352 fini_im_info (im_info);
1357 free_im_list (MPlist *plist)
1361 MPLIST_DO (pl, plist)
1363 MInputMethodInfo *im_info;
1365 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1366 im_info = MPLIST_VAL (elt);
1367 free_im_info (im_info);
1369 M17N_OBJECT_UNREF (plist);
1372 static MInputMethodInfo *
1373 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1375 if (name == Mnil && extra == Mnil)
1376 language = Mt, extra = Mglobal;
1377 while ((plist = mplist__assq (plist, language)))
1379 MPlist *elt = MPLIST_PLIST (plist);
1381 plist = MPLIST_NEXT (plist);
1382 elt = MPLIST_NEXT (elt);
1383 if (MPLIST_SYMBOL (elt) != name)
1385 elt = MPLIST_NEXT (elt);
1386 if (MPLIST_SYMBOL (elt) != extra)
1388 elt = MPLIST_NEXT (elt);
1389 return MPLIST_VAL (elt);
1394 static void load_im_info (MPlist *, MInputMethodInfo *);
1396 #define get_custom_info(im_info) \
1398 ? lookup_im_info (im_custom_list, (im_info)->language, \
1399 (im_info)->name, (im_info)->extra) \
1402 #define get_config_info(im_info) \
1404 ? lookup_im_info (im_config_list, (im_info)->language, \
1405 (im_info)->name, (im_info)->extra) \
1409 update_custom_info (void)
1415 if (mdatabase__check (im_custom_mdb) > 0)
1420 MDatabaseInfo *custom_dir_info;
1421 char custom_path[PATH_MAX + 1];
1423 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1424 if (! custom_dir_info->filename
1425 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1427 strcpy (custom_path, custom_dir_info->filename);
1428 strcat (custom_path, CUSTOM_FILE);
1429 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1435 free_im_list (im_custom_list);
1436 im_custom_list = NULL;
1438 plist = mdatabase_load (im_custom_mdb);
1441 im_custom_list = mplist ();
1443 MPLIST_DO (pl, plist)
1445 MSymbol language, name, extra;
1446 MInputMethodInfo *im_info;
1447 MPlist *im_data, *p;
1449 if (! MPLIST_PLIST_P (pl))
1451 p = MPLIST_PLIST (pl);
1452 im_data = MPLIST_NEXT (p);
1453 if (! MPLIST_PLIST_P (p))
1455 p = MPLIST_PLIST (p);
1456 if (! MPLIST_SYMBOL_P (p)
1457 || MPLIST_SYMBOL (p) != Minput_method)
1459 p = MPLIST_NEXT (p);
1460 if (! MPLIST_SYMBOL_P (p))
1462 language = MPLIST_SYMBOL (p);
1463 p = MPLIST_NEXT (p);
1464 if (! MPLIST_SYMBOL_P (p))
1466 name = MPLIST_SYMBOL (p);
1467 p = MPLIST_NEXT (p);
1468 if (MPLIST_TAIL_P (p))
1470 else if (MPLIST_SYMBOL_P (p))
1471 extra = MPLIST_SYMBOL (p);
1472 if (language == Mnil || (name == Mnil && extra == Mnil))
1474 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1475 load_im_info (im_data, im_info);
1477 M17N_OBJECT_UNREF (plist);
1482 update_global_info (void)
1488 int ret = mdatabase__check (global_info->mdb);
1492 fini_im_info (global_info);
1496 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1500 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1502 if (! global_info->mdb
1503 || ! (plist = mdatabase_load (global_info->mdb)))
1506 load_im_info (plist, global_info);
1507 M17N_OBJECT_UNREF (plist);
1512 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1513 and EXTRA. KEY, if not Mnil, tells which kind of information about
1514 the input method is necessary, and the returned IM_INFO may contain
1515 only that information. */
1517 static MInputMethodInfo *
1518 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1521 MInputMethodInfo *im_info;
1524 if (name == Mnil && extra == Mnil)
1525 language = Mt, extra = Mglobal;
1526 im_info = lookup_im_info (im_info_list, language, name, extra);
1529 if (key == Mnil ? im_info->states != NULL
1530 : key == Mcommand ? im_info->cmds != NULL
1531 : key == Mvariable ? im_info->vars != NULL
1532 : key == Mtitle ? im_info->title != NULL
1533 : key == Mdescription ? im_info->description != NULL
1535 /* IM_INFO already contains required information. */
1537 /* We have not yet loaded required information. */
1541 mdb = mdatabase_find (Minput_method, language, name, extra);
1544 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1549 plist = mdatabase_load (im_info->mdb);
1553 mplist_push (load_im_info_keys, key, Mt);
1554 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1555 mplist_pop (load_im_info_keys);
1559 MERROR (MERROR_IM, im_info);
1560 update_global_info ();
1561 load_im_info (plist, im_info);
1562 M17N_OBJECT_UNREF (plist);
1565 if (! im_info->cmds)
1566 im_info->cmds = mplist ();
1567 if (! im_info->vars)
1568 im_info->vars = mplist ();
1570 if (! im_info->title
1571 && (key == Mnil || key == Mtitle))
1572 im_info->title = (name == Mnil ? mtext ()
1573 : mtext_from_data (MSYMBOL_NAME (name),
1574 MSYMBOL_NAMELEN (name),
1575 MTEXT_FORMAT_US_ASCII));
1579 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1580 If updated, but got unloadable, return -1. Otherwise, update
1581 contents of IM_INFO from the new database, and return 1. */
1584 reload_im_info (MInputMethodInfo *im_info)
1589 update_custom_info ();
1590 update_global_info ();
1591 check = mdatabase__check (im_info->mdb);
1594 plist = mdatabase_load (im_info->mdb);
1597 fini_im_info (im_info);
1598 load_im_info (plist, im_info);
1599 M17N_OBJECT_UNREF (plist);
1600 if (! im_info->cmds)
1601 im_info->cmds = mplist ();
1602 if (! im_info->vars)
1603 im_info->vars = mplist ();
1604 if (! im_info->title)
1606 MSymbol name = im_info->name;
1608 im_info->title = (name == Mnil ? mtext ()
1609 : mtext_from_data (MSYMBOL_NAME (name),
1610 MSYMBOL_NAMELEN (name),
1611 MTEXT_FORMAT_US_ASCII));
1616 static MInputMethodInfo *
1617 get_im_info_by_tags (MPlist *plist)
1622 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1623 i++, plist = MPLIST_NEXT (plist))
1624 tag[i] = MPLIST_SYMBOL (plist);
1629 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1634 check_description (MPlist *plist)
1638 if (MPLIST_MTEXT_P (plist))
1640 if (MPLIST_PLIST_P (plist))
1642 MPlist *pl = MPLIST_PLIST (plist);
1644 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1646 pl =MPLIST_NEXT (pl);
1647 if (MFAILP (MPLIST_MTEXT_P (pl)))
1649 mt = MPLIST_MTEXT (pl);
1650 M17N_OBJECT_REF (mt);
1653 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1655 if (translated == (char *) MTEXT_DATA (mt))
1656 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1657 if (translated != (char *) MTEXT_DATA (mt))
1659 M17N_OBJECT_UNREF (mt);
1660 mt = mtext__from_data (translated, strlen (translated),
1661 MTEXT_FORMAT_UTF_8, 1);
1665 mplist_set (plist, Mtext, mt);
1666 M17N_OBJECT_UNREF (mt);
1669 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1675 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1679 check_command_keyseq (MPlist *keyseq)
1681 if (MPLIST_PLIST_P (keyseq))
1683 MPlist *p = MPLIST_PLIST (keyseq);
1686 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1690 if (MPLIST_MTEXT_P (keyseq))
1692 MText *mt = MPLIST_MTEXT (keyseq);
1695 for (i = 0; i < mtext_nchars (mt); i++)
1696 if (mtext_ref_char (mt, i) >= 256)
1703 /* Load command defitions from PLIST into IM_INFO->cmds.
1705 PLIST is well-formed and has this form;
1706 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1707 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1708 M-text or a plist of symbols.
1710 The returned list has the same form, but for each element...
1712 (1) If DESCRIPTION and the rest are omitted, the element is not
1713 stored in the returned list.
1715 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1716 description in global_info->cmds (if any). */
1719 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1723 im_info->cmds = tail = mplist ();
1725 MPLIST_DO (plist, MPLIST_NEXT (plist))
1727 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1730 if (MFAILP (MPLIST_PLIST_P (plist)))
1732 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1733 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1735 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1736 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1738 if (MFAILP (im_info != global_info))
1739 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1743 if (! check_description (p))
1744 mplist_set (p, Msymbol, Mnil);
1745 p = MPLIST_NEXT (p);
1746 while (! MPLIST_TAIL_P (p))
1748 if (MFAILP (check_command_keyseq (p)))
1749 mplist__pop_unref (p);
1751 p = MPLIST_NEXT (p);
1754 tail = mplist_add (tail, Mplist, pl);
1759 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1760 MPlist *config_cmds)
1762 MPlist *global = NULL, *custom = NULL, *config = NULL;
1763 MSymbol name = MPLIST_SYMBOL (plist);
1765 MPlist *description, *keyseq;
1767 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1768 global = MPLIST_NEXT (MPLIST_PLIST (global));
1770 plist = MPLIST_NEXT (plist);
1771 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1773 description = plist;
1774 plist = MPLIST_NEXT (plist);
1778 description = global;
1779 if (! MPLIST_TAIL_P (plist))
1780 plist = MPLIST_NEXT (plist);
1782 if (MPLIST_TAIL_P (plist) && global)
1784 keyseq = MPLIST_NEXT (global);
1785 status = Minherited;
1793 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1795 status = Mconfigured;
1796 config = MPLIST_NEXT (MPLIST_PLIST (config));
1797 if (! MPLIST_TAIL_P (config))
1800 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1802 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1804 if (MPLIST_TAIL_P (this_keyseq))
1805 mplist__pop_unref (custom);
1808 status = Mcustomized;
1809 keyseq = this_keyseq;
1814 mplist_add (plist, Msymbol, name);
1816 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1818 mplist_add (plist, Msymbol, Mnil);
1819 mplist_add (plist, Msymbol, status);
1820 mplist__conc (plist, keyseq);
1825 config_all_commands (MInputMethodInfo *im_info)
1827 MPlist *global_cmds, *custom_cmds, *config_cmds;
1828 MInputMethodInfo *temp;
1829 MPlist *tail, *plist;
1831 M17N_OBJECT_UNREF (im_info->configured_cmds);
1833 if (MPLIST_TAIL_P (im_info->cmds)
1837 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1838 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1839 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1841 im_info->configured_cmds = tail = mplist ();
1842 MPLIST_DO (plist, im_info->cmds)
1844 MPlist *pl = config_command (MPLIST_PLIST (plist),
1845 global_cmds, custom_cmds, config_cmds);
1848 tail = mplist_add (tail, Mplist, pl);
1849 M17N_OBJECT_UNREF (pl);
1854 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1855 valid, return 0 if not. */
1858 check_variable_value (MPlist *val, MPlist *global)
1860 MSymbol type = MPLIST_KEY (val);
1861 MPlist *valids = MPLIST_NEXT (val);
1863 if (type != Minteger && type != Mtext && type != Msymbol)
1867 if (MPLIST_KEY (global) != Mt
1868 && MPLIST_KEY (global) != MPLIST_KEY (val))
1870 if (MPLIST_TAIL_P (valids))
1871 valids = MPLIST_NEXT (global);
1873 if (MPLIST_TAIL_P (valids))
1876 if (type == Minteger)
1878 int n = MPLIST_INTEGER (val);
1880 MPLIST_DO (valids, valids)
1882 if (MPLIST_INTEGER_P (valids))
1884 if (n == MPLIST_INTEGER (valids))
1887 else if (MPLIST_PLIST_P (valids))
1889 MPlist *p = MPLIST_PLIST (valids);
1890 int min_bound, max_bound;
1892 if (! MPLIST_INTEGER_P (p))
1893 MERROR (MERROR_IM, 0);
1894 min_bound = MPLIST_INTEGER (p);
1895 p = MPLIST_NEXT (p);
1896 if (! MPLIST_INTEGER_P (p))
1897 MERROR (MERROR_IM, 0);
1898 max_bound = MPLIST_INTEGER (p);
1899 if (n >= min_bound && n <= max_bound)
1904 else if (type == Msymbol)
1906 MSymbol sym = MPLIST_SYMBOL (val);
1908 MPLIST_DO (valids, valids)
1910 if (! MPLIST_SYMBOL_P (valids))
1911 MERROR (MERROR_IM, 0);
1912 if (sym == MPLIST_SYMBOL (valids))
1918 MText *mt = MPLIST_MTEXT (val);
1920 MPLIST_DO (valids, valids)
1922 if (! MPLIST_MTEXT_P (valids))
1923 MERROR (MERROR_IM, 0);
1924 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1929 return (! MPLIST_TAIL_P (valids));
1932 /* Load variable defitions from PLIST into IM_INFO->vars.
1934 PLIST is well-formed and has this form;
1935 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1937 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1939 The returned list has the same form, but for each element...
1941 (1) If DESCRIPTION and the rest are omitted, the element is not
1942 stored in the returned list.
1944 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1945 description in global_info->vars (if any). */
1948 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1950 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1951 ? global_info->vars : NULL);
1954 im_info->vars = tail = mplist ();
1955 MPLIST_DO (plist, MPLIST_NEXT (plist))
1959 if (MFAILP (MPLIST_PLIST_P (plist)))
1961 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1962 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1964 if (im_info == global_info)
1966 /* Loading a global variable. */
1967 p = MPLIST_NEXT (pl);
1968 if (MPLIST_TAIL_P (p))
1969 mplist_add (p, Msymbol, Mnil);
1972 if (! check_description (p))
1973 mplist_set (p, Msymbol, Mnil);
1974 p = MPLIST_NEXT (p);
1975 if (MFAILP (! MPLIST_TAIL_P (p)
1976 && check_variable_value (p, NULL)))
1977 mplist_set (p, Mt, NULL);
1980 else if (im_info->mdb)
1982 /* Loading a local variable. */
1983 MSymbol name = MPLIST_SYMBOL (pl);
1984 MPlist *global = NULL;
1987 && (p = mplist__assq (global_vars, name)))
1989 /* P ::= ((NAME DESC ...) ...) */
1990 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1991 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1992 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1995 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1996 if (! MPLIST_TAIL_P (p))
1998 if (! check_description (p))
1999 mplist_set (p, Msymbol, Mnil);
2000 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2001 if (MFAILP (! MPLIST_TAIL_P (p)))
2002 mplist_set (p, Mt, NULL);
2005 MPlist *valid_values = MPLIST_NEXT (p);
2007 if (! MPLIST_TAIL_P (valid_values)
2008 ? MFAILP (check_variable_value (p, NULL))
2009 : global && MFAILP (check_variable_value (p, global)))
2010 mplist_set (p, Mt, NULL);
2016 /* Loading a variable customization. */
2017 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2018 if (MFAILP (! MPLIST_TAIL_P (p)))
2020 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2021 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2022 || MPLIST_MTEXT_P (p)))
2025 tail = mplist_add (tail, Mplist, pl);
2030 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2031 MPlist *config_vars)
2033 MPlist *global = NULL, *custom = NULL, *config = NULL;
2034 MSymbol name = MPLIST_SYMBOL (plist);
2036 MPlist *description = NULL, *value, *valids;
2040 global = mplist__assq (global_vars, name);
2042 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2045 plist = MPLIST_NEXT (plist);
2046 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2047 description = plist;
2049 description = global;
2051 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2053 if (MPLIST_TAIL_P (plist))
2055 /* Inherit from global (if any). */
2059 if (MPLIST_KEY (value) == Mt)
2061 valids = MPLIST_NEXT (global);
2062 status = Minherited;
2074 value = plist = MPLIST_NEXT (plist);
2075 valids = MPLIST_NEXT (value);
2076 if (MPLIST_KEY (value) == Mt)
2078 if (! MPLIST_TAIL_P (valids))
2081 valids = MPLIST_NEXT (global);
2085 if (config_vars && (config = mplist__assq (config_vars, name)))
2087 status = Mconfigured;
2088 config = MPLIST_NEXT (MPLIST_PLIST (config));
2089 if (! MPLIST_TAIL_P (config))
2092 if (MFAILP (check_variable_value (value, global ? global : plist)))
2096 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2098 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2100 if (MPLIST_TAIL_P (this_value))
2101 mplist__pop_unref (custom);
2105 if (MFAILP (check_variable_value (value, global ? global : plist)))
2107 status = Mcustomized;
2112 mplist_add (plist, Msymbol, name);
2114 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2116 mplist_add (plist, Msymbol, Mnil);
2117 mplist_add (plist, Msymbol, status);
2119 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2121 mplist_add (plist, Mt, NULL);
2122 if (valids && ! MPLIST_TAIL_P (valids))
2123 mplist__conc (plist, valids);
2127 /* Return a configured variable definition list based on
2128 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2129 get it from global_info->vars. */
2132 config_all_variables (MInputMethodInfo *im_info)
2134 MPlist *global_vars, *custom_vars, *config_vars;
2135 MInputMethodInfo *temp;
2136 MPlist *tail, *plist;
2138 M17N_OBJECT_UNREF (im_info->configured_vars);
2140 if (MPLIST_TAIL_P (im_info->vars)
2144 global_vars = im_info != global_info ? global_info->vars : NULL;
2145 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2146 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2148 im_info->configured_vars = tail = mplist ();
2149 MPLIST_DO (plist, im_info->vars)
2151 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2152 global_vars, custom_vars, config_vars);
2155 tail = mplist_add (tail, Mplist, pl);
2156 M17N_OBJECT_UNREF (pl);
2161 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2162 CONFIG contains configuration information of the input method. */
2165 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2169 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2171 load_commands (im_info, MPLIST_PLIST (pl));
2172 config_all_commands (im_info);
2173 pl = mplist_pop (pl);
2174 M17N_OBJECT_UNREF (pl);
2177 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2179 load_variables (im_info, MPLIST_PLIST (pl));
2180 config_all_variables (im_info);
2181 pl = mplist_pop (pl);
2182 M17N_OBJECT_UNREF (pl);
2185 MPLIST_DO (plist, plist)
2186 if (MPLIST_PLIST_P (plist))
2188 MPlist *elt = MPLIST_PLIST (plist);
2191 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2193 key = MPLIST_SYMBOL (elt);
2198 elt = MPLIST_NEXT (elt);
2199 if (MFAILP (MPLIST_MTEXT_P (elt)))
2201 im_info->title = MPLIST_MTEXT (elt);
2202 M17N_OBJECT_REF (im_info->title);
2204 else if (key == Mmap)
2206 pl = mplist__from_alist (MPLIST_NEXT (elt));
2209 if (! im_info->maps)
2213 mplist__conc (im_info->maps, pl);
2214 M17N_OBJECT_UNREF (pl);
2217 else if (key == Mmacro)
2219 if (! im_info->macros)
2220 im_info->macros = mplist ();
2221 MPLIST_DO (elt, MPLIST_NEXT (elt))
2223 if (MFAILP (MPLIST_PLIST_P (elt)))
2225 load_macros (im_info, MPLIST_PLIST (elt));
2228 else if (key == Mmodule)
2230 if (! im_info->externals)
2231 im_info->externals = mplist ();
2232 MPLIST_DO (elt, MPLIST_NEXT (elt))
2234 if (MFAILP (MPLIST_PLIST_P (elt)))
2236 load_external_module (im_info, MPLIST_PLIST (elt));
2239 else if (key == Mstate)
2241 MPLIST_DO (elt, MPLIST_NEXT (elt))
2245 if (MFAILP (MPLIST_PLIST_P (elt)))
2247 pl = MPLIST_PLIST (elt);
2248 if (! im_info->states)
2249 im_info->states = mplist ();
2250 state = load_state (im_info, MPLIST_PLIST (elt));
2253 mplist_put (im_info->states, state->name, state);
2256 else if (key == Minclude)
2258 /* elt ::= include (tag1 tag2 ...) key item ... */
2260 MInputMethodInfo *temp;
2262 elt = MPLIST_NEXT (elt);
2263 if (MFAILP (MPLIST_PLIST_P (elt)))
2265 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2268 elt = MPLIST_NEXT (elt);
2269 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2271 key = MPLIST_SYMBOL (elt);
2272 elt = MPLIST_NEXT (elt);
2275 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2277 if (! im_info->maps)
2278 im_info->maps = mplist ();
2279 MPLIST_DO (pl, temp->maps)
2281 p = MPLIST_VAL (pl);
2282 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2283 M17N_OBJECT_REF (p);
2286 else if (key == Mmacro)
2288 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2290 if (! im_info->macros)
2291 im_info->macros = mplist ();
2292 MPLIST_DO (pl, temp->macros)
2294 p = MPLIST_VAL (pl);
2295 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2296 M17N_OBJECT_REF (p);
2299 else if (key == Mstate)
2301 if (! temp->states || MPLIST_TAIL_P (temp->states))
2303 if (! im_info->states)
2304 im_info->states = mplist ();
2305 MPLIST_DO (pl, temp->states)
2307 MIMState *state = MPLIST_VAL (pl);
2309 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2310 M17N_OBJECT_REF (state);
2314 else if (key == Mdescription)
2316 if (im_info->description)
2318 elt = MPLIST_NEXT (elt);
2319 if (! check_description (elt))
2321 im_info->description = MPLIST_MTEXT (elt);
2322 M17N_OBJECT_REF (im_info->description);
2325 im_info->tick = time (NULL);
2330 static int take_action_list (MInputContext *ic, MPlist *action_list);
2331 static void preedit_commit (MInputContext *ic, int need_prefix);
2334 shift_state (MInputContext *ic, MSymbol state_name)
2336 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2337 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2338 MIMState *orig_state = ic_info->state, *state;
2340 /* Find a state to shift to. If not found, shift to the initial
2342 if (state_name == Mt)
2344 if (! ic_info->prev_state)
2346 state = ic_info->prev_state;
2348 else if (state_name == Mnil)
2350 state = (MIMState *) MPLIST_VAL (im_info->states);
2354 state = (MIMState *) mplist_get (im_info->states, state_name);
2356 state = (MIMState *) MPLIST_VAL (im_info->states);
2362 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2363 MSYMBOL_NAME (orig_state->name),
2364 MSYMBOL_NAME (state->name));
2366 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2369 /* Enter the new state. */
2370 ic_info->state = state;
2371 ic_info->map = state->map;
2372 ic_info->state_key_head = ic_info->key_head;
2373 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2375 /* We have shifted to the initial state. */
2376 preedit_commit (ic, 0);
2377 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2378 ic_info->state_pos = ic->cursor_pos;
2379 if (state != orig_state)
2381 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2383 /* Shifted to the initial state. */
2384 ic_info->prev_state = NULL;
2385 M17N_OBJECT_UNREF (ic_info->vars_saved);
2386 ic_info->vars_saved = mplist_copy (ic_info->vars);
2389 ic_info->prev_state = orig_state;
2392 ic->status = state->title;
2394 ic->status = im_info->title;
2395 ic->status_changed = 1;
2396 if (ic_info->map == ic_info->state->map
2397 && ic_info->map->map_actions)
2399 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2400 MSYMBOL_NAME (state->name));
2401 take_action_list (ic, ic_info->map->map_actions);
2406 /* Find a candidate group that contains a candidate number INDEX from
2407 PLIST. Set START_INDEX to the first candidate number of the group,
2408 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2409 candidate group number if they are non-NULL. If INDEX is -1, find
2410 the last candidate group. */
2413 find_candidates_group (MPlist *plist, int index,
2414 int *start_index, int *end_index, int *group_index)
2416 int i = 0, gidx = 0, len;
2418 MPLIST_DO (plist, plist)
2420 if (MPLIST_MTEXT_P (plist))
2421 len = mtext_nchars (MPLIST_MTEXT (plist));
2423 len = mplist_length (MPLIST_PLIST (plist));
2424 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2430 *end_index = i + len;
2432 *group_index = gidx;
2441 /* Adjust markers for the change of preedit text.
2442 If FROM == TO, the change is insertion of INS chars.
2443 If FROM < TO and INS == 0, the change is deletion of the range.
2444 If FROM < TO and INS > 0, the change is replacement. */
2447 adjust_markers (MInputContext *ic, int from, int to, int ins)
2449 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2454 MPLIST_DO (markers, ic_info->markers)
2455 if (MPLIST_INTEGER (markers) > from)
2456 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2457 if (ic->cursor_pos >= from)
2458 ic->cursor_pos += ins;
2462 MPLIST_DO (markers, ic_info->markers)
2464 if (MPLIST_INTEGER (markers) >= to)
2465 MPLIST_VAL (markers)
2466 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2467 else if (MPLIST_INTEGER (markers) > from)
2468 MPLIST_VAL (markers) = (void *) from;
2470 if (ic->cursor_pos >= to)
2471 ic->cursor_pos += ins - (to - from);
2472 else if (ic->cursor_pos > from)
2473 ic->cursor_pos = from;
2479 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2481 int nchars = mt ? mtext_nchars (mt) : 1;
2485 mtext_ins (ic->preedit, pos, mt);
2486 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2490 mtext_ins_char (ic->preedit, pos, c, 1);
2492 MDEBUG_PRINT1 ("('%c')", c);
2494 MDEBUG_PRINT1 ("(U+%04X)", c);
2496 adjust_markers (ic, pos, pos, nchars);
2497 ic->preedit_changed = 1;
2502 preedit_delete (MInputContext *ic, int from, int to)
2504 mtext_del (ic->preedit, from, to);
2505 adjust_markers (ic, from, to, 0);
2506 ic->preedit_changed = 1;
2510 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2514 mtext_del (ic->preedit, from, to);
2517 mtext_ins (ic->preedit, from, mt);
2518 ins = mtext_nchars (mt);
2522 mtext_ins_char (ic->preedit, from, c, 1);
2525 adjust_markers (ic, from, to, ins);
2526 ic->preedit_changed = 1;
2531 preedit_commit (MInputContext *ic, int need_prefix)
2533 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2534 int preedit_len = mtext_nchars (ic->preedit);
2536 if (preedit_len > 0)
2540 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2541 Mcandidate_list, NULL, 0);
2542 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2543 Mcandidate_index, NULL, 0);
2544 mtext_cat (ic->produced, ic->preedit);
2550 MDEBUG_PRINT1 ("\n [IM] [%s]",
2551 MSYMBOL_NAME (ic_info->state->name));
2552 MDEBUG_PRINT (" (commit");
2553 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2554 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2558 mtext_reset (ic->preedit);
2559 mtext_reset (ic_info->preedit_saved);
2560 MPLIST_DO (p, ic_info->markers)
2562 ic->cursor_pos = ic_info->state_pos = 0;
2563 ic->preedit_changed = 1;
2564 ic_info->commit_key_head = ic_info->key_head;
2566 if (ic->candidate_list)
2568 M17N_OBJECT_UNREF (ic->candidate_list);
2569 ic->candidate_list = NULL;
2570 ic->candidate_index = 0;
2571 ic->candidate_from = ic->candidate_to = 0;
2572 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2573 if (ic->candidate_show)
2575 ic->candidate_show = 0;
2576 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2582 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2584 int code = marker_code (sym, 0);
2586 if (mt && (code == '[' || code == ']'))
2590 if (code == '[' && current > 0)
2592 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2596 else if (code == ']' && current < mtext_nchars (mt))
2598 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2604 return (code == '<' ? 0
2605 : code == '>' ? limit
2606 : code == '-' ? current - 1
2607 : code == '+' ? current + 1
2608 : code == '=' ? current
2609 : code - '0' > limit ? limit
2613 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2617 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2619 int from = mtext_property_start (prop);
2620 int to = mtext_property_end (prop);
2622 MPlist *candidate_list = mtext_property_value (prop);
2623 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2625 int ingroup_index = idx - start;
2628 candidate_list = mplist_copy (candidate_list);
2629 if (MPLIST_MTEXT_P (group))
2631 mt = MPLIST_MTEXT (group);
2632 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2640 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2641 i++, plist = MPLIST_NEXT (plist));
2642 mt = MPLIST_MTEXT (plist);
2643 preedit_replace (ic, from, to, mt, 0);
2644 to = from + mtext_nchars (mt);
2646 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2647 M17N_OBJECT_UNREF (candidate_list);
2648 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2649 ic->cursor_pos = to;
2653 get_select_charset (MInputContextInfo * ic_info)
2655 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2658 if (! MPLIST_VAL (plist))
2660 sym = MPLIST_SYMBOL (plist);
2663 return MCHARSET (sym);
2667 adjust_candidates (MPlist *plist, MCharset *charset)
2671 /* plist ::= MTEXT ... | PLIST ... */
2672 plist = mplist_copy (plist);
2673 if (MPLIST_MTEXT_P (plist))
2676 while (! MPLIST_TAIL_P (pl))
2678 /* pl ::= MTEXT ... */
2679 MText *mt = MPLIST_MTEXT (pl);
2683 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2685 c = mtext_ref_char (mt, i);
2686 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2690 mt = mtext_dup (mt);
2691 mplist_set (pl, Mtext, mt);
2692 M17N_OBJECT_UNREF (mt);
2695 mtext_del (mt, i, i + 1);
2698 if (mtext_len (mt) > 0)
2699 pl = MPLIST_NEXT (pl);
2703 M17N_OBJECT_UNREF (mt);
2707 else /* MPLIST_PLIST_P (plist) */
2710 while (! MPLIST_TAIL_P (pl))
2712 /* pl ::= (MTEXT ...) ... */
2713 MPlist *p = MPLIST_PLIST (pl);
2715 /* p ::= MTEXT ... */
2719 while (! MPLIST_TAIL_P (p0))
2721 MText *mt = MPLIST_MTEXT (p0);
2724 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2726 c = mtext_ref_char (mt, i);
2727 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2732 p0 = MPLIST_NEXT (p0);
2739 p = mplist_copy (p);
2740 mplist_set (pl, Mplist, p);
2741 M17N_OBJECT_UNREF (p);
2745 p0 = MPLIST_NEXT (p0);
2748 M17N_OBJECT_UNREF (mt);
2751 if (! MPLIST_TAIL_P (p))
2752 pl = MPLIST_NEXT (pl);
2756 M17N_OBJECT_UNREF (p);
2760 if (MPLIST_TAIL_P (plist))
2762 M17N_OBJECT_UNREF (plist);
2769 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2771 MCharset *charset = get_select_charset (ic_info);
2776 plist = resolve_variable (ic_info, Mcandidates_group_size);
2777 column = MPLIST_INTEGER (plist);
2779 plist = MPLIST_PLIST (args);
2781 plist = adjust_candidates (plist, charset);
2783 if (plist && column > 0)
2785 if (MPLIST_MTEXT_P (plist))
2787 MText *mt = MPLIST_MTEXT (plist);
2788 MPlist *next = MPLIST_NEXT (plist);
2790 if (MPLIST_TAIL_P (next))
2791 M17N_OBJECT_REF (mt);
2794 mt = mtext_dup (mt);
2795 while (! MPLIST_TAIL_P (next))
2797 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2798 next = MPLIST_NEXT (next);
2802 M17N_OBJECT_UNREF (plist);
2804 len = mtext_nchars (mt);
2806 mplist_add (plist, Mtext, mt);
2809 for (i = 0; i < len; i += column)
2811 int to = (i + column < len ? i + column : len);
2812 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2814 mplist_add (plist, Mtext, sub);
2815 M17N_OBJECT_UNREF (sub);
2818 M17N_OBJECT_UNREF (mt);
2820 else if (! MPLIST_TAIL_P (plist))
2822 MPlist *tail = plist;
2823 MPlist *new = mplist ();
2824 MPlist *this = mplist ();
2827 MPLIST_DO (tail, tail)
2829 MPlist *p = MPLIST_PLIST (tail);
2833 MText *mt = MPLIST_MTEXT (p);
2835 if (count == column)
2837 mplist_add (new, Mplist, this);
2838 M17N_OBJECT_UNREF (this);
2842 mplist_add (this, Mtext, mt);
2846 mplist_add (new, Mplist, this);
2847 M17N_OBJECT_UNREF (this);
2848 mplist_set (plist, Mnil, NULL);
2849 MPLIST_DO (tail, new)
2851 MPlist *elt = MPLIST_PLIST (tail);
2853 mplist_add (plist, Mplist, elt);
2855 M17N_OBJECT_UNREF (new);
2864 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2866 MPlist *action = NULL;
2870 if (MPLIST_SYMBOL_P (action_list))
2872 MSymbol var = MPLIST_SYMBOL (action_list);
2875 MPLIST_DO (p, ic_info->vars)
2876 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2878 if (MPLIST_TAIL_P (p))
2880 action = MPLIST_NEXT (MPLIST_PLIST (p));
2881 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2884 if (MPLIST_PLIST_P (action_list))
2886 action = MPLIST_PLIST (action_list);
2887 if (MPLIST_SYMBOL_P (action))
2889 name = MPLIST_SYMBOL (action);
2890 args = MPLIST_NEXT (action);
2892 && MPLIST_PLIST_P (args))
2893 mplist_set (action, Msymbol, M_candidates);
2895 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2898 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2899 mplist_push (action, Msymbol, M_candidates);
2900 mplist_set (action_list, Mplist, action);
2901 M17N_OBJECT_UNREF (action);
2904 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2907 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2908 mplist_push (action, Msymbol, Minsert);
2909 mplist_set (action_list, Mplist, action);
2910 M17N_OBJECT_UNREF (action);
2915 /* Perform list of actions in ACTION_LIST for the current input
2916 context IC. If unhandle action was not performed, return 0.
2917 Otherwise, return -1. */
2920 take_action_list (MInputContext *ic, MPlist *action_list)
2922 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2923 MPlist *candidate_list = ic->candidate_list;
2924 int candidate_index = ic->candidate_index;
2925 int candidate_show = ic->candidate_show;
2926 MTextProperty *prop;
2928 MPLIST_DO (action_list, action_list)
2930 MPlist *action = regularize_action (action_list, ic_info);
2936 name = MPLIST_SYMBOL (action);
2937 args = MPLIST_NEXT (action);
2939 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2940 if (name == Minsert)
2942 if (MPLIST_SYMBOL_P (args))
2944 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2945 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2948 if (MPLIST_MTEXT_P (args))
2949 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2950 else /* MPLIST_INTEGER_P (args)) */
2951 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2953 else if (name == M_candidates)
2955 MPlist *plist = get_candidate_list (ic_info, args);
2958 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2960 if (MPLIST_MTEXT_P (plist))
2962 preedit_insert (ic, ic->cursor_pos, NULL,
2963 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2966 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2970 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2972 preedit_insert (ic, ic->cursor_pos, mt, 0);
2973 len = mtext_nchars (mt);
2975 plist = mplist_copy (plist);
2976 mtext_put_prop (ic->preedit,
2977 ic->cursor_pos - len, ic->cursor_pos,
2978 Mcandidate_list, plist);
2979 M17N_OBJECT_UNREF (plist);
2980 mtext_put_prop (ic->preedit,
2981 ic->cursor_pos - len, ic->cursor_pos,
2982 Mcandidate_index, (void *) 0);
2984 else if (name == Mselect)
2987 int code, idx, gindex;
2988 int pos = ic->cursor_pos;
2990 int idx_decided = 0;
2993 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2996 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2997 group = find_candidates_group (mtext_property_value (prop), idx,
2998 &start, &end, &gindex);
2999 if (MPLIST_SYMBOL_P (args))
3001 code = marker_code (MPLIST_SYMBOL (args), 0);
3004 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3005 if (! MPLIST_INTEGER_P (args))
3007 idx = start + MPLIST_INTEGER (args);
3008 if (idx < start || idx >= end)
3016 if (code != '[' && code != ']')
3021 ? new_index (NULL, ic->candidate_index - start,
3022 end - start - 1, MPLIST_SYMBOL (args),
3024 : MPLIST_INTEGER (args)));
3027 find_candidates_group (mtext_property_value (prop), -1,
3032 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3037 int ingroup_index = idx - start;
3040 group = mtext_property_value (prop);
3041 len = mplist_length (group);
3054 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3055 idx += (MPLIST_MTEXT_P (group)
3056 ? mtext_nchars (MPLIST_MTEXT (group))
3057 : mplist_length (MPLIST_PLIST (group)));
3058 len = (MPLIST_MTEXT_P (group)
3059 ? mtext_nchars (MPLIST_MTEXT (group))
3060 : mplist_length (MPLIST_PLIST (group)));
3061 if (ingroup_index >= len)
3062 ingroup_index = len - 1;
3063 idx += ingroup_index;
3065 update_candidate (ic, prop, idx);
3066 MDEBUG_PRINT1 ("(%d)", idx);
3068 else if (name == Mshow)
3069 ic->candidate_show = 1;
3070 else if (name == Mhide)
3071 ic->candidate_show = 0;
3072 else if (name == Mdelete)
3074 int len = mtext_nchars (ic->preedit);
3078 if (MPLIST_SYMBOL_P (args)
3079 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3081 to = ic->cursor_pos + pos;
3084 delete_surrounding_text (ic, to);
3089 delete_surrounding_text (ic, to - len);
3095 to = (MPLIST_SYMBOL_P (args)
3096 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3098 : MPLIST_INTEGER (args));
3104 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3105 if (to < ic->cursor_pos)
3106 preedit_delete (ic, to, ic->cursor_pos);
3107 else if (to > ic->cursor_pos)
3108 preedit_delete (ic, ic->cursor_pos, to);
3110 else if (name == Mmove)
3112 int len = mtext_nchars (ic->preedit);
3114 = (MPLIST_SYMBOL_P (args)
3115 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3117 : MPLIST_INTEGER (args));
3123 if (pos != ic->cursor_pos)
3125 ic->cursor_pos = pos;
3126 ic->preedit_changed = 1;
3128 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3130 else if (name == Mmark)
3132 int code = marker_code (MPLIST_SYMBOL (args), 0);
3136 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3137 (void *) ic->cursor_pos);
3138 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3141 else if (name == Mpushback)
3143 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3147 if (MPLIST_SYMBOL_P (args))
3149 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3150 if (MPLIST_INTEGER_P (args))
3151 num = MPLIST_INTEGER (args);
3156 num = MPLIST_INTEGER (args);
3159 ic_info->key_head -= num;
3161 ic_info->key_head = 0;
3163 ic_info->key_head = - num;
3164 if (ic_info->key_head > ic_info->used)
3165 ic_info->key_head = ic_info->used;
3167 else if (MPLIST_MTEXT_P (args))
3169 MText *mt = MPLIST_MTEXT (args);
3170 int i, len = mtext_nchars (mt);
3173 ic_info->key_head--;
3174 for (i = 0; i < len; i++)
3176 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3177 if (ic_info->key_head + i < ic_info->used)
3178 ic_info->keys[ic_info->key_head + i] = key;
3180 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3185 MPlist *plist = MPLIST_PLIST (args), *pl;
3189 ic_info->key_head--;
3191 MPLIST_DO (pl, plist)
3193 key = MPLIST_SYMBOL (pl);
3194 if (ic_info->key_head < ic_info->used)
3195 ic_info->keys[ic_info->key_head + i] = key;
3197 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3202 else if (name == Mpop)
3204 if (ic_info->key_head < ic_info->used)
3205 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3207 else if (name == Mcall)
3209 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3210 MIMExternalFunc func = NULL;
3211 MSymbol module, func_name;
3212 MPlist *func_args, *val;
3215 module = MPLIST_SYMBOL (args);
3216 args = MPLIST_NEXT (args);
3217 func_name = MPLIST_SYMBOL (args);
3219 if (im_info->externals)
3221 MIMExternalModule *external
3222 = (MIMExternalModule *) mplist_get (im_info->externals,
3225 func = ((MIMExternalFunc)
3226 mplist_get_func (external->func_list, func_name));
3230 func_args = mplist ();
3231 mplist_add (func_args, Mt, ic);
3232 MPLIST_DO (args, MPLIST_NEXT (args))
3236 if (MPLIST_KEY (args) == Msymbol
3237 && MPLIST_KEY (args) != Mnil
3238 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3240 code = new_index (ic, ic->cursor_pos,
3241 mtext_nchars (ic->preedit),
3242 MPLIST_SYMBOL (args), ic->preedit);
3243 mplist_add (func_args, Minteger, (void *) code);
3246 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3248 val = (func) (func_args);
3249 M17N_OBJECT_UNREF (func_args);
3250 if (val && ! MPLIST_TAIL_P (val))
3251 ret = take_action_list (ic, val);
3252 M17N_OBJECT_UNREF (val);
3256 else if (name == Mshift)
3258 shift_state (ic, MPLIST_SYMBOL (args));
3260 else if (name == Mundo)
3262 int intarg = (MPLIST_TAIL_P (args)
3264 : integer_value (ic, args, NULL, 0));
3266 mtext_reset (ic->preedit);
3267 mtext_reset (ic_info->preedit_saved);
3268 mtext_reset (ic->produced);
3269 M17N_OBJECT_UNREF (ic_info->vars);
3270 ic_info->vars = mplist_copy (ic_info->vars_saved);
3271 ic->cursor_pos = ic_info->state_pos = 0;
3272 ic_info->state_key_head = ic_info->key_head
3273 = ic_info->commit_key_head = 0;
3275 shift_state (ic, Mnil);
3278 if (MPLIST_TAIL_P (args))
3283 ic_info->used += intarg;
3286 ic_info->used = intarg;
3289 else if (name == Mset || name == Madd || name == Msub
3290 || name == Mmul || name == Mdiv)
3292 MSymbol sym = MPLIST_SYMBOL (args);
3297 val1 = integer_value (ic, args, &value, 0);
3298 args = MPLIST_NEXT (args);
3299 val2 = resolve_expression (ic, args);
3301 val1 = val2, op = "=";
3302 else if (name == Madd)
3303 val1 += val2, op = "+=";
3304 else if (name == Msub)
3305 val1 -= val2, op = "-=";
3306 else if (name == Mmul)
3307 val1 *= val2, op = "*=";
3309 val1 /= val2, op = "/=";
3310 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3311 MSYMBOL_NAME (sym), op, val1, val1);
3313 mplist_set (value, Minteger, (void *) val1);
3315 else if (name == Mequal || name == Mless || name == Mgreater
3316 || name == Mless_equal || name == Mgreater_equal)
3319 MPlist *actions1, *actions2;
3322 val1 = resolve_expression (ic, args);
3323 args = MPLIST_NEXT (args);
3324 val2 = resolve_expression (ic, args);
3325 args = MPLIST_NEXT (args);
3326 actions1 = MPLIST_PLIST (args);
3327 args = MPLIST_NEXT (args);
3328 if (MPLIST_TAIL_P (args))
3331 actions2 = MPLIST_PLIST (args);
3332 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3333 if (name == Mequal ? val1 == val2
3334 : name == Mless ? val1 < val2
3335 : name == Mgreater ? val1 > val2
3336 : name == Mless_equal ? val1 <= val2
3339 MDEBUG_PRINT ("ok");
3340 ret = take_action_list (ic, actions1);
3344 MDEBUG_PRINT ("no");
3346 ret = take_action_list (ic, actions2);
3351 else if (name == Mcond)
3355 MPLIST_DO (args, args)
3360 if (! MPLIST_PLIST (args))
3362 cond = MPLIST_PLIST (args);
3363 if (resolve_expression (ic, cond) != 0)
3365 MDEBUG_PRINT1 ("(%dth)", idx);
3366 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3372 else if (name == Mcommit)
3374 preedit_commit (ic, 0);
3376 else if (name == Munhandle)
3378 preedit_commit (ic, 0);
3383 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3387 && (actions = mplist_get (im_info->macros, name)))
3389 if (take_action_list (ic, actions) < 0)
3395 if (ic->candidate_list)
3397 M17N_OBJECT_UNREF (ic->candidate_list);
3398 ic->candidate_list = NULL;
3400 if (ic->cursor_pos > 0
3401 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3404 ic->candidate_list = mtext_property_value (prop);
3405 M17N_OBJECT_REF (ic->candidate_list);
3407 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3409 ic->candidate_from = mtext_property_start (prop);
3410 ic->candidate_to = mtext_property_end (prop);
3413 if (candidate_list != ic->candidate_list)
3414 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3415 if (candidate_index != ic->candidate_index)
3416 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3417 if (candidate_show != ic->candidate_show)
3418 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3423 /* Handle the input key KEY in the current state and map specified in
3424 the input context IC. If KEY is handled correctly, return 0.
3425 Otherwise, return -1. */
3428 handle_key (MInputContext *ic)
3430 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3431 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3432 MIMMap *map = ic_info->map;
3433 MIMMap *submap = NULL;
3434 MSymbol key = ic_info->keys[ic_info->key_head];
3435 MSymbol alias = Mnil;
3438 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3439 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3443 submap = mplist_get (map->submaps, key);
3446 && (alias = msymbol_get (alias, M_key_alias))
3448 submap = mplist_get (map->submaps, alias);
3453 if (! alias || alias == key)
3454 MDEBUG_PRINT (" submap-found");
3456 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3457 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3458 ic->preedit_changed = 1;
3459 ic->cursor_pos = ic_info->state_pos;
3460 ic_info->key_head++;
3461 ic_info->map = map = submap;
3462 if (map->map_actions)
3464 MDEBUG_PRINT (" map-actions:");
3465 if (take_action_list (ic, map->map_actions) < 0)
3467 MDEBUG_PRINT ("\n");
3471 else if (map->submaps)
3473 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3475 MSymbol key = ic_info->keys[i];
3476 char *name = msymbol_name (key);
3478 if (! name[0] || ! name[1])
3479 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3483 /* If this is the terminal map or we have shifted to another
3484 state, perform branch actions (if any). */
3485 if (! map->submaps || map != ic_info->map)
3487 if (map->branch_actions)
3489 MDEBUG_PRINT (" branch-actions:");
3490 if (take_action_list (ic, map->branch_actions) < 0)
3492 MDEBUG_PRINT ("\n");
3496 /* If MAP is still not the root map, shift to the current
3498 if (ic_info->map != ic_info->state->map)
3499 shift_state (ic, ic_info->state->name);
3504 /* MAP can not handle KEY. */
3506 /* Perform branch actions if any. */
3507 if (map->branch_actions)
3509 MDEBUG_PRINT (" branch-actions:");
3510 if (take_action_list (ic, map->branch_actions) < 0)
3512 MDEBUG_PRINT ("\n");
3517 if (map == ic_info->map)
3519 /* The above branch actions didn't change the state. */
3521 /* If MAP is the root map of the initial state, and there
3522 still exist an unhandled key, it means that the current
3523 input method can not handle it. */
3524 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3525 && ic_info->key_head < ic_info->used)
3527 MDEBUG_PRINT (" unhandled\n");
3531 if (map != ic_info->state->map)
3533 /* MAP is not the root map. Shift to the root map of the
3535 shift_state (ic, ic_info->state->name);
3537 else if (! map->branch_actions)
3539 /* MAP is the root map without any default branch
3540 actions. Shift to the initial state. */
3541 shift_state (ic, Mnil);
3545 MDEBUG_PRINT ("\n");
3549 /* Initialize IC->ic_info. */
3552 init_ic_info (MInputContext *ic)
3554 MInputMethodInfo *im_info = ic->im->info;
3555 MInputContextInfo *ic_info = ic->info;
3558 MLIST_INIT1 (ic_info, keys, 8);;
3560 ic_info->markers = mplist ();
3562 ic_info->vars = mplist ();
3563 if (im_info->configured_vars)
3564 MPLIST_DO (plist, im_info->configured_vars)
3566 MPlist *pl = MPLIST_PLIST (plist);
3567 MSymbol name = MPLIST_SYMBOL (pl);
3569 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3570 if (MPLIST_KEY (pl) != Mt)
3572 MPlist *p = mplist ();
3574 mplist_push (ic_info->vars, Mplist, p);
3575 M17N_OBJECT_UNREF (p);
3576 mplist_add (p, Msymbol, name);
3577 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3580 ic_info->vars_saved = mplist_copy (ic_info->vars);
3582 if (im_info->externals)
3584 MPlist *func_args = mplist (), *plist;
3586 mplist_add (func_args, Mt, ic);
3587 MPLIST_DO (plist, im_info->externals)
3589 MIMExternalModule *external = MPLIST_VAL (plist);
3590 MIMExternalFunc func
3591 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3596 M17N_OBJECT_UNREF (func_args);
3599 ic_info->preedit_saved = mtext ();
3600 ic_info->tick = im_info->tick;
3603 /* Finalize IC->ic_info. */
3606 fini_ic_info (MInputContext *ic)
3608 MInputMethodInfo *im_info = ic->im->info;
3609 MInputContextInfo *ic_info = ic->info;
3611 if (im_info->externals)
3613 MPlist *func_args = mplist (), *plist;
3615 mplist_add (func_args, Mt, ic);
3616 MPLIST_DO (plist, im_info->externals)
3618 MIMExternalModule *external = MPLIST_VAL (plist);
3619 MIMExternalFunc func
3620 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3625 M17N_OBJECT_UNREF (func_args);
3628 MLIST_FREE1 (ic_info, keys);
3629 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3630 M17N_OBJECT_UNREF (ic_info->markers);
3631 M17N_OBJECT_UNREF (ic_info->vars);
3632 M17N_OBJECT_UNREF (ic_info->vars_saved);
3633 M17N_OBJECT_UNREF (ic_info->preceding_text);
3634 M17N_OBJECT_UNREF (ic_info->following_text);
3636 memset (ic_info, 0, sizeof (MInputContextInfo));
3640 re_init_ic (MInputContext *ic, int reload)
3642 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3643 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3644 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3646 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3647 preedit_changed = mtext_nchars (ic->preedit) > 0;
3648 cursor_pos_changed = ic->cursor_pos > 0;
3649 candidates_changed = 0;
3650 if (ic->candidate_list)
3652 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3653 M17N_OBJECT_UNREF (ic->candidate_list);
3654 ic->candidate_list = NULL;
3656 if (ic->candidate_show)
3658 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3659 ic->candidate_show = 0;
3661 if (ic->candidate_index > 0)
3663 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3664 ic->candidate_index = 0;
3665 ic->candidate_from = ic->candidate_to = 0;
3667 if (mtext_nchars (ic->produced) > 0)
3668 mtext_reset (ic->produced);
3669 if (mtext_nchars (ic->preedit) > 0)
3670 mtext_reset (ic->preedit);
3672 M17N_OBJECT_UNREF (ic->plist);
3673 ic->plist = mplist ();
3677 reload_im_info (im_info);
3678 if (! im_info->states)
3680 struct MIMState *state;
3682 M17N_OBJECT (state, free_state, MERROR_IM);
3683 state->name = msymbol ("init");
3684 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3685 MSTRUCT_CALLOC (state->map, MERROR_IM);
3686 im_info->states = mplist ();
3687 mplist_add (im_info->states, state->name, state);
3690 shift_state (ic, Mnil);
3692 ic->status_changed = status_changed;
3693 ic->preedit_changed = preedit_changed;
3694 ic->cursor_pos_changed = cursor_pos_changed;
3695 ic->candidates_changed = candidates_changed;
3699 reset_ic (MInputContext *ic, MSymbol ignore)
3701 MDEBUG_PRINT ("\n [IM] reset\n");
3706 open_im (MInputMethod *im)
3708 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3710 if (! im_info || ! im_info->states)
3711 MERROR (MERROR_IM, -1);
3718 close_im (MInputMethod *im)
3724 create_ic (MInputContext *ic)
3726 MInputContextInfo *ic_info;
3728 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3731 shift_state (ic, Mnil);
3736 destroy_ic (MInputContext *ic)
3743 check_reload (MInputContext *ic, MSymbol key)
3745 MInputMethodInfo *im_info = ic->im->info;
3746 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3750 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3754 MPLIST_DO (plist, plist)
3756 MSymbol this_key, alias;
3758 if (MPLIST_MTEXT_P (plist))
3760 MText *mt = MPLIST_MTEXT (plist);
3761 int c = mtext_ref_char (mt, 0);
3765 this_key = one_char_symbol[c];
3769 MPlist *pl = MPLIST_PLIST (plist);
3771 this_key = MPLIST_SYMBOL (pl);
3775 && (alias = msymbol_get (alias, M_key_alias))
3776 && alias != this_key);
3780 if (MPLIST_TAIL_P (plist))
3783 MDEBUG_PRINT ("\n [IM] reload");
3789 /** Handle the input key KEY in the current state and map of IC->info.
3790 If KEY is handled but no text is produced, return 0, otherwise
3796 filter (MInputContext *ic, MSymbol key, void *arg)
3798 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3799 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3802 if (check_reload (ic, key))
3805 if (! ic_info->state)
3807 ic_info->key_unhandled = 1;
3810 mtext_reset (ic->produced);
3811 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3812 M17N_OBJECT_UNREF (ic_info->preceding_text);
3813 M17N_OBJECT_UNREF (ic_info->following_text);
3814 ic_info->preceding_text = ic_info->following_text = NULL;
3815 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3816 ic_info->key_unhandled = 0;
3819 if (handle_key (ic) < 0)
3821 /* KEY was not handled. Delete it from the current key sequence. */
3822 if (ic_info->used > 0)
3824 memmove (ic_info->keys, ic_info->keys + 1,
3825 sizeof (int) * (ic_info->used - 1));
3827 if (ic_info->state_key_head > 0)
3828 ic_info->state_key_head--;
3829 if (ic_info->commit_key_head > 0)
3830 ic_info->commit_key_head--;
3832 /* This forces returning 1. */
3833 ic_info->key_unhandled = 1;
3839 reset_ic (ic, Mnil);
3840 ic_info->key_unhandled = 1;
3843 /* Break the loop if all keys were handled. */
3844 } while (ic_info->key_head < ic_info->used);
3846 /* If the current map is the root of the initial state, we should
3847 produce any preedit text in ic->produced. */
3848 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3849 preedit_commit (ic, 1);
3851 if (mtext_nchars (ic->produced) > 0)
3855 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3856 MSYMBOL_NAME (ic_info->state->name));
3857 for (i = 0; i < mtext_nchars (ic->produced); i++)
3858 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3862 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3863 Mlanguage, ic->im->language);
3865 if (ic_info->commit_key_head > 0)
3867 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3868 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3869 ic_info->used -= ic_info->commit_key_head;
3870 ic_info->key_head -= ic_info->commit_key_head;
3871 ic_info->state_key_head -= ic_info->commit_key_head;
3872 ic_info->commit_key_head = 0;
3874 if (ic_info->key_unhandled)
3877 ic_info->key_head = ic_info->state_key_head
3878 = ic_info->commit_key_head = 0;
3881 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3885 /** Return 1 if the last event or key was not handled, otherwise
3888 There is no need of looking up because ic->produced should already
3889 contain the produced text (if any).
3894 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3896 mtext_cat (mt, ic->produced);
3897 mtext_reset (ic->produced);
3898 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3902 /* Input method command handler. */
3904 /* List of all (global and local) commands.
3905 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3906 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3907 Global commands are stored as (t (t COMMAND ...)) */
3910 /* Input method variable handler. */
3913 /* Support functions for mdebug_dump_im. */
3916 dump_im_map (MPlist *map_list, int indent)
3919 MSymbol key = MPLIST_KEY (map_list);
3920 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3922 prefix = (char *) alloca (indent + 1);
3923 memset (prefix, 32, indent);
3924 prefix[indent] = '\0';
3926 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3927 if (map->map_actions)
3928 mdebug_dump_plist (map->map_actions, indent + 2);
3931 MPLIST_DO (map_list, map->submaps)
3933 fprintf (stderr, "\n%s ", prefix);
3934 dump_im_map (map_list, indent + 2);
3937 if (map->branch_actions)
3939 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3940 mdebug_dump_plist (map->branch_actions, indent + 4);
3941 fprintf (stderr, ")");
3943 fprintf (stderr, ")");
3948 dump_im_state (MIMState *state, int indent)
3953 prefix = (char *) alloca (indent + 1);
3954 memset (prefix, 32, indent);
3955 prefix[indent] = '\0';
3957 fprintf (stderr, "(%s", msymbol_name (state->name));
3958 if (state->map->submaps)
3960 MPLIST_DO (map_list, state->map->submaps)
3962 fprintf (stderr, "\n%s ", prefix);
3963 dump_im_map (map_list, indent + 2);
3966 fprintf (stderr, ")");
3974 Minput_driver = msymbol ("input-driver");
3976 Minput_preedit_start = msymbol ("input-preedit-start");
3977 Minput_preedit_done = msymbol ("input-preedit-done");
3978 Minput_preedit_draw = msymbol ("input-preedit-draw");
3979 Minput_status_start = msymbol ("input-status-start");
3980 Minput_status_done = msymbol ("input-status-done");
3981 Minput_status_draw = msymbol ("input-status-draw");
3982 Minput_candidates_start = msymbol ("input-candidates-start");
3983 Minput_candidates_done = msymbol ("input-candidates-done");
3984 Minput_candidates_draw = msymbol ("input-candidates-draw");
3985 Minput_set_spot = msymbol ("input-set-spot");
3986 Minput_focus_move = msymbol ("input-focus-move");
3987 Minput_focus_in = msymbol ("input-focus-in");
3988 Minput_focus_out = msymbol ("input-focus-out");
3989 Minput_toggle = msymbol ("input-toggle");
3990 Minput_reset = msymbol ("input-reset");
3991 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3992 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3993 Mcustomized = msymbol ("customized");
3994 Mconfigured = msymbol ("configured");
3995 Minherited = msymbol ("inherited");
3997 minput_default_driver.open_im = open_im;
3998 minput_default_driver.close_im = close_im;
3999 minput_default_driver.create_ic = create_ic;
4000 minput_default_driver.destroy_ic = destroy_ic;
4001 minput_default_driver.filter = filter;
4002 minput_default_driver.lookup = lookup;
4003 minput_default_driver.callback_list = mplist ();
4004 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4005 M17N_FUNC (reset_ic));
4006 minput_driver = &minput_default_driver;
4008 fully_initialized = 0;
4015 if (fully_initialized)
4017 free_im_list (im_info_list);
4019 free_im_list (im_custom_list);
4021 free_im_list (im_config_list);
4022 M17N_OBJECT_UNREF (load_im_info_keys);
4025 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4026 M17N_OBJECT_UNREF (minput_driver->callback_list);
4031 minput__char_to_key (int c)
4033 if (c < 0 || c >= 0x100)
4036 return one_char_symbol[c];
4040 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4045 /*** @addtogroup m17nInputMethod */
4050 @name Variables: Predefined symbols for callback commands.
4052 These are the predefined symbols that are used as the @c COMMAND
4053 argument of callback functions of an input method driver (see
4054 #MInputDriver::callback_list).
4056 Most of them do not require extra argument nor return any value;
4057 exceptions are these:
4059 Minput_get_surrounding_text: When a callback function assigned for
4060 this command is called, the first element of #MInputContext::plist
4061 has key #Minteger and the value specifies which portion of the
4062 surrounding text should be retrieved. If the value is positive,
4063 it specifies the number of characters following the current cursor
4064 position. If the value is negative, the absolute value specifies
4065 the number of characters preceding the current cursor position.
4066 If the value is zero, it means that the caller just wants to know
4067 if the surrounding text is currently supported or not.
4069 If the surrounding text is currently supported, the callback
4070 function must set the key of this element to #Mtext and the value
4071 to the retrieved M-text. The length of the M-text may be shorter
4072 than the requested number of characters, if the available text is
4073 not that long. The length can be zero in the worst case. Or, the
4074 length may be longer if an application thinks it is more efficient
4075 to return that length.
4077 If the surrounding text is not currently supported, the callback
4078 function should return without changing the first element of
4079 #MInputContext::plist.
4081 Minput_delete_surrounding_text: When a callback function assigned
4082 for this command is called, the first element of
4083 #MInputContext::plist has key #Minteger and the value specifies
4084 which portion of the surrounding text should be deleted in the
4085 same way as the case of Minput_get_surrounding_text. The callback
4086 function must delete the specified text. It should not alter
4087 #MInputContext::plist. */
4089 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4091 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4092 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4094 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4096 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4097 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4098 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4099 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4100 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4101 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4102 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4104 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4105 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4106 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4107 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4108 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4110 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4111 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4113 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4114 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4115 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4116 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4117 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4118 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4122 MSymbol Minput_preedit_start;
4123 MSymbol Minput_preedit_done;
4124 MSymbol Minput_preedit_draw;
4125 MSymbol Minput_status_start;
4126 MSymbol Minput_status_done;
4127 MSymbol Minput_status_draw;
4128 MSymbol Minput_candidates_start;
4129 MSymbol Minput_candidates_done;
4130 MSymbol Minput_candidates_draw;
4131 MSymbol Minput_set_spot;
4132 MSymbol Minput_toggle;
4133 MSymbol Minput_reset;
4134 MSymbol Minput_get_surrounding_text;
4135 MSymbol Minput_delete_surrounding_text;
4141 @name Variables: Predefined symbols for special input events.
4143 These are the predefined symbols that are used as the @c KEY
4144 argument of minput_filter (). */
4146 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4148 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4153 MSymbol Minput_focus_out;
4154 MSymbol Minput_focus_in;
4155 MSymbol Minput_focus_move;
4161 @name Variables: Predefined symbols used in input method information.
4163 These are the predefined symbols describing status of input method
4164 command and variable, and are used in a return value of
4165 minput_get_command () and minput_get_variable (). */
4167 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4169 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4170 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4174 MSymbol Mcustomized;
4175 MSymbol Mconfigured;
4181 @brief The default driver for internal input methods.
4183 The variable #minput_default_driver is the default driver for
4184 internal input methods.
4186 The member MInputDriver::open_im () searches the m17n database for
4187 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4188 $NAME\> and loads it.
4190 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4191 programmers responsibility to set it to a plist of proper callback
4192 functions. Otherwise, no feedback information (e.g. preedit text)
4193 can be shown to users.
4195 The macro M17N_INIT () sets the variable #minput_driver to the
4196 pointer to this driver so that all internal input methods use it.
4198 Therefore, unless @c minput_driver is set differently, the driver
4199 dependent arguments $ARG of the functions whose name begins with
4200 "minput_" are all ignored. */
4202 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4204 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4206 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4207 \< #Minput_method, $LANGUAGE, $NAME\>
4208 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4210 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4211 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4212 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4213 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4215 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4216 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4218 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4219 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4221 MInputDriver minput_default_driver;
4225 @brief The driver for internal input methods.
4227 The variable #minput_driver is a pointer to the input method
4228 driver that is used by internal input methods. The macro
4229 M17N_INIT () initializes it to a pointer to #minput_default_driver
4230 if <m17n<EM></EM>.h> is included. */
4232 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4234 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4235 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4236 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4237 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4239 MInputDriver *minput_driver;
4241 MSymbol Minput_driver;
4256 @brief Open an input method.
4258 The minput_open_im () function opens an input method whose
4259 language and name match $LANGUAGE and $NAME, and returns a pointer
4260 to the input method object newly allocated.
4262 This function at first decides a driver for the input method as
4265 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4266 #minput_driver is used.
4268 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4269 driver pointed to by the property value is used to open the input
4270 method. If $NAME has no such a property, @c NULL is returned.
4272 Then, the member MInputDriver::open_im () of the driver is
4275 $ARG is set in the member @c arg of the structure MInputMethod so
4276 that the driver can refer to it. */
4278 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4280 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4281 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4283 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4285 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4286 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4288 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4289 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4290 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4292 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4294 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4296 @latexonly \IPAlabel{minput_open} @endlatexonly
4301 minput_open_im (MSymbol language, MSymbol name, void *arg)
4304 MInputDriver *driver;
4308 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4309 msymbol_name (language), msymbol_name (name));
4311 driver = minput_driver;
4314 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4316 MERROR (MERROR_IM, NULL);
4319 MSTRUCT_CALLOC (im, MERROR_IM);
4320 im->language = language;
4323 im->driver = *driver;
4324 if ((*im->driver.open_im) (im) < 0)
4326 MDEBUG_PRINT (" failed\n");
4330 MDEBUG_PRINT (" ok\n");
4337 @brief Close an input method.
4339 The minput_close_im () function closes the input method $IM, which
4340 must have been created by minput_open_im (). */
4343 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4345 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4346 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4349 minput_close_im (MInputMethod *im)
4351 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4352 msymbol_name (im->name), msymbol_name (im->language));
4353 (*im->driver.close_im) (im);
4355 MDEBUG_PRINT (" done\n");
4361 @brief Create an input context.
4363 The minput_create_ic () function creates an input context object
4364 associated with input method $IM, and calls callback functions
4365 corresponding to #Minput_preedit_start, #Minput_status_start, and
4366 #Minput_status_draw in this order.
4369 If an input context is successfully created, minput_create_ic ()
4370 returns a pointer to it. Otherwise it returns @c NULL. */
4373 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4375 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4376 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4377 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4378 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4381 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4382 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4386 minput_create_ic (MInputMethod *im, void *arg)
4390 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4391 msymbol_name (im->name), msymbol_name (im->language));
4392 MSTRUCT_CALLOC (ic, MERROR_IM);
4395 ic->preedit = mtext ();
4396 ic->candidate_list = NULL;
4397 ic->produced = mtext ();
4398 ic->spot.x = ic->spot.y = 0;
4400 ic->plist = mplist ();
4401 if ((*im->driver.create_ic) (ic) < 0)
4403 MDEBUG_PRINT (" failed\n");
4404 M17N_OBJECT_UNREF (ic->preedit);
4405 M17N_OBJECT_UNREF (ic->produced);
4406 M17N_OBJECT_UNREF (ic->plist);
4411 if (im->driver.callback_list)
4413 minput_callback (ic, Minput_preedit_start);
4414 minput_callback (ic, Minput_status_start);
4415 minput_callback (ic, Minput_status_draw);
4418 MDEBUG_PRINT (" ok\n");
4425 @brief Destroy an input context.
4427 The minput_destroy_ic () function destroys the input context $IC,
4428 which must have been created by minput_create_ic (). It calls
4429 callback functions corresponding to #Minput_preedit_done,
4430 #Minput_status_done, and #Minput_candidates_done in this order. */
4433 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4435 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4436 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4437 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4438 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4439 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4443 minput_destroy_ic (MInputContext *ic)
4445 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4446 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4447 if (ic->im->driver.callback_list)
4449 minput_callback (ic, Minput_preedit_done);
4450 minput_callback (ic, Minput_status_done);
4451 minput_callback (ic, Minput_candidates_done);
4453 (*ic->im->driver.destroy_ic) (ic);
4454 M17N_OBJECT_UNREF (ic->preedit);
4455 M17N_OBJECT_UNREF (ic->produced);
4456 M17N_OBJECT_UNREF (ic->plist);
4457 MDEBUG_PRINT (" done\n");
4464 @brief Filter an input key.
4466 The minput_filter () function filters input key $KEY according to
4467 input context $IC, and calls callback functions corresponding to
4468 #Minput_preedit_draw, #Minput_status_draw, and
4469 #Minput_candidates_draw if the preedit text, the status, and the
4470 current candidate are changed respectively.
4472 To make the input method commit the current preedit text (if any)
4473 and shift to the initial state, call this function with #Mnil as
4476 To inform the input method about the focus-out event, call this
4477 function with #Minput_focus_out as $KEY.
4479 To inform the input method about the focus-in event, call this
4480 function with #Minput_focus_in as $KEY.
4482 To inform the input method about the focus-move event (i.e. input
4483 spot change within the same input context), call this function
4484 with #Minput_focus_move as $KEY.
4487 If $KEY is filtered out, this function returns 1. In that case,
4488 the caller should discard the key. Otherwise, it returns 0, and
4489 the caller should handle the key, for instance, by calling the
4490 function minput_lookup () with the same key. */
4493 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4495 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4496 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4497 #Minput_preedit_draw, #Minput_status_draw,
4498 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4501 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4502 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4503 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4504 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4506 @latexonly \IPAlabel{minput_filter} @endlatexonly
4510 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4517 if (ic->im->driver.callback_list
4518 && mtext_nchars (ic->preedit) > 0)
4519 minput_callback (ic, Minput_preedit_draw);
4521 ret = (*ic->im->driver.filter) (ic, key, arg);
4523 if (ic->im->driver.callback_list)
4525 if (ic->preedit_changed)
4526 minput_callback (ic, Minput_preedit_draw);
4527 if (ic->status_changed)
4528 minput_callback (ic, Minput_status_draw);
4529 if (ic->candidates_changed)
4530 minput_callback (ic, Minput_candidates_draw);
4539 @brief Look up a text produced in the input context.
4541 The minput_lookup () function looks up a text in the input context
4542 $IC. $KEY must be identical to the one that was used in the previous call of
4545 If a text was produced by the input method, it is concatenated
4548 This function calls #MInputDriver::lookup .
4551 If $KEY was correctly handled by the input method, this function
4552 returns 0. Otherwise, it returns -1, even though some text
4553 might be produced in $MT. */
4556 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4558 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4559 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4561 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4564 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4567 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4568 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4569 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4571 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4574 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4576 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4581 @brief Set the spot of the input context.
4583 The minput_set_spot () function sets the spot of input context $IC
4584 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4585 The semantics of these values depends on the input method driver.
4587 For instance, a driver designed to work in a CUI environment may
4588 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4589 $DESCENT . A driver designed to work in a window system may
4590 interpret $X and $Y as the pixel offsets relative to the origin of the
4591 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4592 descent pixels of the line at ($X . $Y ).
4594 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4596 $MT and $POS are the M-text and the character position at the spot.
4597 $MT may be @c NULL, in which case, the input method cannot get
4598 information about the text around the spot. */
4601 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4603 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4604 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4605 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4607 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4608 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4609 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4610 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4611 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4612 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4614 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4616 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4617 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4621 minput_set_spot (MInputContext *ic, int x, int y,
4622 int ascent, int descent, int fontsize,
4627 ic->spot.ascent = ascent;
4628 ic->spot.descent = descent;
4629 ic->spot.fontsize = fontsize;
4632 if (ic->im->driver.callback_list)
4633 minput_callback (ic, Minput_set_spot);
4638 @brief Toggle input method.
4640 The minput_toggle () function toggles the input method associated
4641 with input context $IC. */
4643 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4645 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4646 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4650 minput_toggle (MInputContext *ic)
4652 if (ic->im->driver.callback_list)
4653 minput_callback (ic, Minput_toggle);
4654 ic->active = ! ic->active;
4660 @brief Reset an input context.
4662 The minput_reset_ic () function resets input context $IC by
4663 calling a callback function corresponding to #Minput_reset. It
4664 resets the status of $IC to its initial one. As the
4665 current preedit text is deleted without commitment, if necessary,
4666 call minput_filter () with the arg @r key #Mnil to force the input
4667 method to commit the preedit in advance. */
4670 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4672 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4673 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4674 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4675 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4676 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4677 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4680 minput_reset_ic (MInputContext *ic)
4682 if (ic->im->driver.callback_list)
4683 minput_callback (ic, Minput_reset);
4689 @brief Get title and icon filename of an input method.
4691 The minput_get_title_icon () function returns a plist containing a
4692 title and icon filename (if any) of an input method specified by
4693 $LANGUAGE and $NAME.
4695 The first element of the plist has key #Mtext and the value is an
4696 M-text of the title for identifying the input method. The second
4697 element (if any) has key #Mtext and the value is an M-text of the
4698 icon image (absolute) filename for the same purpose.
4701 If there exists a specified input method and it defines an title,
4702 a plist is returned. Otherwise, NULL is returned. The caller
4703 must free the plist by m17n_object_unref (). */
4705 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4707 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4708 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4711 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4712 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4713 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4716 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4717 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4718 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4721 minput_get_title_icon (MSymbol language, MSymbol name)
4723 MInputMethodInfo *im_info;
4730 im_info = get_im_info (language, name, Mnil, Mtitle);
4731 if (! im_info || !im_info->title)
4733 mt = mtext_get_prop (im_info->title, 0, Mtext);
4735 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4738 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4741 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4742 (char *) MSYMBOL_NAME (name));
4743 file = mdatabase__find_file (buf);
4744 if (! file && language == Mt)
4746 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4747 file = mdatabase__find_file (buf);
4752 mplist_add (plist, Mtext, im_info->title);
4755 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4757 mplist_add (plist, Mtext, mt);
4758 M17N_OBJECT_UNREF (mt);
4766 @brief Get description text of an input method.
4768 The minput_get_description () function returns an M-text that
4769 describes the input method specified by $LANGUAGE and $NAME.
4772 If the specified input method has a description text, a pointer to
4773 #MText is returned. The caller has to free it by m17n_object_unref ().
4774 If the input method does not have a description text, @c NULL is
4777 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4779 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4780 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4782 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4783 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4784 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4785 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4788 minput_get_description (MSymbol language, MSymbol name)
4790 MInputMethodInfo *im_info;
4798 extra = language, language = Mt;
4800 im_info = get_im_info (language, name, extra, Mdescription);
4801 if (! im_info || ! im_info->description)
4803 M17N_OBJECT_REF (im_info->description);
4804 return im_info->description;
4810 @brief Get information about input method command(s).
4812 The minput_get_command () function returns information about
4813 the command $COMMAND of the input method specified by $LANGUAGE and
4814 $NAME. An input method command is a pseudo key event to which one
4815 or more actual input key sequences are assigned.
4817 There are two kinds of commands, global and local. A global
4818 command has a global definition, and the description and the key
4819 assignment may be inherited by a local command. Each input method
4820 defines a local command which has a local key assignment. It may
4821 also declare a local command that inherits the definition of a
4822 global command of the same name.
4824 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4825 information about a global command. Otherwise information about a
4826 local command is returned.
4828 If $COMMAND is #Mnil, information about all commands is returned.
4830 The return value is a @e well-formed plist (@ref m17nPlist) of this
4833 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4835 @c NAME is a symbol representing the command name.
4837 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4838 command has no description.
4840 @c STATUS is a symbol representing how the key assignment is decided.
4841 The value is #Mnil (the default key assignment), #Mcustomized (the
4842 key assignment is customized by per-user customization file), or
4843 #Mconfigured (the key assignment is set by the call of
4844 minput_config_command ()). For a local command only, it may also
4845 be #Minherited (the key assignment is inherited from the
4846 corresponding global command).
4848 @c KEYSEQ is a plist of one or more symbols representing a key
4849 sequence assigned to the command. If there's no KEYSEQ, the
4850 command is currently disabled (i.e. no key sequence can trigger
4851 actions of the command).
4853 If $COMMAND is not #Mnil, the first element of the returned plist
4854 contains the information about $COMMAND.
4858 If the requested information was found, a pointer to a non-empty
4859 plist is returned. As the plist is kept in the library, the
4860 caller must not modify nor free it.
4862 Otherwise (the specified input method or the specified command
4863 does not exist), @c NULL is returned. */
4865 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4867 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4868 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4869 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4870 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4872 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4873 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4874 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4875 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4876 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4878 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4879 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4882 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4884 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4887 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4889 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4891 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4894 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4895 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4896 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4897 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4898 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4899 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4902 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4903 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4904 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4905 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4907 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4908 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4912 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4913 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4916 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4921 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4923 /* Return a description of the command COMMAND of the input method
4924 specified by LANGUAGE and NAME. */
4925 MPlist *cmd = minput_get_command (langauge, name, command);
4930 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4931 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4932 return (mplist_key (plist) == Mtext
4933 ? (MText *) mplist_value (plist)
4939 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4941 MInputMethodInfo *im_info;
4945 im_info = get_im_info (language, name, Mnil, Mcommand);
4947 || ! im_info->configured_cmds
4948 || MPLIST_TAIL_P (im_info->configured_cmds))
4950 if (command == Mnil)
4951 return im_info->configured_cmds;
4952 return mplist__assq (im_info->configured_cmds, command);
4958 @brief Configure the key sequence of an input method command.
4960 The minput_config_command () function assigns a list of key
4961 sequences $KEYSEQLIST to the command $COMMAND of the input method
4962 specified by $LANGUAGE and $NAME.
4964 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4965 sequences, and each key sequence must be a plist of symbols.
4967 If $KEYSEQLIST is an empty plist, any configuration and
4968 customization of the command are cancelled, and default key
4969 sequences become effective.
4971 If $KEYSEQLIST is NULL, the configuration of the command is
4972 canceled, and the original key sequences (what saved in per-user
4973 customization file, or the default one) become effective.
4975 In the latter two cases, $COMMAND can be #Mnil to make all the
4976 commands of the input method the target of the operation.
4978 If $NAME is #Mnil, this function configures the key assignment of a
4979 global command, not that of a specific input method.
4981 The configuration takes effect for input methods opened or
4982 re-opened later in the current session. In order to make the
4983 configuration take effect for the future session, it must be saved
4984 in a per-user customization file by the function
4985 minput_save_config ().
4988 If the operation was successful, this function returns 0,
4989 otherwise returns -1. The operation fails in these cases:
4991 <li>$KEYSEQLIST is not in a valid form.
4992 <li>$COMMAND is not available for the input method.
4993 <li>$LANGUAGE and $NAME do not specify an existing input method.
4997 minput_get_commands (), minput_save_config ().
5000 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5002 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5003 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5004 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5006 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5007 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5009 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5010 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5012 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5013 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5014 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5016 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5017 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5019 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5020 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5022 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5023 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5024 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5025 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5029 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5031 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5032 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5033 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5037 minput_get_commands (), minput_save_config ().
5041 /* Add "C-x u" to the "start" command of Unicode input method. */
5043 MSymbol start_command = msymbol ("start");
5044 MSymbol unicode = msymbol ("unicode");
5045 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5047 /* At first get the current key-sequence assignment. */
5048 cmd = minput_get_command (Mt, unicode, start_command);
5051 /* The input method does not have the command "start". Here
5052 should come some error handling code. */
5054 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5055 Extract the part (KEY-SEQUENCE ...). */
5056 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5057 /* Copy it because we should not modify it directly. */
5058 key_seq_list = mplist_copy (plist);
5060 key_seq = mplist ();
5061 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5062 mplist_add (key_seq, Msymbol, msymbol ("u"));
5063 mplist_add (key_seq_list, Mplist, key_seq);
5064 m17n_object_unref (key_seq);
5066 minput_config_command (Mt, unicode, start_command, key_seq_list);
5067 m17n_object_unref (key_seq_list);
5072 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5075 MInputMethodInfo *im_info, *config;
5080 im_info = get_im_info (language, name, Mnil, Mcommand);
5082 MERROR (MERROR_IM, -1);
5083 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5085 || ! mplist__assq (im_info->configured_cmds, command)))
5086 MERROR (MERROR_IM, -1);
5087 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5089 MPLIST_DO (plist, keyseqlist)
5090 if (! check_command_keyseq (plist))
5091 MERROR (MERROR_IM, -1);
5094 config = get_config_info (im_info);
5097 if (! im_config_list)
5098 im_config_list = mplist ();
5099 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5100 config->cmds = mplist ();
5101 config->vars = mplist ();
5104 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5105 /* Nothing to do. */
5108 if (command == Mnil)
5112 /* Cancal the configuration. */
5113 if (MPLIST_TAIL_P (config->cmds))
5115 mplist_set (config->cmds, Mnil, NULL);
5119 /* Cancal the customization. */
5120 MInputMethodInfo *custom = get_custom_info (im_info);
5122 if (MPLIST_TAIL_P (config->cmds)
5123 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5124 /* Nothing to do. */
5126 mplist_set (config->cmds, Mnil, NULL);
5127 MPLIST_DO (plist, custom->cmds)
5129 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5131 mplist_add (plist, Msymbol, command);
5132 mplist_push (config->cmds, Mplist, plist);
5133 M17N_OBJECT_UNREF (plist);
5139 plist = mplist__assq (config->cmds, command);
5142 /* Cancel the configuration. */
5145 mplist__pop_unref (plist);
5147 else if (MPLIST_TAIL_P (keyseqlist))
5149 /* Cancel the customization. */
5150 MInputMethodInfo *custom = get_custom_info (im_info);
5151 int no_custom = (! custom || ! custom->cmds
5152 || ! mplist__assq (custom->cmds, command));
5158 mplist_add (config->cmds, Mplist, plist);
5159 M17N_OBJECT_UNREF (plist);
5160 plist = mplist_add (plist, Msymbol, command);
5165 mplist__pop_unref (plist);
5168 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5169 plist = MPLIST_NEXT (plist);
5170 mplist_set (plist, Mnil, NULL);
5180 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5181 if (! MPLIST_TAIL_P (plist))
5182 mplist_set (plist, Mnil, NULL);
5187 mplist_add (config->cmds, Mplist, plist);
5188 M17N_OBJECT_UNREF (plist);
5189 plist = mplist_add (plist, Msymbol, command);
5190 plist = MPLIST_NEXT (plist);
5192 MPLIST_DO (keyseqlist, keyseqlist)
5194 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5195 plist = mplist_add (plist, Mplist, pl);
5196 M17N_OBJECT_UNREF (pl);
5200 config_all_commands (im_info);
5201 im_info->tick = time (NULL);
5208 @brief Get information about input method variable(s).
5210 The minput_get_variable () function returns information about
5211 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5212 An input method variable controls behavior of an input method.
5214 There are two kinds of variables, global and local. A global
5215 variable has a global definition, and the description and the value
5216 may be inherited by a local variable. Each input method defines a
5217 local variable which has local value. It may also declare a
5218 local variable that inherits definition of a global variable of
5221 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5222 variable is returned. Otherwise information about a local variable
5225 If $VARIABLE is #Mnil, information about all variables is
5228 The return value is a @e well-formed plist (@ref m17nPlist) of this
5231 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5233 @c NAME is a symbol representing the variable name.
5235 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5236 variable has no description.
5238 @c STATUS is a symbol representing how the value is decided. The
5239 value is #Mnil (the default value), #Mcustomized (the value is
5240 customized by per-user customization file), or #Mconfigured (the
5241 value is set by the call of minput_config_variable ()). For a
5242 local variable only, it may also be #Minherited (the value is
5243 inherited from the corresponding global variable).
5245 @c VALUE is the initial value of the variable. If the key of this
5246 element is #Mt, the variable has no initial value. Otherwise, the
5247 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5250 @c VALID-VALUEs (if any) specify which values the variable can have.
5251 They have the same type (i.e. having the same key) as @c VALUE except
5252 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5253 may be a plist of two integers specifying the range of possible
5256 If there no @c VALID-VALUE, the variable can have any value as long
5257 as the type is the same as @c VALUE.
5259 If $VARIABLE is not #Mnil, the first element of the returned plist
5260 contains the information about $VARIABLE.
5264 If the requested information was found, a pointer to a non-empty
5265 plist is returned. As the plist is kept in the library, the
5266 caller must not modify nor free it.
5268 Otherwise (the specified input method or the specified variable
5269 does not exist), @c NULL is returned. */
5271 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5273 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5274 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5275 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5277 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5278 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5279 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5280 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5283 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5284 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5286 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5288 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5290 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5293 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5295 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5298 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5299 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5300 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5301 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5302 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5303 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5305 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5306 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5307 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5309 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5310 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5311 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5312 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5314 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5317 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5318 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5322 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5323 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5326 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5330 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5332 MInputMethodInfo *im_info;
5336 im_info = get_im_info (language, name, Mnil, Mvariable);
5337 if (! im_info || ! im_info->configured_vars)
5339 if (variable == Mnil)
5340 return im_info->configured_vars;
5341 return mplist__assq (im_info->configured_vars, variable);
5347 @brief Configure the value of an input method variable.
5349 The minput_config_variable () function assigns $VALUE to the
5350 variable $VARIABLE of the input method specified by $LANGUAGE and
5353 If $VALUE is a non-empty plist, it must be a plist of one element
5354 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5355 the corresponding type. That value is assigned to the variable.
5357 If $VALUE is an empty plist, any configuration and customization
5358 of the variable are canceled, and the default value is assigned to
5361 If $VALUE is NULL, the configuration of the variable is canceled,
5362 and the original value (what saved in per-user customization file,
5363 or the default value) is assigned to the variable.
5365 In the latter two cases, $VARIABLE can be #Mnil to make all the
5366 variables of the input method the target of the operation.
5368 If $NAME is #Mnil, this function configures the value of global
5369 variable, not that of a specific input method.
5371 The configuration takes effect for input methods opened or
5372 re-opened later in the current session. To make the configuration
5373 take effect for the future session, it must be saved in a per-user
5374 customization file by the function minput_save_config ().
5378 If the operation was successful, this function returns 0,
5379 otherwise returns -1. The operation fails in these cases:
5381 <li>$VALUE is not in a valid form, the type does not match the
5382 definition, or the value is our of range.
5383 <li>$VARIABLE is not available for the input method.
5384 <li>$LANGUAGE and $NAME do not specify an existing input method.
5388 minput_get_variable (), minput_save_config (). */
5390 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5392 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5393 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5395 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5396 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5397 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5399 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5400 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5402 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5403 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5405 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5406 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5408 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5409 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5411 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5412 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5413 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5414 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5418 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5420 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5421 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5422 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5426 minput_get_commands (), minput_save_config ().
5429 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5432 MInputMethodInfo *im_info, *config;
5437 im_info = get_im_info (language, name, Mnil, Mvariable);
5439 MERROR (MERROR_IM, -1);
5440 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5442 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5443 MERROR (MERROR_IM, -1);
5445 if (value && ! MPLIST_TAIL_P (value))
5447 plist = MPLIST_PLIST (plist);
5448 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5449 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5450 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5451 if (MPLIST_KEY (plist) != Mt
5452 && ! check_variable_value (value, plist))
5453 MERROR (MERROR_IM, -1);
5456 config = get_config_info (im_info);
5459 if (! im_config_list)
5460 im_config_list = mplist ();
5461 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5462 config->cmds = mplist ();
5463 config->vars = mplist ();
5466 if (! value && MPLIST_TAIL_P (config->vars))
5467 /* Nothing to do. */
5470 if (variable == Mnil)
5474 /* Cancel the configuration. */
5475 if (MPLIST_TAIL_P (config->vars))
5477 mplist_set (config->vars, Mnil, NULL);
5481 /* Cancel the customization. */
5482 MInputMethodInfo *custom = get_custom_info (im_info);
5484 if (MPLIST_TAIL_P (config->vars)
5485 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5486 /* Nothing to do. */
5488 mplist_set (config->vars, Mnil, NULL);
5489 MPLIST_DO (plist, custom->vars)
5491 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5493 mplist_add (plist, Msymbol, variable);
5494 mplist_push (config->vars, Mplist, plist);
5495 M17N_OBJECT_UNREF (plist);
5501 plist = mplist__assq (config->vars, variable);
5504 /* Cancel the configuration. */
5507 mplist__pop_unref (plist);
5509 else if (MPLIST_TAIL_P (value))
5511 /* Cancel the customization. */
5512 MInputMethodInfo *custom = get_custom_info (im_info);
5513 int no_custom = (! custom || ! custom->vars
5514 || ! mplist__assq (custom->vars, variable));
5520 mplist_add (config->vars, Mplist, plist);
5521 M17N_OBJECT_UNREF (plist);
5522 plist = mplist_add (plist, Msymbol, variable);
5527 mplist__pop_unref (plist);
5530 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5531 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5532 mplist_set (plist, Mnil ,NULL);
5540 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5541 if (! MPLIST_TAIL_P (plist))
5542 mplist_set (plist, Mnil, NULL);
5547 mplist_add (config->vars, Mplist, plist);
5548 M17N_OBJECT_UNREF (plist);
5549 plist = mplist_add (plist, Msymbol, variable);
5550 plist = MPLIST_NEXT (plist);
5552 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5555 config_all_variables (im_info);
5556 im_info->tick = time (NULL);
5563 @brief Get the name of per-user customization file.
5565 The minput_config_file () function returns the absolute path name
5566 of per-user customization file into which minput_save_config ()
5567 save configurations. It is usually @c "config.mic" under the
5568 directory @c ".m17n.d" of user's home directory. It is not assured
5569 that the file of the returned name exists nor is
5570 readable/writable. If minput_save_config () fails and returns -1,
5571 an application program might check the file, make it
5572 writable (if possible), and try minput_save_config () again.
5576 This function returns a string. As the string is kept in the
5577 library, the caller must not modify nor free it.
5580 minput_save_config ()
5583 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5585 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5586 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5587 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5588 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5589 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5590 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5591 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5596 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5597 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5600 minput_save_config ()
5604 minput_config_file ()
5608 return mdatabase__file (im_custom_mdb);
5614 @brief Save configurations in per-user customization file.
5616 The minput_save_config () function saves the configurations done
5617 so far in the current session into the per-user customization
5622 If the operation was successful, 1 is returned. If the per-user
5623 customization file is currently locked, 0 is returned. In that
5624 case, the caller may wait for a while and try again. If the
5625 configuration file is not writable, -1 is returned. In that case,
5626 the caller may check the name of the file by calling
5627 minput_config_file (), make it writable if possible, and try
5631 minput_config_file () */
5633 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5635 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5636 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5640 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5641 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5642 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5643 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5647 minput_config_file () */
5650 minput_save_config (void)
5652 MPlist *data, *tail, *plist, *p, *elt;
5656 ret = mdatabase__lock (im_custom_mdb);
5659 if (! im_config_list)
5661 update_custom_info ();
5662 if (! im_custom_list)
5663 im_custom_list = mplist ();
5665 /* At first, reflect configuration in customization. */
5666 MPLIST_DO (plist, im_config_list)
5668 MPlist *pl = MPLIST_PLIST (plist);
5669 MSymbol language, name, extra, command, variable;
5670 MInputMethodInfo *custom, *config;
5672 language = MPLIST_SYMBOL (pl);
5673 pl = MPLIST_NEXT (pl);
5674 name = MPLIST_SYMBOL (pl);
5675 pl = MPLIST_NEXT (pl);
5676 extra = MPLIST_SYMBOL (pl);
5677 pl = MPLIST_NEXT (pl);
5678 config = MPLIST_VAL (pl);
5679 custom = get_custom_info (config);
5681 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5683 MPLIST_DO (pl, config->cmds)
5685 elt = MPLIST_PLIST (pl);
5686 command = MPLIST_SYMBOL (elt);
5688 p = mplist__assq (custom->cmds, command);
5690 custom->cmds = mplist (), p = NULL;
5691 elt = MPLIST_NEXT (elt);
5694 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5695 mplist_set (p, Mnil, NULL);
5700 mplist_add (custom->cmds, Mplist, p);
5701 M17N_OBJECT_UNREF (p);
5702 mplist_add (p, Msymbol, command);
5703 p = mplist_add (p, Msymbol, Mnil);
5704 p = MPLIST_NEXT (p);
5706 mplist__conc (p, elt);
5709 MPLIST_DO (pl, config->vars)
5711 elt = MPLIST_PLIST (pl);
5712 variable = MPLIST_SYMBOL (elt);
5714 p = mplist__assq (custom->vars, variable);
5716 custom->vars = mplist (), p = NULL;
5717 elt = MPLIST_NEXT (elt);
5720 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5721 mplist_set (p, Mnil, NULL);
5726 mplist_add (custom->vars, Mplist, p);
5727 M17N_OBJECT_UNREF (p);
5728 mplist_add (p, Msymbol, variable);
5729 p = mplist_add (p, Msymbol, Mnil);
5730 p = MPLIST_NEXT (p);
5732 mplist__conc (p, elt);
5735 free_im_list (im_config_list);
5736 im_config_list = NULL;
5738 /* Next, reflect customization to the actual plist to be written. */
5739 data = tail = mplist ();
5740 MPLIST_DO (plist, im_custom_list)
5742 MPlist *pl = MPLIST_PLIST (plist);
5743 MSymbol language, name, extra;
5744 MInputMethodInfo *custom, *im_info;
5746 language = MPLIST_SYMBOL (pl);
5747 pl = MPLIST_NEXT (pl);
5748 name = MPLIST_SYMBOL (pl);
5749 pl = MPLIST_NEXT (pl);
5750 extra = MPLIST_SYMBOL (pl);
5751 pl = MPLIST_NEXT (pl);
5752 custom = MPLIST_VAL (pl);
5753 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5754 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5756 im_info = lookup_im_info (im_info_list, language, name, extra);
5760 config_all_commands (im_info);
5762 config_all_variables (im_info);
5766 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5768 MPLIST_DO (p, custom->cmds)
5769 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5771 if (! MPLIST_TAIL_P (p))
5775 mplist_add (elt, Mplist, pl);
5776 M17N_OBJECT_UNREF (pl);
5777 pl = mplist_add (pl, Msymbol, Mcommand);
5778 MPLIST_DO (p, custom->cmds)
5779 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5780 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5783 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5785 MPLIST_DO (p, custom->vars)
5786 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5788 if (! MPLIST_TAIL_P (p))
5793 mplist_add (elt, Mplist, pl);
5794 M17N_OBJECT_UNREF (pl);
5795 pl = mplist_add (pl, Msymbol, Mvariable);
5796 MPLIST_DO (p, custom->vars)
5797 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5798 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5804 mplist_push (elt, Mplist, pl);
5805 M17N_OBJECT_UNREF (pl);
5806 pl = mplist_add (pl, Msymbol, Minput_method);
5807 pl = mplist_add (pl, Msymbol, language);
5808 pl = mplist_add (pl, Msymbol, name);
5810 pl = mplist_add (pl, Msymbol, extra);
5811 tail = mplist_add (tail, Mplist, elt);
5812 M17N_OBJECT_UNREF (elt);
5816 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5817 ret = mdatabase__save (im_custom_mdb, data);
5818 mdatabase__unlock (im_custom_mdb);
5819 M17N_OBJECT_UNREF (data);
5820 return (ret < 0 ? -1 : 1);
5827 @name Obsolete functions
5830 @name Obsolete ¤Ê´Ø¿ô
5836 @brief Get a list of variables of an input method (obsolete).
5838 This function is obsolete. Use minput_get_variable () instead.
5840 The minput_get_variables () function returns a plist (#MPlist) of
5841 variables used to control the behavior of the input method
5842 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5843 (@ref m17nPlist) of the following format:
5846 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5847 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5851 @c VARNAME is a symbol representing the variable name.
5853 @c DOC-MTEXT is an M-text describing the variable.
5855 @c DEFAULT-VALUE is the default value of the variable. It is a
5856 symbol, integer, or M-text.
5858 @c VALUEs (if any) specifies the possible values of the variable.
5859 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5860 @c TO), where @c FROM and @c TO specifies a range of possible
5863 For instance, suppose an input method has the variables:
5865 @li name:intvar, description:"value is an integer",
5866 initial value:0, value-range:0..3,10,20
5868 @li name:symvar, description:"value is a symbol",
5869 initial value:nil, value-range:a, b, c, nil
5871 @li name:txtvar, description:"value is an M-text",
5872 initial value:empty text, no value-range (i.e. any text)
5874 Then, the returned plist is as follows.
5877 (intvar ("value is an integer" 0 (0 3) 10 20)
5878 symvar ("value is a symbol" nil a b c nil)
5879 txtvar ("value is an M-text" ""))
5883 If the input method uses any variables, a pointer to #MPlist is
5884 returned. As the plist is kept in the library, the caller must not
5885 modify nor free it. If the input method does not use any
5886 variable, @c NULL is returned. */
5888 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5890 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5891 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5892 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5896 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5897 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5901 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5903 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5905 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5908 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5909 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5910 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5912 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5914 @li name:intvar, ÀâÌÀ:"value is an integer",
5915 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5917 @li name:symvar, ÀâÌÀ:"value is a symbol",
5918 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5920 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5921 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5923 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5926 (intvar ("value is an integer" 0 (0 3) 10 20)
5927 symvar ("value is a symbol" nil a b c nil)
5928 txtvar ("value is an M-text" ""))
5932 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5933 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5934 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5937 minput_get_variables (MSymbol language, MSymbol name)
5939 MInputMethodInfo *im_info;
5944 im_info = get_im_info (language, name, Mnil, Mvariable);
5945 if (! im_info || ! im_info->configured_vars)
5948 M17N_OBJECT_UNREF (im_info->bc_vars);
5949 im_info->bc_vars = mplist ();
5950 MPLIST_DO (vars, im_info->configured_vars)
5952 MPlist *plist = MPLIST_PLIST (vars);
5953 MPlist *elt = mplist ();
5955 mplist_push (im_info->bc_vars, Mplist, elt);
5956 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5957 elt = MPLIST_NEXT (elt);
5958 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5959 M17N_OBJECT_UNREF (elt);
5961 return im_info->bc_vars;
5967 @brief Set the initial value of an input method variable.
5969 The minput_set_variable () function sets the initial value of
5970 input method variable $VARIABLE to $VALUE for the input method
5971 specified by $LANGUAGE and $NAME.
5973 By default, the initial value is 0.
5975 This setting gets effective in a newly opened input method.
5978 If the operation was successful, 0 is returned. Otherwise -1 is
5979 returned, and #merror_code is set to #MERROR_IM. */
5981 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5983 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5984 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5985 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5987 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5989 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5992 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5993 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5996 minput_set_variable (MSymbol language, MSymbol name,
5997 MSymbol variable, void *value)
6000 MInputMethodInfo *im_info;
6005 if (variable == Mnil)
6006 MERROR (MERROR_IM, -1);
6007 plist = minput_get_variable (language, name, variable);
6008 plist = MPLIST_PLIST (plist);
6009 plist = MPLIST_NEXT (plist);
6011 mplist_add (pl, MPLIST_KEY (plist), value);
6012 ret = minput_config_variable (language, name, variable, pl);
6013 M17N_OBJECT_UNREF (pl);
6016 im_info = get_im_info (language, name, Mnil, Mvariable);
6025 @brief Get information about input method commands.
6027 The minput_get_commands () function returns information about
6028 input method commands of the input method specified by $LANGUAGE
6029 and $NAME. An input method command is a pseudo key event to which
6030 one or more actual input key sequences are assigned.
6032 There are two kinds of commands, global and local. Global
6033 commands are used by multiple input methods for the same purpose,
6034 and have global key assignments. Local commands are used only by
6035 a specific input method, and have only local key assignments.
6037 Each input method may locally change key assignments for global
6038 commands. The global key assignment for a global command is
6039 effective only when the current input method does not have local
6040 key assignments for that command.
6042 If $NAME is #Mnil, information about global commands is returned.
6043 In this case $LANGUAGE is ignored.
6045 If $NAME is not #Mnil, information about those commands that have
6046 local key assignments in the input method specified by $LANGUAGE
6047 and $NAME is returned.
6050 If no input method commands are found, this function returns @c NULL.
6052 Otherwise, a pointer to a plist is returned. The key of each
6053 element in the plist is a symbol representing a command, and the
6054 value is a plist of the form COMMAND-INFO described below.
6056 The first element of COMMAND-INFO has the key #Mtext, and the
6057 value is an M-text describing the command.
6059 If there are no more elements, that means no key sequences are
6060 assigned to the command. Otherwise, each of the remaining
6061 elements has the key #Mplist, and the value is a plist whose keys are
6062 #Msymbol and values are symbols representing input keys, which are
6063 currently assigned to the command.
6065 As the returned plist is kept in the library, the caller must not
6066 modify nor free it. */
6068 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6070 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6071 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6072 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6073 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6075 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6076 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6077 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6078 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6080 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6081 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6082 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6085 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6086 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6088 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6089 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6093 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6095 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6096 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6097 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6099 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6100 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6101 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6104 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6105 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6106 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6107 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6108 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6110 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6111 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6114 minput_get_commands (MSymbol language, MSymbol name)
6116 MInputMethodInfo *im_info;
6121 im_info = get_im_info (language, name, Mnil, Mcommand);
6122 if (! im_info || ! im_info->configured_vars)
6124 M17N_OBJECT_UNREF (im_info->bc_cmds);
6125 im_info->bc_cmds = mplist ();
6126 MPLIST_DO (cmds, im_info->configured_cmds)
6128 MPlist *plist = MPLIST_PLIST (cmds);
6129 MPlist *elt = mplist ();
6131 mplist_push (im_info->bc_cmds, Mplist, elt);
6132 mplist_add (elt, MPLIST_SYMBOL (plist),
6133 mplist_copy (MPLIST_NEXT (plist)));
6134 M17N_OBJECT_UNREF (elt);
6136 return im_info->bc_cmds;
6142 @brief Assign a key sequence to an input method command (obsolete).
6144 This function is obsolete. Use minput_config_command () instead.
6146 The minput_assign_command_keys () function assigns input key
6147 sequence $KEYSEQ to input method command $COMMAND for the input
6148 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6149 key sequence is assigned globally no matter what $LANGUAGE is.
6150 Otherwise the key sequence is assigned locally.
6152 Each element of $KEYSEQ must have the key $Msymbol and the value
6153 must be a symbol representing an input key.
6155 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6156 globally or locally.
6158 This assignment gets effective in a newly opened input method.
6161 If the operation was successful, 0 is returned. Otherwise -1 is
6162 returned, and #merror_code is set to #MERROR_IM. */
6164 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6166 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6167 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6168 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6169 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6170 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6172 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6173 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6175 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6176 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6178 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6181 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6182 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6185 minput_assign_command_keys (MSymbol language, MSymbol name,
6186 MSymbol command, MPlist *keyseq)
6192 if (command == Mnil)
6193 MERROR (MERROR_IM, -1);
6198 if (! check_command_keyseq (keyseq))
6199 MERROR (MERROR_IM, -1);
6201 mplist_add (plist, Mplist, keyseq);
6206 ret = minput_config_command (language, name, command, keyseq);
6207 M17N_OBJECT_UNREF (keyseq);
6214 @brief Call a callback function
6216 The minput_callback () functions calls a callback function
6217 $COMMAND assigned for the input context $IC. The caller must set
6218 specific elements in $IC->plist if the callback function requires.
6221 If there exists a specified callback function, 0 is returned.
6222 Otherwise -1 is returned. By side effects, $IC->plist may be
6226 minput_callback (MInputContext *ic, MSymbol command)
6228 MInputCallbackFunc func;
6230 if (! ic->im->driver.callback_list)
6232 func = ((MInputCallbackFunc)
6233 mplist_get_func (ic->im->driver.callback_list, command));
6236 (func) (ic, command);
6243 /*** @addtogroup m17nDebug */
6249 @brief Dump an input method.
6251 The mdebug_dump_im () function prints the input method $IM in a
6252 human readable way to the stderr. $INDENT specifies how many
6253 columns to indent the lines but the first one.
6256 This function returns $IM. */
6258 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6260 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6261 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6264 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6267 mdebug_dump_im (MInputMethod *im, int indent)
6269 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6272 prefix = (char *) alloca (indent + 1);
6273 memset (prefix, 32, indent);
6274 prefix[indent] = '\0';
6276 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6277 msymbol_name (im->name));
6278 mdebug_dump_mtext (im_info->title, 0, 0);
6279 if (im->name != Mnil)
6283 MPLIST_DO (state, im_info->states)
6285 fprintf (stderr, "\n%s ", prefix);
6286 dump_im_state (MPLIST_VAL (state), indent + 2);
6289 fprintf (stderr, ")");