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>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = 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 - 1);
591 mt = get_surrounding_text (ic, pos);
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 - 1);
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);
669 return get_following_char (ic, pos - len + 1);
672 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
674 else if (code >= '0' && code <= '9')
676 else if (code == '=')
677 pos = ic->cursor_pos;
678 else if (code == '[')
679 pos = ic->cursor_pos - 1;
680 else if (code == ']')
681 pos = ic->cursor_pos + 1;
682 else if (code == '<')
684 else if (code == '>')
686 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
690 parse_expression (MPlist *plist)
694 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
696 if (! MPLIST_PLIST_P (plist))
698 plist = MPLIST_PLIST (plist);
699 op = MPLIST_SYMBOL (plist);
700 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
701 && op != Mand && op != Mor && op != Mnot
702 && op != Mless && op != Mgreater && op != Mequal
703 && op != Mless_equal && op != Mgreater_equal)
704 MERROR (MERROR_IM, -1);
705 MPLIST_DO (plist, MPLIST_NEXT (plist))
706 if (parse_expression (plist) < 0)
712 resolve_expression (MInputContext *ic, MPlist *plist)
717 if (MPLIST_INTEGER_P (plist))
718 return MPLIST_INTEGER (plist);
719 if (MPLIST_SYMBOL_P (plist))
720 return integer_value (ic, plist, NULL, 1);
721 if (! MPLIST_PLIST_P (plist))
723 plist = MPLIST_PLIST (plist);
724 if (! MPLIST_SYMBOL_P (plist))
726 op = MPLIST_SYMBOL (plist);
727 plist = MPLIST_NEXT (plist);
728 val = resolve_expression (ic, plist);
730 MPLIST_DO (plist, MPLIST_NEXT (plist))
731 val += resolve_expression (ic, plist);
732 else if (op == Mminus)
733 MPLIST_DO (plist, MPLIST_NEXT (plist))
734 val -= resolve_expression (ic, plist);
735 else if (op == Mstar)
736 MPLIST_DO (plist, MPLIST_NEXT (plist))
737 val *= resolve_expression (ic, plist);
738 else if (op == Mslash)
739 MPLIST_DO (plist, MPLIST_NEXT (plist))
740 val /= resolve_expression (ic, plist);
742 MPLIST_DO (plist, MPLIST_NEXT (plist))
743 val &= resolve_expression (ic, plist);
745 MPLIST_DO (plist, MPLIST_NEXT (plist))
746 val |= resolve_expression (ic, plist);
749 else if (op == Mless)
750 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
751 else if (op == Mequal)
752 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
753 else if (op == Mgreater)
754 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
755 else if (op == Mless_equal)
756 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
757 else if (op == Mgreater_equal)
758 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
762 /* Parse PLIST as an action list. PLIST should have this form:
763 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
764 Return 0 if successfully parsed, otherwise return -1. */
767 parse_action_list (MPlist *plist, MPlist *macros)
769 MPLIST_DO (plist, plist)
771 if (MPLIST_MTEXT_P (plist))
773 /* This is a short form of (insert MTEXT). */
774 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
775 MERROR (MERROR_IM, -1); */
777 else if (MPLIST_PLIST_P (plist)
778 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
779 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
783 /* This is a short form of (insert (GROUPS *)). */
784 MPLIST_DO (pl, MPLIST_PLIST (plist))
786 if (MPLIST_PLIST_P (pl))
790 MPLIST_DO (elt, MPLIST_PLIST (pl))
791 if (! MPLIST_MTEXT_P (elt)
792 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
793 MERROR (MERROR_IM, -1);
797 if (! MPLIST_MTEXT_P (pl)
798 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
799 MERROR (MERROR_IM, -1);
803 else if (MPLIST_INTEGER_P (plist))
805 int c = MPLIST_INTEGER (plist);
807 if (c < 0 || c > MCHAR_MAX)
808 MERROR (MERROR_IM, -1);
810 else if (MPLIST_PLIST_P (plist)
811 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
813 MPlist *pl = MPLIST_PLIST (plist);
814 MSymbol action_name = MPLIST_SYMBOL (pl);
816 pl = MPLIST_NEXT (pl);
818 if (action_name == Minsert)
820 if (MPLIST_MTEXT_P (pl))
822 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
823 MERROR (MERROR_IM, -1);
825 else if (MPLIST_PLIST_P (pl))
827 MPLIST_DO (pl, MPLIST_PLIST (pl))
829 if (MPLIST_PLIST_P (pl))
833 MPLIST_DO (elt, MPLIST_PLIST (pl))
834 if (! MPLIST_MTEXT_P (elt)
835 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
836 MERROR (MERROR_IM, -1);
840 if (! MPLIST_MTEXT_P (pl)
841 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
842 MERROR (MERROR_IM, -1);
846 else if (! MPLIST_SYMBOL_P (pl))
847 MERROR (MERROR_IM, -1);
849 else if (action_name == Mselect
850 || action_name == Mdelete
851 || action_name == Mmove)
853 if (parse_expression (pl) < 0)
856 else if (action_name == Mmark
857 || action_name == Mcall
858 || action_name == Mshift)
860 if (! MPLIST_SYMBOL_P (pl))
861 MERROR (MERROR_IM, -1);
863 else if (action_name == Mundo)
865 if (! MPLIST_TAIL_P (pl))
867 if (! MPLIST_SYMBOL_P (pl)
868 && ! MPLIST_INTEGER_P (pl))
869 MERROR (MERROR_IM, -1);
872 else if (action_name == Mpushback)
874 if (MPLIST_MTEXT_P (pl))
876 MText *mt = MPLIST_MTEXT (pl);
878 if (mtext_nchars (mt) != mtext_nbytes (mt))
879 MERROR (MERROR_IM, -1);
881 else if (MPLIST_PLIST_P (pl))
885 MPLIST_DO (p, MPLIST_PLIST (pl))
886 if (! MPLIST_SYMBOL_P (p))
887 MERROR (MERROR_IM, -1);
889 else if (! MPLIST_INTEGER_P (pl))
890 MERROR (MERROR_IM, -1);
892 else if (action_name == Mset || action_name == Madd
893 || action_name == Msub || action_name == Mmul
894 || action_name == Mdiv)
896 if (! MPLIST_SYMBOL_P (pl))
897 MERROR (MERROR_IM, -1);
898 if (parse_expression (MPLIST_NEXT (pl)) < 0)
901 else if (action_name == Mequal || action_name == Mless
902 || action_name == Mgreater || action_name == Mless_equal
903 || action_name == Mgreater_equal)
905 if (parse_expression (pl) < 0
906 || parse_expression (MPLIST_NEXT (pl)) < 0)
908 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
909 if (! MPLIST_PLIST_P (pl))
910 MERROR (MERROR_IM, -1);
911 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
912 MERROR (MERROR_IM, -1);
913 pl = MPLIST_NEXT (pl);
914 if (MPLIST_PLIST_P (pl)
915 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
916 MERROR (MERROR_IM, -1);
918 else if (action_name == Mshow || action_name == Mhide
919 || action_name == Mcommit || action_name == Munhandle
920 || action_name == Mpop)
922 else if (action_name == Mcond)
925 if (! MPLIST_PLIST_P (pl))
926 MERROR (MERROR_IM, -1);
928 else if (! macros || ! mplist_get (macros, action_name))
929 MERROR (MERROR_IM, -1);
931 else if (! MPLIST_SYMBOL_P (plist))
932 MERROR (MERROR_IM, -1);
939 resolve_command (MPlist *cmds, MSymbol command)
943 if (! cmds || ! (plist = mplist__assq (cmds, command)))
945 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
946 plist = MPLIST_NEXT (plist);
947 plist = MPLIST_NEXT (plist);
948 plist = MPLIST_NEXT (plist);
952 /* Load a translation into MAP from PLIST.
954 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
957 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
958 MPlist *branch_actions, MPlist *macros)
963 if (MPLIST_MTEXT_P (keylist))
965 MText *mt = MPLIST_MTEXT (keylist);
967 len = mtext_nchars (mt);
968 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
970 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
971 for (i = 0; i < len; i++)
972 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
978 if (MFAILP (MPLIST_PLIST_P (keylist)))
980 elt = MPLIST_PLIST (keylist);
981 len = MPLIST_LENGTH (elt);
982 if (MFAILP (len > 0))
984 keyseq = (MSymbol *) alloca (sizeof (int) * len);
985 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
987 if (MPLIST_INTEGER_P (elt))
989 int c = MPLIST_INTEGER (elt);
991 if (MFAILP (c >= 0 && c < 0x100))
993 keyseq[i] = one_char_symbol[c];
997 if (MFAILP (MPLIST_SYMBOL_P (elt)))
999 keyseq[i] = MPLIST_SYMBOL (elt);
1004 for (i = 0; i < len; i++)
1006 MIMMap *deeper = NULL;
1009 deeper = mplist_get (map->submaps, keyseq[i]);
1011 map->submaps = mplist ();
1014 /* Fixme: It is better to make all deeper maps at once. */
1015 MSTRUCT_CALLOC (deeper, MERROR_IM);
1016 mplist_put (map->submaps, keyseq[i], deeper);
1021 /* We reach a terminal map. */
1022 if (map->map_actions
1023 || map->branch_actions)
1024 /* This map is already defined. We avoid overriding it. */
1027 if (! MPLIST_TAIL_P (map_actions))
1029 if (parse_action_list (map_actions, macros) < 0)
1030 MERROR (MERROR_IM, -1);
1031 map->map_actions = map_actions;
1035 map->branch_actions = branch_actions;
1036 M17N_OBJECT_REF (branch_actions);
1042 /* Load a branch from PLIST into MAP. PLIST has this form:
1043 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1046 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1049 MPlist *branch_actions;
1051 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1053 map_name = MPLIST_SYMBOL (plist);
1054 plist = MPLIST_NEXT (plist);
1055 if (MPLIST_TAIL_P (plist))
1056 branch_actions = NULL;
1057 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1060 branch_actions = plist;
1061 if (map_name == Mnil)
1063 map->branch_actions = branch_actions;
1065 M17N_OBJECT_REF (branch_actions);
1067 else if (map_name == Mt)
1069 map->map_actions = branch_actions;
1071 M17N_OBJECT_REF (branch_actions);
1073 else if (im_info->maps)
1075 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1078 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1080 if (p && MPLIST_PLIST_P (p))
1082 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1083 if (MPLIST_SYMBOL_P (p))
1084 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1089 MPLIST_DO (plist, plist)
1091 MPlist *keylist, *map_actions;
1093 if (! MPLIST_PLIST_P (plist))
1094 MERROR (MERROR_IM, -1);
1095 keylist = MPLIST_PLIST (plist);
1096 map_actions = MPLIST_NEXT (keylist);
1097 if (MPLIST_SYMBOL_P (keylist))
1099 MSymbol command = MPLIST_SYMBOL (keylist);
1102 if (MFAILP (command != Mat_reload))
1104 pl = resolve_command (im_info->configured_cmds, command);
1108 load_translation (map, pl, map_actions, branch_actions,
1112 load_translation (map, keylist, map_actions, branch_actions,
1121 /* Load a macro from PLIST into IM_INFO->macros.
1122 PLIST has this from:
1123 PLIST ::= ( MACRO-NAME ACTION * )
1124 IM_INFO->macros is a plist of macro names vs action list. */
1127 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1132 if (! MPLIST_SYMBOL_P (plist))
1133 MERROR (MERROR_IM, -1);
1134 name = MPLIST_SYMBOL (plist);
1135 plist = MPLIST_NEXT (plist);
1136 if (MPLIST_TAIL_P (plist)
1137 || parse_action_list (plist, im_info->macros) < 0)
1138 MERROR (MERROR_IM, -1);
1139 pl = mplist_get (im_info->macros, name);
1140 M17N_OBJECT_UNREF (pl);
1141 mplist_put (im_info->macros, name, plist);
1142 M17N_OBJECT_REF (plist);
1146 /* Load an external module from PLIST into IM_INFO->externals.
1147 PLIST has this form:
1148 PLIST ::= ( MODULE-NAME FUNCTION * )
1149 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1152 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1157 MIMExternalModule *external;
1161 if (MPLIST_MTEXT_P (plist))
1162 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1163 else if (MPLIST_SYMBOL_P (plist))
1164 module = MPLIST_SYMBOL (plist);
1165 module_file = alloca (strlen (MSYMBOL_NAME (module))
1166 + strlen (DLOPEN_SHLIB_EXT) + 1);
1167 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1169 handle = dlopen (module_file, RTLD_NOW);
1170 if (MFAILP (handle))
1172 fprintf (stderr, "%s\n", dlerror ());
1175 func_list = mplist ();
1176 MPLIST_DO (plist, MPLIST_NEXT (plist))
1178 if (! MPLIST_SYMBOL_P (plist))
1179 MERROR_GOTO (MERROR_IM, err_label);
1180 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1183 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1186 MSTRUCT_MALLOC (external, MERROR_IM);
1187 external->handle = handle;
1188 external->func_list = func_list;
1189 mplist_add (im_info->externals, module, external);
1194 M17N_OBJECT_UNREF (func_list);
1199 free_map (MIMMap *map, int top)
1204 M17N_OBJECT_UNREF (map->map_actions);
1207 MPLIST_DO (plist, map->submaps)
1208 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1209 M17N_OBJECT_UNREF (map->submaps);
1211 M17N_OBJECT_UNREF (map->branch_actions);
1216 free_state (void *object)
1218 MIMState *state = object;
1220 M17N_OBJECT_UNREF (state->title);
1222 free_map (state->map, 1);
1226 /** Load a state from PLIST into a newly allocated state object.
1227 PLIST has this form:
1228 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1229 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1230 Return the state object. */
1233 load_state (MInputMethodInfo *im_info, MPlist *plist)
1237 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1239 M17N_OBJECT (state, free_state, MERROR_IM);
1240 state->name = MPLIST_SYMBOL (plist);
1241 plist = MPLIST_NEXT (plist);
1242 if (MPLIST_MTEXT_P (plist))
1244 state->title = MPLIST_MTEXT (plist);
1245 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1246 Mlanguage, im_info->language);
1247 M17N_OBJECT_REF (state->title);
1248 plist = MPLIST_NEXT (plist);
1250 MSTRUCT_CALLOC (state->map, MERROR_IM);
1251 MPLIST_DO (plist, plist)
1253 if (MFAILP (MPLIST_PLIST_P (plist)))
1255 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1260 /* Return a newly created IM_INFO for an input method specified by
1261 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1263 static MInputMethodInfo *
1264 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1267 MInputMethodInfo *im_info;
1270 if (name == Mnil && extra == Mnil)
1271 language = Mt, extra = Mglobal;
1272 MSTRUCT_CALLOC (im_info, MERROR_IM);
1274 im_info->language = language;
1275 im_info->name = name;
1276 im_info->extra = extra;
1279 mplist_add (plist, Mplist, elt);
1280 M17N_OBJECT_UNREF (elt);
1281 elt = mplist_add (elt, Msymbol, language);
1282 elt = mplist_add (elt, Msymbol, name);
1283 elt = mplist_add (elt, Msymbol, extra);
1284 mplist_add (elt, Mt, im_info);
1290 fini_im_info (MInputMethodInfo *im_info)
1294 M17N_OBJECT_UNREF (im_info->cmds);
1295 M17N_OBJECT_UNREF (im_info->configured_cmds);
1296 M17N_OBJECT_UNREF (im_info->bc_cmds);
1297 M17N_OBJECT_UNREF (im_info->vars);
1298 M17N_OBJECT_UNREF (im_info->configured_vars);
1299 M17N_OBJECT_UNREF (im_info->bc_vars);
1300 M17N_OBJECT_UNREF (im_info->description);
1301 M17N_OBJECT_UNREF (im_info->title);
1302 if (im_info->states)
1304 MPLIST_DO (plist, im_info->states)
1306 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1308 M17N_OBJECT_UNREF (state);
1310 M17N_OBJECT_UNREF (im_info->states);
1313 if (im_info->macros)
1315 MPLIST_DO (plist, im_info->macros)
1316 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1317 M17N_OBJECT_UNREF (im_info->macros);
1320 if (im_info->externals)
1322 MPLIST_DO (plist, im_info->externals)
1324 MIMExternalModule *external = MPLIST_VAL (plist);
1326 dlclose (external->handle);
1327 M17N_OBJECT_UNREF (external->func_list);
1329 MPLIST_KEY (plist) = Mt;
1331 M17N_OBJECT_UNREF (im_info->externals);
1335 MPLIST_DO (plist, im_info->maps)
1337 MPlist *p = MPLIST_PLIST (plist);
1339 M17N_OBJECT_UNREF (p);
1341 M17N_OBJECT_UNREF (im_info->maps);
1348 free_im_info (MInputMethodInfo *im_info)
1350 fini_im_info (im_info);
1355 free_im_list (MPlist *plist)
1359 MPLIST_DO (pl, plist)
1361 MInputMethodInfo *im_info;
1363 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1364 im_info = MPLIST_VAL (elt);
1365 free_im_info (im_info);
1367 M17N_OBJECT_UNREF (plist);
1370 static MInputMethodInfo *
1371 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1373 if (name == Mnil && extra == Mnil)
1374 language = Mt, extra = Mglobal;
1375 while ((plist = mplist__assq (plist, language)))
1377 MPlist *elt = MPLIST_PLIST (plist);
1379 plist = MPLIST_NEXT (plist);
1380 elt = MPLIST_NEXT (elt);
1381 if (MPLIST_SYMBOL (elt) != name)
1383 elt = MPLIST_NEXT (elt);
1384 if (MPLIST_SYMBOL (elt) != extra)
1386 elt = MPLIST_NEXT (elt);
1387 return MPLIST_VAL (elt);
1392 static void load_im_info (MPlist *, MInputMethodInfo *);
1394 #define get_custom_info(im_info) \
1396 ? lookup_im_info (im_custom_list, (im_info)->language, \
1397 (im_info)->name, (im_info)->extra) \
1400 #define get_config_info(im_info) \
1402 ? lookup_im_info (im_config_list, (im_info)->language, \
1403 (im_info)->name, (im_info)->extra) \
1407 update_custom_info (void)
1413 if (mdatabase__check (im_custom_mdb) > 0)
1418 MDatabaseInfo *custom_dir_info;
1419 char custom_path[PATH_MAX + 1];
1421 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1422 if (! custom_dir_info->filename
1423 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1425 strcpy (custom_path, custom_dir_info->filename);
1426 strcat (custom_path, CUSTOM_FILE);
1427 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1433 free_im_list (im_custom_list);
1434 im_custom_list = NULL;
1436 plist = mdatabase_load (im_custom_mdb);
1439 im_custom_list = mplist ();
1441 MPLIST_DO (pl, plist)
1443 MSymbol language, name, extra;
1444 MInputMethodInfo *im_info;
1445 MPlist *im_data, *p;
1447 if (! MPLIST_PLIST_P (pl))
1449 p = MPLIST_PLIST (pl);
1450 im_data = MPLIST_NEXT (p);
1451 if (! MPLIST_PLIST_P (p))
1453 p = MPLIST_PLIST (p);
1454 if (! MPLIST_SYMBOL_P (p)
1455 || MPLIST_SYMBOL (p) != Minput_method)
1457 p = MPLIST_NEXT (p);
1458 if (! MPLIST_SYMBOL_P (p))
1460 language = MPLIST_SYMBOL (p);
1461 p = MPLIST_NEXT (p);
1462 if (! MPLIST_SYMBOL_P (p))
1464 name = MPLIST_SYMBOL (p);
1465 p = MPLIST_NEXT (p);
1466 if (MPLIST_TAIL_P (p))
1468 else if (MPLIST_SYMBOL_P (p))
1469 extra = MPLIST_SYMBOL (p);
1470 if (language == Mnil || (name == Mnil && extra == Mnil))
1472 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1473 load_im_info (im_data, im_info);
1475 M17N_OBJECT_UNREF (plist);
1480 update_global_info (void)
1486 int ret = mdatabase__check (global_info->mdb);
1490 fini_im_info (global_info);
1494 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1496 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1498 if (! global_info->mdb
1499 || ! (plist = mdatabase_load (global_info->mdb)))
1502 load_im_info (plist, global_info);
1503 M17N_OBJECT_UNREF (plist);
1508 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1509 and EXTRA. KEY, if not Mnil, tells which kind of information about
1510 the input method is necessary, and the returned IM_INFO may contain
1511 only that information. */
1513 static MInputMethodInfo *
1514 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1517 MInputMethodInfo *im_info;
1520 if (name == Mnil && extra == Mnil)
1521 language = Mt, extra = Mglobal;
1522 im_info = lookup_im_info (im_info_list, language, name, extra);
1525 if (key == Mnil ? im_info->states != NULL
1526 : key == Mcommand ? im_info->cmds != NULL
1527 : key == Mvariable ? im_info->vars != NULL
1528 : key == Mtitle ? im_info->title != NULL
1529 : key == Mdescription ? im_info->description != NULL
1531 /* IM_INFO already contains required information. */
1533 /* We have not yet loaded required information. */
1537 mdb = mdatabase_find (Minput_method, language, name, extra);
1540 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1545 plist = mdatabase_load (im_info->mdb);
1549 mplist_push (load_im_info_keys, key, Mt);
1550 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1551 mplist_pop (load_im_info_keys);
1555 MERROR (MERROR_IM, im_info);
1556 update_global_info ();
1557 load_im_info (plist, im_info);
1558 M17N_OBJECT_UNREF (plist);
1561 if (! im_info->cmds)
1562 im_info->cmds = mplist ();
1563 if (! im_info->vars)
1564 im_info->vars = mplist ();
1566 if (! im_info->title
1567 && (key == Mnil || key == Mtitle))
1568 im_info->title = (name == Mnil ? mtext ()
1569 : mtext_from_data (MSYMBOL_NAME (name),
1570 MSYMBOL_NAMELEN (name),
1571 MTEXT_FORMAT_US_ASCII));
1575 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1576 If updated, but got unloadable, return -1. Otherwise, update
1577 contents of IM_INFO from the new database, and return 1. */
1580 reload_im_info (MInputMethodInfo *im_info)
1585 update_custom_info ();
1586 update_global_info ();
1587 check = mdatabase__check (im_info->mdb);
1590 plist = mdatabase_load (im_info->mdb);
1593 fini_im_info (im_info);
1594 load_im_info (plist, im_info);
1595 M17N_OBJECT_UNREF (plist);
1596 if (! im_info->cmds)
1597 im_info->cmds = mplist ();
1598 if (! im_info->vars)
1599 im_info->vars = mplist ();
1600 if (! im_info->title)
1602 MSymbol name = im_info->name;
1604 im_info->title = (name == Mnil ? mtext ()
1605 : mtext_from_data (MSYMBOL_NAME (name),
1606 MSYMBOL_NAMELEN (name),
1607 MTEXT_FORMAT_US_ASCII));
1612 static MInputMethodInfo *
1613 get_im_info_by_tags (MPlist *plist)
1618 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1619 i++, plist = MPLIST_NEXT (plist))
1620 tag[i] = MPLIST_SYMBOL (plist);
1625 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1630 check_description (MPlist *plist)
1634 if (MPLIST_MTEXT_P (plist))
1636 if (MPLIST_PLIST_P (plist))
1638 MPlist *pl = MPLIST_PLIST (plist);
1640 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1642 pl =MPLIST_NEXT (pl);
1643 if (MFAILP (MPLIST_MTEXT_P (pl)))
1645 mt = MPLIST_MTEXT (pl);
1646 M17N_OBJECT_REF (mt);
1649 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1651 if (translated == (char *) MTEXT_DATA (mt))
1652 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1653 if (translated != (char *) MTEXT_DATA (mt))
1655 M17N_OBJECT_UNREF (mt);
1656 mt = mtext__from_data (translated, strlen (translated),
1657 MTEXT_FORMAT_UTF_8, 1);
1661 mplist_set (plist, Mtext, mt);
1662 M17N_OBJECT_UNREF (mt);
1665 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1671 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1675 check_command_keyseq (MPlist *keyseq)
1677 if (MPLIST_PLIST_P (keyseq))
1679 MPlist *p = MPLIST_PLIST (keyseq);
1682 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1686 if (MPLIST_MTEXT_P (keyseq))
1688 MText *mt = MPLIST_MTEXT (keyseq);
1691 for (i = 0; i < mtext_nchars (mt); i++)
1692 if (mtext_ref_char (mt, i) >= 256)
1699 /* Load command defitions from PLIST into IM_INFO->cmds.
1701 PLIST is well-formed and has this form;
1702 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1703 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1704 M-text or a plist of symbols.
1706 The returned list has the same form, but for each element...
1708 (1) If DESCRIPTION and the rest are omitted, the element is not
1709 stored in the returned list.
1711 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1712 description in global_info->cmds (if any). */
1715 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1719 im_info->cmds = tail = mplist ();
1721 MPLIST_DO (plist, MPLIST_NEXT (plist))
1723 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1726 if (MFAILP (MPLIST_PLIST_P (plist)))
1728 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1729 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1731 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1732 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1734 if (MFAILP (im_info != global_info))
1735 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1739 if (! check_description (p))
1740 mplist_set (p, Msymbol, Mnil);
1741 p = MPLIST_NEXT (p);
1742 while (! MPLIST_TAIL_P (p))
1744 if (MFAILP (check_command_keyseq (p)))
1745 mplist__pop_unref (p);
1747 p = MPLIST_NEXT (p);
1750 tail = mplist_add (tail, Mplist, pl);
1755 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1756 MPlist *config_cmds)
1758 MPlist *global = NULL, *custom = NULL, *config = NULL;
1759 MSymbol name = MPLIST_SYMBOL (plist);
1761 MPlist *description, *keyseq;
1763 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1764 global = MPLIST_NEXT (MPLIST_PLIST (global));
1766 plist = MPLIST_NEXT (plist);
1767 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1769 description = plist;
1770 plist = MPLIST_NEXT (plist);
1774 description = global;
1775 if (! MPLIST_TAIL_P (plist))
1776 plist = MPLIST_NEXT (plist);
1778 if (MPLIST_TAIL_P (plist) && global)
1780 keyseq = MPLIST_NEXT (global);
1781 status = Minherited;
1789 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1791 status = Mconfigured;
1792 config = MPLIST_NEXT (MPLIST_PLIST (config));
1793 if (! MPLIST_TAIL_P (config))
1796 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1798 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1800 if (MPLIST_TAIL_P (this_keyseq))
1801 mplist__pop_unref (custom);
1804 status = Mcustomized;
1805 keyseq = this_keyseq;
1810 mplist_add (plist, Msymbol, name);
1812 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1814 mplist_add (plist, Msymbol, Mnil);
1815 mplist_add (plist, Msymbol, status);
1816 mplist__conc (plist, keyseq);
1821 config_all_commands (MInputMethodInfo *im_info)
1823 MPlist *global_cmds, *custom_cmds, *config_cmds;
1824 MInputMethodInfo *temp;
1825 MPlist *tail, *plist;
1827 M17N_OBJECT_UNREF (im_info->configured_cmds);
1829 if (MPLIST_TAIL_P (im_info->cmds)
1833 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1834 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1835 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1837 im_info->configured_cmds = tail = mplist ();
1838 MPLIST_DO (plist, im_info->cmds)
1840 MPlist *pl = config_command (MPLIST_PLIST (plist),
1841 global_cmds, custom_cmds, config_cmds);
1844 tail = mplist_add (tail, Mplist, pl);
1845 M17N_OBJECT_UNREF (pl);
1850 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1851 valid, return 0 if not. */
1854 check_variable_value (MPlist *val, MPlist *global)
1856 MSymbol type = MPLIST_KEY (val);
1857 MPlist *valids = MPLIST_NEXT (val);
1859 if (type != Minteger && type != Mtext && type != Msymbol)
1863 if (MPLIST_KEY (global) != Mt
1864 && MPLIST_KEY (global) != MPLIST_KEY (val))
1866 if (MPLIST_TAIL_P (valids))
1867 valids = MPLIST_NEXT (global);
1869 if (MPLIST_TAIL_P (valids))
1872 if (type == Minteger)
1874 int n = MPLIST_INTEGER (val);
1876 MPLIST_DO (valids, valids)
1878 if (MPLIST_INTEGER_P (valids))
1880 if (n == MPLIST_INTEGER (valids))
1883 else if (MPLIST_PLIST_P (valids))
1885 MPlist *p = MPLIST_PLIST (valids);
1886 int min_bound, max_bound;
1888 if (! MPLIST_INTEGER_P (p))
1889 MERROR (MERROR_IM, 0);
1890 min_bound = MPLIST_INTEGER (p);
1891 p = MPLIST_NEXT (p);
1892 if (! MPLIST_INTEGER_P (p))
1893 MERROR (MERROR_IM, 0);
1894 max_bound = MPLIST_INTEGER (p);
1895 if (n >= min_bound && n <= max_bound)
1900 else if (type == Msymbol)
1902 MSymbol sym = MPLIST_SYMBOL (val);
1904 MPLIST_DO (valids, valids)
1906 if (! MPLIST_SYMBOL_P (valids))
1907 MERROR (MERROR_IM, 0);
1908 if (sym == MPLIST_SYMBOL (valids))
1914 MText *mt = MPLIST_MTEXT (val);
1916 MPLIST_DO (valids, valids)
1918 if (! MPLIST_MTEXT_P (valids))
1919 MERROR (MERROR_IM, 0);
1920 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1925 return (! MPLIST_TAIL_P (valids));
1928 /* Load variable defitions from PLIST into IM_INFO->vars.
1930 PLIST is well-formed and has this form;
1931 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1933 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1935 The returned list has the same form, but for each element...
1937 (1) If DESCRIPTION and the rest are omitted, the element is not
1938 stored in the returned list.
1940 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1941 description in global_info->vars (if any). */
1944 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1946 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1947 ? global_info->vars : NULL);
1950 im_info->vars = tail = mplist ();
1951 MPLIST_DO (plist, MPLIST_NEXT (plist))
1955 if (MFAILP (MPLIST_PLIST_P (plist)))
1957 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1958 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1960 if (im_info == global_info)
1962 /* Loading a global variable. */
1963 p = MPLIST_NEXT (pl);
1964 if (MPLIST_TAIL_P (p))
1965 mplist_add (p, Msymbol, Mnil);
1968 if (! check_description (p))
1969 mplist_set (p, Msymbol, Mnil);
1970 p = MPLIST_NEXT (p);
1971 if (MFAILP (! MPLIST_TAIL_P (p)
1972 && check_variable_value (p, NULL)))
1973 mplist_set (p, Mt, NULL);
1976 else if (im_info->mdb)
1978 /* Loading a local variable. */
1979 MSymbol name = MPLIST_SYMBOL (pl);
1980 MPlist *global = NULL;
1983 && (p = mplist__assq (global_vars, name)))
1985 /* P ::= ((NAME DESC ...) ...) */
1986 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1987 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1988 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1991 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1992 if (! MPLIST_TAIL_P (p))
1994 if (! check_description (p))
1995 mplist_set (p, Msymbol, Mnil);
1996 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1997 if (MFAILP (! MPLIST_TAIL_P (p)))
1998 mplist_set (p, Mt, NULL);
2001 MPlist *valid_values = MPLIST_NEXT (p);
2003 if (! MPLIST_TAIL_P (valid_values)
2004 ? MFAILP (check_variable_value (p, NULL))
2005 : global && MFAILP (check_variable_value (p, global)))
2006 mplist_set (p, Mt, NULL);
2012 /* Loading a variable customization. */
2013 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2014 if (MFAILP (! MPLIST_TAIL_P (p)))
2016 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2017 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2018 || MPLIST_MTEXT_P (p)))
2021 tail = mplist_add (tail, Mplist, pl);
2026 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2027 MPlist *config_vars)
2029 MPlist *global = NULL, *custom = NULL, *config = NULL;
2030 MSymbol name = MPLIST_SYMBOL (plist);
2032 MPlist *description = NULL, *value, *valids;
2036 global = mplist__assq (global_vars, name);
2038 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2041 plist = MPLIST_NEXT (plist);
2042 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2043 description = plist;
2045 description = global;
2047 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2049 if (MPLIST_TAIL_P (plist))
2051 /* Inherit from global (if any). */
2055 if (MPLIST_KEY (value) == Mt)
2057 valids = MPLIST_NEXT (global);
2058 status = Minherited;
2070 value = plist = MPLIST_NEXT (plist);
2071 valids = MPLIST_NEXT (value);
2072 if (MPLIST_KEY (value) == Mt)
2074 if (! MPLIST_TAIL_P (valids))
2077 valids = MPLIST_NEXT (global);
2081 if (config_vars && (config = mplist__assq (config_vars, name)))
2083 status = Mconfigured;
2084 config = MPLIST_NEXT (MPLIST_PLIST (config));
2085 if (! MPLIST_TAIL_P (config))
2088 if (MFAILP (check_variable_value (value, global ? global : plist)))
2092 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2094 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2096 if (MPLIST_TAIL_P (this_value))
2097 mplist__pop_unref (custom);
2101 if (MFAILP (check_variable_value (value, global ? global : plist)))
2103 status = Mcustomized;
2108 mplist_add (plist, Msymbol, name);
2110 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2112 mplist_add (plist, Msymbol, Mnil);
2113 mplist_add (plist, Msymbol, status);
2115 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2117 mplist_add (plist, Mt, NULL);
2118 if (valids && ! MPLIST_TAIL_P (valids))
2119 mplist__conc (plist, valids);
2123 /* Return a configured variable definition list based on
2124 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2125 get it from global_info->vars. */
2128 config_all_variables (MInputMethodInfo *im_info)
2130 MPlist *global_vars, *custom_vars, *config_vars;
2131 MInputMethodInfo *temp;
2132 MPlist *tail, *plist;
2134 M17N_OBJECT_UNREF (im_info->configured_vars);
2136 if (MPLIST_TAIL_P (im_info->vars)
2140 global_vars = im_info != global_info ? global_info->vars : NULL;
2141 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2142 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2144 im_info->configured_vars = tail = mplist ();
2145 MPLIST_DO (plist, im_info->vars)
2147 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2148 global_vars, custom_vars, config_vars);
2151 tail = mplist_add (tail, Mplist, pl);
2152 M17N_OBJECT_UNREF (pl);
2157 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2158 CONFIG contains configuration information of the input method. */
2161 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2165 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2167 load_commands (im_info, MPLIST_PLIST (pl));
2168 config_all_commands (im_info);
2169 pl = mplist_pop (pl);
2170 M17N_OBJECT_UNREF (pl);
2173 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2175 load_variables (im_info, MPLIST_PLIST (pl));
2176 config_all_variables (im_info);
2177 pl = mplist_pop (pl);
2178 M17N_OBJECT_UNREF (pl);
2181 MPLIST_DO (plist, plist)
2182 if (MPLIST_PLIST_P (plist))
2184 MPlist *elt = MPLIST_PLIST (plist);
2187 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2189 key = MPLIST_SYMBOL (elt);
2194 elt = MPLIST_NEXT (elt);
2195 if (MFAILP (MPLIST_MTEXT_P (elt)))
2197 im_info->title = MPLIST_MTEXT (elt);
2198 M17N_OBJECT_REF (im_info->title);
2200 else if (key == Mmap)
2202 pl = mplist__from_alist (MPLIST_NEXT (elt));
2205 if (! im_info->maps)
2209 mplist__conc (im_info->maps, pl);
2210 M17N_OBJECT_UNREF (pl);
2213 else if (key == Mmacro)
2215 if (! im_info->macros)
2216 im_info->macros = mplist ();
2217 MPLIST_DO (elt, MPLIST_NEXT (elt))
2219 if (MFAILP (MPLIST_PLIST_P (elt)))
2221 load_macros (im_info, MPLIST_PLIST (elt));
2224 else if (key == Mmodule)
2226 if (! im_info->externals)
2227 im_info->externals = mplist ();
2228 MPLIST_DO (elt, MPLIST_NEXT (elt))
2230 if (MFAILP (MPLIST_PLIST_P (elt)))
2232 load_external_module (im_info, MPLIST_PLIST (elt));
2235 else if (key == Mstate)
2237 MPLIST_DO (elt, MPLIST_NEXT (elt))
2241 if (MFAILP (MPLIST_PLIST_P (elt)))
2243 pl = MPLIST_PLIST (elt);
2244 if (! im_info->states)
2245 im_info->states = mplist ();
2246 state = load_state (im_info, MPLIST_PLIST (elt));
2249 mplist_put (im_info->states, state->name, state);
2252 else if (key == Minclude)
2254 /* elt ::= include (tag1 tag2 ...) key item ... */
2256 MInputMethodInfo *temp;
2258 elt = MPLIST_NEXT (elt);
2259 if (MFAILP (MPLIST_PLIST_P (elt)))
2261 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2264 elt = MPLIST_NEXT (elt);
2265 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2267 key = MPLIST_SYMBOL (elt);
2268 elt = MPLIST_NEXT (elt);
2271 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2273 if (! im_info->maps)
2274 im_info->maps = mplist ();
2275 MPLIST_DO (pl, temp->maps)
2277 p = MPLIST_VAL (pl);
2278 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2279 M17N_OBJECT_REF (p);
2282 else if (key == Mmacro)
2284 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2286 if (! im_info->macros)
2287 im_info->macros = mplist ();
2288 MPLIST_DO (pl, temp->macros)
2290 p = MPLIST_VAL (pl);
2291 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2292 M17N_OBJECT_REF (p);
2295 else if (key == Mstate)
2297 if (! temp->states || MPLIST_TAIL_P (temp->states))
2299 if (! im_info->states)
2300 im_info->states = mplist ();
2301 MPLIST_DO (pl, temp->states)
2303 MIMState *state = MPLIST_VAL (pl);
2305 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2306 M17N_OBJECT_REF (state);
2310 else if (key == Mdescription)
2312 if (im_info->description)
2314 elt = MPLIST_NEXT (elt);
2315 if (! check_description (elt))
2317 im_info->description = MPLIST_MTEXT (elt);
2318 M17N_OBJECT_REF (im_info->description);
2321 im_info->tick = time (NULL);
2326 static int take_action_list (MInputContext *ic, MPlist *action_list);
2327 static void preedit_commit (MInputContext *ic);
2330 shift_state (MInputContext *ic, MSymbol state_name)
2332 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2333 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2334 MIMState *orig_state = ic_info->state, *state;
2336 /* Find a state to shift to. If not found, shift to the initial
2338 if (state_name == Mt)
2340 if (! ic_info->prev_state)
2342 state = ic_info->prev_state;
2344 else if (state_name == Mnil)
2346 state = (MIMState *) MPLIST_VAL (im_info->states);
2350 state = (MIMState *) mplist_get (im_info->states, state_name);
2352 state = (MIMState *) MPLIST_VAL (im_info->states);
2355 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2357 /* Enter the new state. */
2358 ic_info->state = state;
2359 ic_info->map = state->map;
2360 ic_info->state_key_head = ic_info->key_head;
2361 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2363 /* We have shifted to the initial state. */
2364 preedit_commit (ic);
2365 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2366 ic_info->state_pos = ic->cursor_pos;
2367 if (state != orig_state)
2369 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2371 /* Shifted to the initial state. */
2372 ic_info->prev_state = NULL;
2373 M17N_OBJECT_UNREF (ic_info->vars_saved);
2374 ic_info->vars_saved = mplist_copy (ic_info->vars);
2377 ic_info->prev_state = orig_state;
2380 ic->status = state->title;
2382 ic->status = im_info->title;
2383 ic->status_changed = 1;
2384 if (ic_info->map == ic_info->state->map
2385 && ic_info->map->map_actions)
2387 MDEBUG_PRINT (" init-actions:");
2388 take_action_list (ic, ic_info->map->map_actions);
2393 /* Find a candidate group that contains a candidate number INDEX from
2394 PLIST. Set START_INDEX to the first candidate number of the group,
2395 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2396 candidate group number if they are non-NULL. If INDEX is -1, find
2397 the last candidate group. */
2400 find_candidates_group (MPlist *plist, int index,
2401 int *start_index, int *end_index, int *group_index)
2403 int i = 0, gidx = 0, len;
2405 MPLIST_DO (plist, plist)
2407 if (MPLIST_MTEXT_P (plist))
2408 len = mtext_nchars (MPLIST_MTEXT (plist));
2410 len = mplist_length (MPLIST_PLIST (plist));
2411 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2417 *end_index = i + len;
2419 *group_index = gidx;
2428 /* Adjust markers for the change of preedit text.
2429 If FROM == TO, the change is insertion of INS chars.
2430 If FROM < TO and INS == 0, the change is deletion of the range.
2431 If FROM < TO and INS > 0, the change is replacement. */
2434 adjust_markers (MInputContext *ic, int from, int to, int ins)
2436 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2441 MPLIST_DO (markers, ic_info->markers)
2442 if (MPLIST_INTEGER (markers) > from)
2443 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2444 if (ic->cursor_pos >= from)
2445 ic->cursor_pos += ins;
2449 MPLIST_DO (markers, ic_info->markers)
2451 if (MPLIST_INTEGER (markers) >= to)
2452 MPLIST_VAL (markers)
2453 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2454 else if (MPLIST_INTEGER (markers) > from)
2455 MPLIST_VAL (markers) = (void *) from;
2457 if (ic->cursor_pos >= to)
2458 ic->cursor_pos += ins - (to - from);
2459 else if (ic->cursor_pos > from)
2460 ic->cursor_pos = from;
2466 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2468 int nchars = mt ? mtext_nchars (mt) : 1;
2471 mtext_ins (ic->preedit, pos, mt);
2473 mtext_ins_char (ic->preedit, pos, c, 1);
2474 adjust_markers (ic, pos, pos, nchars);
2475 ic->preedit_changed = 1;
2480 preedit_delete (MInputContext *ic, int from, int to)
2482 mtext_del (ic->preedit, from, to);
2483 adjust_markers (ic, from, to, 0);
2484 ic->preedit_changed = 1;
2488 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2492 mtext_del (ic->preedit, from, to);
2495 mtext_ins (ic->preedit, from, mt);
2496 ins = mtext_nchars (mt);
2500 mtext_ins_char (ic->preedit, from, c, 1);
2503 adjust_markers (ic, from, to, ins);
2504 ic->preedit_changed = 1;
2509 preedit_commit (MInputContext *ic)
2511 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2512 int preedit_len = mtext_nchars (ic->preedit);
2514 if (preedit_len > 0)
2518 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2519 Mcandidate_list, NULL, 0);
2520 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2521 Mcandidate_index, NULL, 0);
2522 mtext_cat (ic->produced, ic->preedit);
2523 if (mdebug__flag & mdebug_mask)
2527 MDEBUG_PRINT (" (commit");
2528 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2529 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2533 mtext_reset (ic->preedit);
2534 mtext_reset (ic_info->preedit_saved);
2535 MPLIST_DO (p, ic_info->markers)
2537 ic->cursor_pos = ic_info->state_pos = 0;
2538 ic->preedit_changed = 1;
2539 ic_info->commit_key_head = ic_info->key_head;
2541 if (ic->candidate_list)
2543 M17N_OBJECT_UNREF (ic->candidate_list);
2544 ic->candidate_list = NULL;
2545 ic->candidate_index = 0;
2546 ic->candidate_from = ic->candidate_to = 0;
2547 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2548 if (ic->candidate_show)
2550 ic->candidate_show = 0;
2551 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2557 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2559 int code = marker_code (sym, 0);
2561 if (mt && (code == '[' || code == ']'))
2565 if (code == '[' && current > 0)
2567 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2571 else if (code == ']' && current < mtext_nchars (mt))
2573 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2579 return (code == '<' ? 0
2580 : code == '>' ? limit
2581 : code == '-' ? current - 1
2582 : code == '+' ? current + 1
2583 : code == '=' ? current
2584 : code - '0' > limit ? limit
2588 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2592 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2594 int from = mtext_property_start (prop);
2595 int to = mtext_property_end (prop);
2597 MPlist *candidate_list = mtext_property_value (prop);
2598 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2600 int ingroup_index = idx - start;
2603 if (MPLIST_MTEXT_P (group))
2605 mt = MPLIST_MTEXT (group);
2606 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2614 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2615 i++, plist = MPLIST_NEXT (plist));
2616 mt = MPLIST_MTEXT (plist);
2617 preedit_replace (ic, from, to, mt, 0);
2618 to = from + mtext_nchars (mt);
2620 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2621 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2622 ic->cursor_pos = to;
2626 get_select_charset (MInputContextInfo * ic_info)
2628 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2631 if (! MPLIST_VAL (plist))
2633 sym = MPLIST_SYMBOL (plist);
2636 return MCHARSET (sym);
2640 adjust_candidates (MPlist *plist, MCharset *charset)
2644 /* plist ::= MTEXT ... | PLIST ... */
2645 plist = mplist_copy (plist);
2646 if (MPLIST_MTEXT_P (plist))
2649 while (! MPLIST_TAIL_P (pl))
2651 /* pl ::= MTEXT ... */
2652 MText *mt = MPLIST_MTEXT (pl);
2656 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2658 c = mtext_ref_char (mt, i);
2659 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2663 mt = mtext_dup (mt);
2664 mplist_set (pl, Mtext, mt);
2665 M17N_OBJECT_UNREF (mt);
2668 mtext_del (mt, i, i + 1);
2671 if (mtext_len (mt) > 0)
2672 pl = MPLIST_NEXT (pl);
2676 M17N_OBJECT_UNREF (mt);
2680 else /* MPLIST_PLIST_P (plist) */
2683 while (! MPLIST_TAIL_P (pl))
2685 /* pl ::= (MTEXT ...) ... */
2686 MPlist *p = MPLIST_PLIST (pl);
2688 /* p ::= MTEXT ... */
2692 while (! MPLIST_TAIL_P (p0))
2694 MText *mt = MPLIST_MTEXT (p0);
2697 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2699 c = mtext_ref_char (mt, i);
2700 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2705 p0 = MPLIST_NEXT (p0);
2712 p = mplist_copy (p);
2713 mplist_set (pl, Mplist, p);
2714 M17N_OBJECT_UNREF (p);
2718 p0 = MPLIST_NEXT (p0);
2721 M17N_OBJECT_UNREF (mt);
2724 if (! MPLIST_TAIL_P (p))
2725 pl = MPLIST_NEXT (pl);
2729 M17N_OBJECT_UNREF (p);
2733 if (MPLIST_TAIL_P (plist))
2735 M17N_OBJECT_UNREF (plist);
2742 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2744 MCharset *charset = get_select_charset (ic_info);
2749 plist = resolve_variable (ic_info, Mcandidates_group_size);
2750 column = MPLIST_INTEGER (plist);
2752 plist = MPLIST_PLIST (args);
2754 plist = adjust_candidates (plist, charset);
2756 if (plist && column > 0)
2758 if (MPLIST_MTEXT_P (plist))
2760 MText *mt = MPLIST_MTEXT (plist);
2761 MPlist *next = MPLIST_NEXT (plist);
2763 if (MPLIST_TAIL_P (next))
2764 M17N_OBJECT_REF (mt);
2767 mt = mtext_dup (mt);
2768 while (! MPLIST_TAIL_P (next))
2770 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2771 next = MPLIST_NEXT (next);
2775 M17N_OBJECT_UNREF (plist);
2777 len = mtext_nchars (mt);
2779 mplist_add (plist, Mtext, mt);
2782 for (i = 0; i < len; i += column)
2784 int to = (i + column < len ? i + column : len);
2785 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2787 mplist_add (plist, Mtext, sub);
2788 M17N_OBJECT_UNREF (sub);
2791 M17N_OBJECT_UNREF (mt);
2793 else if (! MPLIST_TAIL_P (plist))
2795 MPlist *tail = plist;
2796 MPlist *new = mplist ();
2797 MPlist *this = mplist ();
2800 MPLIST_DO (tail, tail)
2802 MPlist *p = MPLIST_PLIST (tail);
2806 MText *mt = MPLIST_MTEXT (p);
2808 if (count == column)
2810 mplist_add (new, Mplist, this);
2811 M17N_OBJECT_UNREF (this);
2815 mplist_add (this, Mtext, mt);
2819 mplist_add (new, Mplist, this);
2820 M17N_OBJECT_UNREF (this);
2821 mplist_set (plist, Mnil, NULL);
2822 MPLIST_DO (tail, new)
2824 MPlist *elt = MPLIST_PLIST (tail);
2826 mplist_add (plist, Mplist, elt);
2828 M17N_OBJECT_UNREF (new);
2837 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2839 MPlist *action = NULL;
2843 if (MPLIST_SYMBOL_P (action_list))
2845 MSymbol var = MPLIST_SYMBOL (action_list);
2848 MPLIST_DO (p, ic_info->vars)
2849 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2851 if (MPLIST_TAIL_P (p))
2853 action = MPLIST_NEXT (MPLIST_PLIST (p));
2854 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2857 if (MPLIST_PLIST_P (action_list))
2859 action = MPLIST_PLIST (action_list);
2860 if (MPLIST_SYMBOL_P (action))
2862 name = MPLIST_SYMBOL (action);
2863 args = MPLIST_NEXT (action);
2865 && MPLIST_PLIST_P (args))
2866 mplist_set (action, Msymbol, M_candidates);
2868 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2871 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2872 mplist_push (action, Msymbol, M_candidates);
2873 mplist_set (action_list, Mplist, action);
2874 M17N_OBJECT_UNREF (action);
2877 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2880 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2881 mplist_push (action, Msymbol, Minsert);
2882 mplist_set (action_list, Mplist, action);
2883 M17N_OBJECT_UNREF (action);
2888 /* Perform list of actions in ACTION_LIST for the current input
2889 context IC. If unhandle action was not performed, return 0.
2890 Otherwise, return -1. */
2893 take_action_list (MInputContext *ic, MPlist *action_list)
2895 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2896 MPlist *candidate_list = ic->candidate_list;
2897 int candidate_index = ic->candidate_index;
2898 int candidate_show = ic->candidate_show;
2899 MTextProperty *prop;
2901 MPLIST_DO (action_list, action_list)
2903 MPlist *action = regularize_action (action_list, ic_info);
2909 name = MPLIST_SYMBOL (action);
2910 args = MPLIST_NEXT (action);
2912 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2913 if (name == Minsert)
2915 if (MPLIST_SYMBOL_P (args))
2917 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2918 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2921 if (MPLIST_MTEXT_P (args))
2922 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2923 else /* MPLIST_INTEGER_P (args)) */
2924 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2926 else if (name == M_candidates)
2928 MPlist *plist = get_candidate_list (ic_info, args);
2931 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2933 if (MPLIST_MTEXT_P (plist))
2935 preedit_insert (ic, ic->cursor_pos, NULL,
2936 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2939 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2943 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2945 preedit_insert (ic, ic->cursor_pos, mt, 0);
2946 len = mtext_nchars (mt);
2948 mtext_put_prop (ic->preedit,
2949 ic->cursor_pos - len, ic->cursor_pos,
2950 Mcandidate_list, plist);
2951 mtext_put_prop (ic->preedit,
2952 ic->cursor_pos - len, ic->cursor_pos,
2953 Mcandidate_index, (void *) 0);
2955 else if (name == Mselect)
2958 int code, idx, gindex;
2959 int pos = ic->cursor_pos;
2961 int idx_decided = 0;
2964 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2967 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2968 group = find_candidates_group (mtext_property_value (prop), idx,
2969 &start, &end, &gindex);
2970 if (MPLIST_SYMBOL_P (args))
2972 code = marker_code (MPLIST_SYMBOL (args), 0);
2975 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2976 if (! MPLIST_INTEGER_P (args))
2978 idx = start + MPLIST_INTEGER (args);
2979 if (idx < start || idx >= end)
2987 if (code != '[' && code != ']')
2992 ? new_index (NULL, ic->candidate_index - start,
2993 end - start - 1, MPLIST_SYMBOL (args),
2995 : MPLIST_INTEGER (args)));
2998 find_candidates_group (mtext_property_value (prop), -1,
3003 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3008 int ingroup_index = idx - start;
3011 group = mtext_property_value (prop);
3012 len = mplist_length (group);
3025 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3026 idx += (MPLIST_MTEXT_P (group)
3027 ? mtext_nchars (MPLIST_MTEXT (group))
3028 : mplist_length (MPLIST_PLIST (group)));
3029 len = (MPLIST_MTEXT_P (group)
3030 ? mtext_nchars (MPLIST_MTEXT (group))
3031 : mplist_length (MPLIST_PLIST (group)));
3032 if (ingroup_index >= len)
3033 ingroup_index = len - 1;
3034 idx += ingroup_index;
3036 update_candidate (ic, prop, idx);
3037 MDEBUG_PRINT1 ("(%d)", idx);
3039 else if (name == Mshow)
3040 ic->candidate_show = 1;
3041 else if (name == Mhide)
3042 ic->candidate_show = 0;
3043 else if (name == Mdelete)
3045 int len = mtext_nchars (ic->preedit);
3049 if (MPLIST_SYMBOL_P (args)
3050 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3052 to = ic->cursor_pos + pos;
3055 delete_surrounding_text (ic, to);
3060 delete_surrounding_text (ic, to - len);
3066 to = (MPLIST_SYMBOL_P (args)
3067 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3069 : MPLIST_INTEGER (args));
3075 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3076 if (to < ic->cursor_pos)
3077 preedit_delete (ic, to, ic->cursor_pos);
3078 else if (to > ic->cursor_pos)
3079 preedit_delete (ic, ic->cursor_pos, to);
3081 else if (name == Mmove)
3083 int len = mtext_nchars (ic->preedit);
3085 = (MPLIST_SYMBOL_P (args)
3086 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3088 : MPLIST_INTEGER (args));
3094 if (pos != ic->cursor_pos)
3096 ic->cursor_pos = pos;
3097 ic->preedit_changed = 1;
3099 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3101 else if (name == Mmark)
3103 int code = marker_code (MPLIST_SYMBOL (args), 0);
3107 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3108 (void *) ic->cursor_pos);
3109 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3112 else if (name == Mpushback)
3114 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3118 if (MPLIST_SYMBOL_P (args))
3120 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3121 if (MPLIST_INTEGER_P (args))
3122 num = MPLIST_INTEGER (args);
3127 num = MPLIST_INTEGER (args);
3130 ic_info->key_head -= num;
3132 ic_info->key_head = 0;
3134 ic_info->key_head = - num;
3135 if (ic_info->key_head > ic_info->used)
3136 ic_info->key_head = ic_info->used;
3138 else if (MPLIST_MTEXT_P (args))
3140 MText *mt = MPLIST_MTEXT (args);
3141 int i, len = mtext_nchars (mt);
3144 ic_info->key_head--;
3145 for (i = 0; i < len; i++)
3147 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3148 if (ic_info->key_head + i < ic_info->used)
3149 ic_info->keys[ic_info->key_head + i] = key;
3151 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3156 MPlist *plist = MPLIST_PLIST (args), *pl;
3160 ic_info->key_head--;
3162 MPLIST_DO (pl, plist)
3164 key = MPLIST_SYMBOL (pl);
3165 if (ic_info->key_head < ic_info->used)
3166 ic_info->keys[ic_info->key_head + i] = key;
3168 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3173 else if (name == Mpop)
3175 if (ic_info->key_head < ic_info->used)
3176 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3178 else if (name == Mcall)
3180 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3181 MIMExternalFunc func = NULL;
3182 MSymbol module, func_name;
3183 MPlist *func_args, *val;
3186 module = MPLIST_SYMBOL (args);
3187 args = MPLIST_NEXT (args);
3188 func_name = MPLIST_SYMBOL (args);
3190 if (im_info->externals)
3192 MIMExternalModule *external
3193 = (MIMExternalModule *) mplist_get (im_info->externals,
3196 func = ((MIMExternalFunc)
3197 mplist_get_func (external->func_list, func_name));
3201 func_args = mplist ();
3202 mplist_add (func_args, Mt, ic);
3203 MPLIST_DO (args, MPLIST_NEXT (args))
3207 if (MPLIST_KEY (args) == Msymbol
3208 && MPLIST_KEY (args) != Mnil
3209 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3211 code = new_index (ic, ic->cursor_pos,
3212 mtext_nchars (ic->preedit),
3213 MPLIST_SYMBOL (args), ic->preedit);
3214 mplist_add (func_args, Minteger, (void *) code);
3217 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3219 val = (func) (func_args);
3220 M17N_OBJECT_UNREF (func_args);
3221 if (val && ! MPLIST_TAIL_P (val))
3222 ret = take_action_list (ic, val);
3223 M17N_OBJECT_UNREF (val);
3227 else if (name == Mshift)
3229 shift_state (ic, MPLIST_SYMBOL (args));
3231 else if (name == Mundo)
3233 int intarg = (MPLIST_TAIL_P (args)
3235 : integer_value (ic, args, NULL, 0));
3237 mtext_reset (ic->preedit);
3238 mtext_reset (ic_info->preedit_saved);
3239 mtext_reset (ic->produced);
3240 M17N_OBJECT_UNREF (ic_info->vars);
3241 ic_info->vars = mplist_copy (ic_info->vars_saved);
3242 ic->cursor_pos = ic_info->state_pos = 0;
3243 ic_info->state_key_head = ic_info->key_head
3244 = ic_info->commit_key_head = 0;
3246 shift_state (ic, Mnil);
3249 if (MPLIST_TAIL_P (args))
3254 ic_info->used += intarg;
3257 ic_info->used = intarg;
3260 else if (name == Mset || name == Madd || name == Msub
3261 || name == Mmul || name == Mdiv)
3263 MSymbol sym = MPLIST_SYMBOL (args);
3268 val1 = integer_value (ic, args, &value, 0);
3269 args = MPLIST_NEXT (args);
3270 val2 = resolve_expression (ic, args);
3272 val1 = val2, op = "=";
3273 else if (name == Madd)
3274 val1 += val2, op = "+=";
3275 else if (name == Msub)
3276 val1 -= val2, op = "-=";
3277 else if (name == Mmul)
3278 val1 *= val2, op = "*=";
3280 val1 /= val2, op = "/=";
3281 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3282 MSYMBOL_NAME (sym), op, val1, val1);
3284 mplist_set (value, Minteger, (void *) val1);
3286 else if (name == Mequal || name == Mless || name == Mgreater
3287 || name == Mless_equal || name == Mgreater_equal)
3290 MPlist *actions1, *actions2;
3293 val1 = resolve_expression (ic, args);
3294 args = MPLIST_NEXT (args);
3295 val2 = resolve_expression (ic, args);
3296 args = MPLIST_NEXT (args);
3297 actions1 = MPLIST_PLIST (args);
3298 args = MPLIST_NEXT (args);
3299 if (MPLIST_TAIL_P (args))
3302 actions2 = MPLIST_PLIST (args);
3303 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3304 if (name == Mequal ? val1 == val2
3305 : name == Mless ? val1 < val2
3306 : name == Mgreater ? val1 > val2
3307 : name == Mless_equal ? val1 <= val2
3310 MDEBUG_PRINT ("ok");
3311 ret = take_action_list (ic, actions1);
3315 MDEBUG_PRINT ("no");
3317 ret = take_action_list (ic, actions2);
3322 else if (name == Mcond)
3326 MPLIST_DO (args, args)
3331 if (! MPLIST_PLIST (args))
3333 cond = MPLIST_PLIST (args);
3334 if (resolve_expression (ic, cond) != 0)
3336 MDEBUG_PRINT1 ("(%dth)", idx);
3337 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3343 else if (name == Mcommit)
3345 preedit_commit (ic);
3347 else if (name == Munhandle)
3349 preedit_commit (ic);
3354 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3358 && (actions = mplist_get (im_info->macros, name)))
3360 if (take_action_list (ic, actions) < 0)
3366 if (ic->candidate_list)
3368 M17N_OBJECT_UNREF (ic->candidate_list);
3369 ic->candidate_list = NULL;
3371 if (ic->cursor_pos > 0
3372 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3375 ic->candidate_list = mtext_property_value (prop);
3376 M17N_OBJECT_REF (ic->candidate_list);
3378 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3380 ic->candidate_from = mtext_property_start (prop);
3381 ic->candidate_to = mtext_property_end (prop);
3384 if (candidate_list != ic->candidate_list)
3385 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3386 if (candidate_index != ic->candidate_index)
3387 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3388 if (candidate_show != ic->candidate_show)
3389 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3394 /* Handle the input key KEY in the current state and map specified in
3395 the input context IC. If KEY is handled correctly, return 0.
3396 Otherwise, return -1. */
3399 handle_key (MInputContext *ic)
3401 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3402 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3403 MIMMap *map = ic_info->map;
3404 MIMMap *submap = NULL;
3405 MSymbol key = ic_info->keys[ic_info->key_head];
3406 MSymbol alias = Mnil;
3409 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3410 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3414 submap = mplist_get (map->submaps, key);
3417 && (alias = msymbol_get (alias, M_key_alias))
3419 submap = mplist_get (map->submaps, alias);
3424 if (! alias || alias == key)
3425 MDEBUG_PRINT (" submap-found");
3427 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3428 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3429 ic->preedit_changed = 1;
3430 ic->cursor_pos = ic_info->state_pos;
3431 ic_info->key_head++;
3432 ic_info->map = map = submap;
3433 if (map->map_actions)
3435 MDEBUG_PRINT (" map-actions:");
3436 if (take_action_list (ic, map->map_actions) < 0)
3438 MDEBUG_PRINT ("\n");
3442 else if (map->submaps)
3444 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3446 MSymbol key = ic_info->keys[i];
3447 char *name = msymbol_name (key);
3449 if (! name[0] || ! name[1])
3450 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3454 /* If this is the terminal map or we have shifted to another
3455 state, perform branch actions (if any). */
3456 if (! map->submaps || map != ic_info->map)
3458 if (map->branch_actions)
3460 MDEBUG_PRINT (" branch-actions:");
3461 if (take_action_list (ic, map->branch_actions) < 0)
3463 MDEBUG_PRINT ("\n");
3467 /* If MAP is still not the root map, shift to the current
3469 if (ic_info->map != ic_info->state->map)
3470 shift_state (ic, ic_info->state->name);
3475 /* MAP can not handle KEY. */
3477 /* Perform branch actions if any. */
3478 if (map->branch_actions)
3480 MDEBUG_PRINT (" branch-actions:");
3481 if (take_action_list (ic, map->branch_actions) < 0)
3483 MDEBUG_PRINT ("\n");
3488 if (map == ic_info->map)
3490 /* The above branch actions didn't change the state. */
3492 /* If MAP is the root map of the initial state, and there
3493 still exist an unhandled key, it means that the current
3494 input method can not handle it. */
3495 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3496 && ic_info->key_head < ic_info->used)
3498 MDEBUG_PRINT (" unhandled\n");
3502 if (map != ic_info->state->map)
3504 /* MAP is not the root map. Shift to the root map of the
3506 shift_state (ic, ic_info->state->name);
3508 else if (! map->branch_actions)
3510 /* MAP is the root map without any default branch
3511 actions. Shift to the initial state. */
3512 shift_state (ic, Mnil);
3516 MDEBUG_PRINT ("\n");
3520 /* Initialize IC->ic_info. */
3523 init_ic_info (MInputContext *ic)
3525 MInputMethodInfo *im_info = ic->im->info;
3526 MInputContextInfo *ic_info = ic->info;
3529 MLIST_INIT1 (ic_info, keys, 8);;
3531 ic_info->markers = mplist ();
3533 ic_info->vars = mplist ();
3534 if (im_info->configured_vars)
3535 MPLIST_DO (plist, im_info->configured_vars)
3537 MPlist *pl = MPLIST_PLIST (plist);
3538 MSymbol name = MPLIST_SYMBOL (pl);
3540 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3541 if (MPLIST_KEY (pl) != Mt)
3543 MPlist *p = mplist ();
3545 mplist_push (ic_info->vars, Mplist, p);
3546 M17N_OBJECT_UNREF (p);
3547 mplist_add (p, Msymbol, name);
3548 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3551 ic_info->vars_saved = mplist_copy (ic_info->vars);
3553 if (im_info->externals)
3555 MPlist *func_args = mplist (), *plist;
3557 mplist_add (func_args, Mt, ic);
3558 MPLIST_DO (plist, im_info->externals)
3560 MIMExternalModule *external = MPLIST_VAL (plist);
3561 MIMExternalFunc func
3562 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3567 M17N_OBJECT_UNREF (func_args);
3570 ic_info->preedit_saved = mtext ();
3571 ic_info->tick = im_info->tick;
3574 /* Finalize IC->ic_info. */
3577 fini_ic_info (MInputContext *ic)
3579 MInputMethodInfo *im_info = ic->im->info;
3580 MInputContextInfo *ic_info = ic->info;
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, Mfini);
3596 M17N_OBJECT_UNREF (func_args);
3599 MLIST_FREE1 (ic_info, keys);
3600 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3601 M17N_OBJECT_UNREF (ic_info->markers);
3602 M17N_OBJECT_UNREF (ic_info->vars);
3603 M17N_OBJECT_UNREF (ic_info->vars_saved);
3604 M17N_OBJECT_UNREF (ic_info->preceding_text);
3605 M17N_OBJECT_UNREF (ic_info->following_text);
3607 memset (ic_info, 0, sizeof (MInputContextInfo));
3611 re_init_ic (MInputContext *ic, int reload)
3613 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3614 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3615 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3617 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3618 preedit_changed = mtext_nchars (ic->preedit) > 0;
3619 cursor_pos_changed = ic->cursor_pos > 0;
3620 candidates_changed = 0;
3621 if (ic->candidate_list)
3623 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3624 M17N_OBJECT_UNREF (ic->candidate_list);
3625 ic->candidate_list = NULL;
3627 if (ic->candidate_show)
3629 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3630 ic->candidate_show = 0;
3632 if (ic->candidate_index > 0)
3634 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3635 ic->candidate_index = 0;
3636 ic->candidate_from = ic->candidate_to = 0;
3638 if (mtext_nchars (ic->produced) > 0)
3639 mtext_reset (ic->produced);
3640 if (mtext_nchars (ic->preedit) > 0)
3641 mtext_reset (ic->preedit);
3643 M17N_OBJECT_UNREF (ic->plist);
3644 ic->plist = mplist ();
3648 reload_im_info (im_info);
3650 shift_state (ic, Mnil);
3651 ic->status_changed = status_changed;
3652 ic->preedit_changed = preedit_changed;
3653 ic->cursor_pos_changed = cursor_pos_changed;
3654 ic->candidates_changed = candidates_changed;
3658 reset_ic (MInputContext *ic, MSymbol ignore)
3660 MDEBUG_PRINT ("\n [IM] reset\n");
3665 open_im (MInputMethod *im)
3667 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3670 MERROR (MERROR_IM, -1);
3677 close_im (MInputMethod *im)
3683 create_ic (MInputContext *ic)
3685 MInputContextInfo *ic_info;
3687 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3690 shift_state (ic, Mnil);
3695 destroy_ic (MInputContext *ic)
3702 check_reload (MInputContext *ic, MSymbol key)
3704 MInputMethodInfo *im_info = ic->im->info;
3705 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3709 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3713 MPLIST_DO (plist, plist)
3715 MSymbol this_key, alias;
3717 if (MPLIST_MTEXT_P (plist))
3719 MText *mt = MPLIST_MTEXT (plist);
3720 int c = mtext_ref_char (mt, 0);
3724 this_key = one_char_symbol[c];
3728 MPlist *pl = MPLIST_PLIST (plist);
3730 this_key = MPLIST_SYMBOL (pl);
3734 && (alias = msymbol_get (alias, M_key_alias))
3735 && alias != this_key);
3739 if (MPLIST_TAIL_P (plist))
3742 MDEBUG_PRINT ("\n [IM] reload");
3748 /** Handle the input key KEY in the current state and map of IC->info.
3749 If KEY is handled but no text is produced, return 0, otherwise
3755 filter (MInputContext *ic, MSymbol key, void *arg)
3757 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3758 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3761 if (check_reload (ic, key))
3764 if (! ic_info->state)
3766 ic_info->key_unhandled = 1;
3769 mtext_reset (ic->produced);
3770 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3771 M17N_OBJECT_UNREF (ic_info->preceding_text);
3772 M17N_OBJECT_UNREF (ic_info->following_text);
3773 ic_info->preceding_text = ic_info->following_text = NULL;
3774 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3775 ic_info->key_unhandled = 0;
3778 if (handle_key (ic) < 0)
3780 /* KEY was not handled. Delete it from the current key sequence. */
3781 if (ic_info->used > 0)
3783 memmove (ic_info->keys, ic_info->keys + 1,
3784 sizeof (int) * (ic_info->used - 1));
3786 if (ic_info->state_key_head > 0)
3787 ic_info->state_key_head--;
3788 if (ic_info->commit_key_head > 0)
3789 ic_info->commit_key_head--;
3791 /* This forces returning 1. */
3792 ic_info->key_unhandled = 1;
3798 reset_ic (ic, Mnil);
3799 ic_info->key_unhandled = 1;
3802 /* Break the loop if all keys were handled. */
3803 } while (ic_info->key_head < ic_info->used);
3805 /* If the current map is the root of the initial state, we should
3806 produce any preedit text in ic->produced. */
3807 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3808 preedit_commit (ic);
3810 if (mtext_nchars (ic->produced) > 0)
3812 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3814 if (mdebug__flag & mdebug_mask)
3816 MDEBUG_PRINT (" (produced");
3817 for (i = 0; i < mtext_nchars (ic->produced); i++)
3818 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3823 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3824 Mlanguage, ic->im->language);
3826 if (ic_info->commit_key_head > 0)
3828 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3829 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3830 ic_info->used -= ic_info->commit_key_head;
3831 ic_info->key_head -= ic_info->commit_key_head;
3832 ic_info->state_key_head -= ic_info->commit_key_head;
3833 ic_info->commit_key_head = 0;
3835 if (ic_info->key_unhandled)
3838 ic_info->key_head = ic_info->state_key_head
3839 = ic_info->commit_key_head = 0;
3842 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3846 /** Return 1 if the last event or key was not handled, otherwise
3849 There is no need of looking up because ic->produced should already
3850 contain the produced text (if any).
3855 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3857 mtext_cat (mt, ic->produced);
3858 mtext_reset (ic->produced);
3859 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3863 /* Input method command handler. */
3865 /* List of all (global and local) commands.
3866 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3867 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3868 Global commands are stored as (t (t COMMAND ...)) */
3871 /* Input method variable handler. */
3874 /* Support functions for mdebug_dump_im. */
3877 dump_im_map (MPlist *map_list, int indent)
3880 MSymbol key = MPLIST_KEY (map_list);
3881 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3883 prefix = (char *) alloca (indent + 1);
3884 memset (prefix, 32, indent);
3885 prefix[indent] = '\0';
3887 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3888 if (map->map_actions)
3889 mdebug_dump_plist (map->map_actions, indent + 2);
3892 MPLIST_DO (map_list, map->submaps)
3894 fprintf (stderr, "\n%s ", prefix);
3895 dump_im_map (map_list, indent + 2);
3898 if (map->branch_actions)
3900 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3901 mdebug_dump_plist (map->branch_actions, indent + 4);
3902 fprintf (stderr, ")");
3904 fprintf (stderr, ")");
3909 dump_im_state (MIMState *state, int indent)
3914 prefix = (char *) alloca (indent + 1);
3915 memset (prefix, 32, indent);
3916 prefix[indent] = '\0';
3918 fprintf (stderr, "(%s", msymbol_name (state->name));
3919 if (state->map->submaps)
3921 MPLIST_DO (map_list, state->map->submaps)
3923 fprintf (stderr, "\n%s ", prefix);
3924 dump_im_map (map_list, indent + 2);
3927 fprintf (stderr, ")");
3935 Minput_driver = msymbol ("input-driver");
3937 Minput_preedit_start = msymbol ("input-preedit-start");
3938 Minput_preedit_done = msymbol ("input-preedit-done");
3939 Minput_preedit_draw = msymbol ("input-preedit-draw");
3940 Minput_status_start = msymbol ("input-status-start");
3941 Minput_status_done = msymbol ("input-status-done");
3942 Minput_status_draw = msymbol ("input-status-draw");
3943 Minput_candidates_start = msymbol ("input-candidates-start");
3944 Minput_candidates_done = msymbol ("input-candidates-done");
3945 Minput_candidates_draw = msymbol ("input-candidates-draw");
3946 Minput_set_spot = msymbol ("input-set-spot");
3947 Minput_focus_move = msymbol ("input-focus-move");
3948 Minput_focus_in = msymbol ("input-focus-in");
3949 Minput_focus_out = msymbol ("input-focus-out");
3950 Minput_toggle = msymbol ("input-toggle");
3951 Minput_reset = msymbol ("input-reset");
3952 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3953 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3954 Mcustomized = msymbol ("customized");
3955 Mconfigured = msymbol ("configured");
3956 Minherited = msymbol ("inherited");
3958 minput_default_driver.open_im = open_im;
3959 minput_default_driver.close_im = close_im;
3960 minput_default_driver.create_ic = create_ic;
3961 minput_default_driver.destroy_ic = destroy_ic;
3962 minput_default_driver.filter = filter;
3963 minput_default_driver.lookup = lookup;
3964 minput_default_driver.callback_list = mplist ();
3965 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
3966 M17N_FUNC (reset_ic));
3967 minput_driver = &minput_default_driver;
3969 fully_initialized = 0;
3976 if (fully_initialized)
3978 free_im_list (im_info_list);
3980 free_im_list (im_custom_list);
3982 free_im_list (im_config_list);
3983 M17N_OBJECT_UNREF (load_im_info_keys);
3986 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3987 M17N_OBJECT_UNREF (minput_driver->callback_list);
3992 minput__char_to_key (int c)
3994 if (c < 0 || c >= 0x100)
3997 return one_char_symbol[c];
4001 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4006 /*** @addtogroup m17nInputMethod */
4011 @name Variables: Predefined symbols for callback commands.
4013 These are the predefined symbols that are used as the @c COMMAND
4014 argument of callback functions of an input method driver (see
4015 #MInputDriver::callback_list).
4017 Most of them do not require extra argument nor return any value;
4018 exceptions are these:
4020 Minput_get_surrounding_text: When a callback function assigned for
4021 this command is called, the first element of #MInputContext::plist
4022 has key #Minteger and the value specifies which portion of the
4023 surrounding text should be retrieved. If the value is positive,
4024 it specifies the number of characters following the current cursor
4025 position. If the value is negative, the absolute value specifies
4026 the number of characters preceding the current cursor position.
4027 If the value is zero, it means that the caller just wants to know
4028 if the surrounding text is currently supported or not.
4030 If the surrounding text is currently supported, the callback
4031 function must set the key of this element to #Mtext and the value
4032 to the retrieved M-text. The length of the M-text may be shorter
4033 than the requested number of characters, if the available text is
4034 not that long. The length can be zero in the worst case. Or, the
4035 length may be longer if an application thinks it is more efficient
4036 to return that length.
4038 If the surrounding text is not currently supported, the callback
4039 function should return without changing the first element of
4040 #MInputContext::plist.
4042 Minput_delete_surrounding_text: When a callback function assigned
4043 for this command is called, the first element of
4044 #MInputContext::plist has key #Minteger and the value specifies
4045 which portion of the surrounding text should be deleted in the
4046 same way as the case of Minput_get_surrounding_text. The callback
4047 function must delete the specified text. It should not alter
4048 #MInputContext::plist. */
4050 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4052 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4053 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4055 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4057 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4058 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4059 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4060 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4061 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4062 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4063 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4065 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4066 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4067 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4068 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4069 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4071 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4072 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4074 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4075 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4076 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4077 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4078 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4079 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4083 MSymbol Minput_preedit_start;
4084 MSymbol Minput_preedit_done;
4085 MSymbol Minput_preedit_draw;
4086 MSymbol Minput_status_start;
4087 MSymbol Minput_status_done;
4088 MSymbol Minput_status_draw;
4089 MSymbol Minput_candidates_start;
4090 MSymbol Minput_candidates_done;
4091 MSymbol Minput_candidates_draw;
4092 MSymbol Minput_set_spot;
4093 MSymbol Minput_toggle;
4094 MSymbol Minput_reset;
4095 MSymbol Minput_get_surrounding_text;
4096 MSymbol Minput_delete_surrounding_text;
4102 @name Variables: Predefined symbols for special input events.
4104 These are the predefined symbols that are used as the @c KEY
4105 argument of minput_filter (). */
4107 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4109 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4114 MSymbol Minput_focus_out;
4115 MSymbol Minput_focus_in;
4116 MSymbol Minput_focus_move;
4122 @name Variables: Predefined symbols used in input method information.
4124 These are the predefined symbols describing status of input method
4125 command and variable, and are used in a return value of
4126 minput_get_command () and minput_get_variable (). */
4128 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4130 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4131 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4135 MSymbol Mcustomized;
4136 MSymbol Mconfigured;
4142 @brief The default driver for internal input methods.
4144 The variable #minput_default_driver is the default driver for
4145 internal input methods.
4147 The member MInputDriver::open_im () searches the m17n database for
4148 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4149 $NAME\> and loads it.
4151 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4152 programmers responsibility to set it to a plist of proper callback
4153 functions. Otherwise, no feedback information (e.g. preedit text)
4154 can be shown to users.
4156 The macro M17N_INIT () sets the variable #minput_driver to the
4157 pointer to this driver so that all internal input methods use it.
4159 Therefore, unless @c minput_driver is set differently, the driver
4160 dependent arguments $ARG of the functions whose name begins with
4161 "minput_" are all ignored. */
4163 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4165 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4167 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4168 \< #Minput_method, $LANGUAGE, $NAME\>
4169 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4171 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4172 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4173 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4174 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4176 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4177 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4179 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4180 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4182 MInputDriver minput_default_driver;
4186 @brief The driver for internal input methods.
4188 The variable #minput_driver is a pointer to the input method
4189 driver that is used by internal input methods. The macro
4190 M17N_INIT () initializes it to a pointer to #minput_default_driver
4191 if <m17n<EM></EM>.h> is included. */
4193 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4195 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4196 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4197 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4198 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4200 MInputDriver *minput_driver;
4202 MSymbol Minput_driver;
4217 @brief Open an input method.
4219 The minput_open_im () function opens an input method whose
4220 language and name match $LANGUAGE and $NAME, and returns a pointer
4221 to the input method object newly allocated.
4223 This function at first decides a driver for the input method as
4226 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4227 #minput_driver is used.
4229 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4230 driver pointed to by the property value is used to open the input
4231 method. If $NAME has no such a property, @c NULL is returned.
4233 Then, the member MInputDriver::open_im () of the driver is
4236 $ARG is set in the member @c arg of the structure MInputMethod so
4237 that the driver can refer to it. */
4239 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4241 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4242 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4244 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4246 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4247 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4249 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4250 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4251 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4253 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4255 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4257 @latexonly \IPAlabel{minput_open} @endlatexonly
4262 minput_open_im (MSymbol language, MSymbol name, void *arg)
4265 MInputDriver *driver;
4269 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4270 msymbol_name (language), msymbol_name (name));
4272 driver = minput_driver;
4275 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4277 MERROR (MERROR_IM, NULL);
4280 MSTRUCT_CALLOC (im, MERROR_IM);
4281 im->language = language;
4284 im->driver = *driver;
4285 if ((*im->driver.open_im) (im) < 0)
4287 MDEBUG_PRINT (" failed\n");
4291 MDEBUG_PRINT (" ok\n");
4298 @brief Close an input method.
4300 The minput_close_im () function closes the input method $IM, which
4301 must have been created by minput_open_im (). */
4304 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4306 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4307 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4310 minput_close_im (MInputMethod *im)
4312 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4313 msymbol_name (im->name), msymbol_name (im->language));
4314 (*im->driver.close_im) (im);
4316 MDEBUG_PRINT (" done\n");
4322 @brief Create an input context.
4324 The minput_create_ic () function creates an input context object
4325 associated with input method $IM, and calls callback functions
4326 corresponding to #Minput_preedit_start, #Minput_status_start, and
4327 #Minput_status_draw in this order.
4330 If an input context is successfully created, minput_create_ic ()
4331 returns a pointer to it. Otherwise it returns @c NULL. */
4334 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4336 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4337 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4338 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4339 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4342 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4343 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4347 minput_create_ic (MInputMethod *im, void *arg)
4351 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4352 msymbol_name (im->name), msymbol_name (im->language));
4353 MSTRUCT_CALLOC (ic, MERROR_IM);
4356 ic->preedit = mtext ();
4357 ic->candidate_list = NULL;
4358 ic->produced = mtext ();
4359 ic->spot.x = ic->spot.y = 0;
4361 ic->plist = mplist ();
4362 if ((*im->driver.create_ic) (ic) < 0)
4364 MDEBUG_PRINT (" failed\n");
4365 M17N_OBJECT_UNREF (ic->preedit);
4366 M17N_OBJECT_UNREF (ic->produced);
4367 M17N_OBJECT_UNREF (ic->plist);
4372 if (im->driver.callback_list)
4374 minput_callback (ic, Minput_preedit_start);
4375 minput_callback (ic, Minput_status_start);
4376 minput_callback (ic, Minput_status_draw);
4379 MDEBUG_PRINT (" ok\n");
4386 @brief Destroy an input context.
4388 The minput_destroy_ic () function destroys the input context $IC,
4389 which must have been created by minput_create_ic (). It calls
4390 callback functions corresponding to #Minput_preedit_done,
4391 #Minput_status_done, and #Minput_candidates_done in this order. */
4394 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4396 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4397 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4398 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4399 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4400 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4404 minput_destroy_ic (MInputContext *ic)
4406 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4407 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4408 if (ic->im->driver.callback_list)
4410 minput_callback (ic, Minput_preedit_done);
4411 minput_callback (ic, Minput_status_done);
4412 minput_callback (ic, Minput_candidates_done);
4414 (*ic->im->driver.destroy_ic) (ic);
4415 M17N_OBJECT_UNREF (ic->preedit);
4416 M17N_OBJECT_UNREF (ic->produced);
4417 M17N_OBJECT_UNREF (ic->plist);
4418 MDEBUG_PRINT (" done\n");
4425 @brief Filter an input key.
4427 The minput_filter () function filters input key $KEY according to
4428 input context $IC, and calls callback functions corresponding to
4429 #Minput_preedit_draw, #Minput_status_draw, and
4430 #Minput_candidates_draw if the preedit text, the status, and the
4431 current candidate are changed respectively.
4433 To make the input method commit the current preedit text (if any)
4434 and shift to the initial state, call this function with #Mnil as
4437 To inform the input method about the focus-out event, call this
4438 function with #Minput_focus_out as $KEY.
4440 To inform the input method about the focus-in event, call this
4441 function with #Minput_focus_in as $KEY.
4443 To inform the input method about the focus-move event (i.e. input
4444 spot change within the same input context), call this function
4445 with #Minput_focus_move as $KEY.
4448 If $KEY is filtered out, this function returns 1. In that case,
4449 the caller should discard the key. Otherwise, it returns 0, and
4450 the caller should handle the key, for instance, by calling the
4451 function minput_lookup () with the same key. */
4454 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4456 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4457 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4458 #Minput_preedit_draw, #Minput_status_draw,
4459 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4462 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4463 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4464 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4465 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4467 @latexonly \IPAlabel{minput_filter} @endlatexonly
4471 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4478 if (ic->im->driver.callback_list
4479 && mtext_nchars (ic->preedit) > 0)
4480 minput_callback (ic, Minput_preedit_draw);
4482 ret = (*ic->im->driver.filter) (ic, key, arg);
4484 if (ic->im->driver.callback_list)
4486 if (ic->preedit_changed)
4487 minput_callback (ic, Minput_preedit_draw);
4488 if (ic->status_changed)
4489 minput_callback (ic, Minput_status_draw);
4490 if (ic->candidates_changed)
4491 minput_callback (ic, Minput_candidates_draw);
4500 @brief Look up a text produced in the input context.
4502 The minput_lookup () function looks up a text in the input context
4503 $IC. $KEY must be identical to the one that was used in the previous call of
4506 If a text was produced by the input method, it is concatenated
4509 This function calls #MInputDriver::lookup .
4512 If $KEY was correctly handled by the input method, this function
4513 returns 0. Otherwise, it returns -1, even though some text
4514 might be produced in $MT. */
4517 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4519 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4520 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4522 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4525 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4528 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4529 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4530 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4532 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4535 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4537 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4542 @brief Set the spot of the input context.
4544 The minput_set_spot () function sets the spot of input context $IC
4545 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4546 The semantics of these values depends on the input method driver.
4548 For instance, a driver designed to work in a CUI environment may
4549 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4550 $DESCENT . A driver designed to work in a window system may
4551 interpret $X and $Y as the pixel offsets relative to the origin of the
4552 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4553 descent pixels of the line at ($X . $Y ).
4555 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4557 $MT and $POS are the M-text and the character position at the spot.
4558 $MT may be @c NULL, in which case, the input method cannot get
4559 information about the text around the spot. */
4562 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4564 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4565 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4566 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4568 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4569 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4570 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4571 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4572 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4573 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4575 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4577 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4578 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4582 minput_set_spot (MInputContext *ic, int x, int y,
4583 int ascent, int descent, int fontsize,
4588 ic->spot.ascent = ascent;
4589 ic->spot.descent = descent;
4590 ic->spot.fontsize = fontsize;
4593 if (ic->im->driver.callback_list)
4594 minput_callback (ic, Minput_set_spot);
4599 @brief Toggle input method.
4601 The minput_toggle () function toggles the input method associated
4602 with input context $IC. */
4604 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4606 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4607 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4611 minput_toggle (MInputContext *ic)
4613 if (ic->im->driver.callback_list)
4614 minput_callback (ic, Minput_toggle);
4615 ic->active = ! ic->active;
4621 @brief Reset an input context.
4623 The minput_reset_ic () function resets input context $IC by
4624 calling a callback function corresponding to #Minput_reset. It
4625 resets the status of $IC to its initial one. As the
4626 current preedit text is deleted without commitment, if necessary,
4627 call minput_filter () with the arg @r key #Mnil to force the input
4628 method to commit the preedit in advance. */
4631 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4633 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4634 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4635 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4636 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4637 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4638 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4641 minput_reset_ic (MInputContext *ic)
4643 if (ic->im->driver.callback_list)
4644 minput_callback (ic, Minput_reset);
4650 @brief Get title and icon filename of an input method.
4652 The minput_get_title_icon () function returns a plist containing a
4653 title and icon filename (if any) of an input method specified by
4654 $LANGUAGE and $NAME.
4656 The first element of the plist has key #Mtext and the value is an
4657 M-text of the title for identifying the input method. The second
4658 element (if any) has key #Mtext and the value is an M-text of the
4659 icon image (absolute) filename for the same purpose.
4662 If there exists a specified input method and it defines an title,
4663 a plist is returned. Otherwise, NULL is returned. The caller
4664 must free the plist by m17n_object_unref (). */
4666 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4668 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4669 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4672 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4673 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4674 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4677 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4678 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4679 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4682 minput_get_title_icon (MSymbol language, MSymbol name)
4684 MInputMethodInfo *im_info;
4691 im_info = get_im_info (language, name, Mnil, Mtitle);
4692 if (! im_info || !im_info->title)
4694 mt = mtext_get_prop (im_info->title, 0, Mtext);
4696 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4699 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4702 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4703 (char *) MSYMBOL_NAME (name));
4704 file = mdatabase__find_file (buf);
4705 if (! file && language == Mt)
4707 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4708 file = mdatabase__find_file (buf);
4713 mplist_add (plist, Mtext, im_info->title);
4716 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4718 mplist_add (plist, Mtext, mt);
4719 M17N_OBJECT_UNREF (mt);
4727 @brief Get description text of an input method.
4729 The minput_get_description () function returns an M-text that
4730 describes the input method specified by $LANGUAGE and $NAME.
4733 If the specified input method has a description text, a pointer to
4734 #MText is returned. The caller has to free it by m17n_object_unref ().
4735 If the input method does not have a description text, @c NULL is
4738 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4740 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4741 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4743 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4744 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4745 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4746 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4749 minput_get_description (MSymbol language, MSymbol name)
4751 MInputMethodInfo *im_info;
4759 extra = language, language = Mt;
4761 im_info = get_im_info (language, name, extra, Mdescription);
4762 if (! im_info || ! im_info->description)
4764 M17N_OBJECT_REF (im_info->description);
4765 return im_info->description;
4771 @brief Get information about input method command(s).
4773 The minput_get_command () function returns information about
4774 the command $COMMAND of the input method specified by $LANGUAGE and
4775 $NAME. An input method command is a pseudo key event to which one
4776 or more actual input key sequences are assigned.
4778 There are two kinds of commands, global and local. A global
4779 command has a global definition, and the description and the key
4780 assignment may be inherited by a local command. Each input method
4781 defines a local command which has a local key assignment. It may
4782 also declare a local command that inherits the definition of a
4783 global command of the same name.
4785 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4786 information about a global command. Otherwise information about a
4787 local command is returned.
4789 If $COMMAND is #Mnil, information about all commands is returned.
4791 The return value is a @e well-formed plist (#m17nPlist) of this
4794 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4796 @c NAME is a symbol representing the command name.
4798 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4799 command has no description.
4801 @c STATUS is a symbol representing how the key assignment is decided.
4802 The value is #Mnil (the default key assignment), #Mcustomized (the
4803 key assignment is customized by per-user customization file), or
4804 #Mconfigured (the key assignment is set by the call of
4805 minput_config_command ()). For a local command only, it may also
4806 be #Minherited (the key assignment is inherited from the
4807 corresponding global command).
4809 @c KEYSEQ is a plist of one or more symbols representing a key
4810 sequence assigned to the command. If there's no KEYSEQ, the
4811 command is currently disabled (i.e. no key sequence can trigger
4812 actions of the command).
4814 If $COMMAND is not #Mnil, the first element of the returned plist
4815 contains the information about $COMMAND.
4819 If the requested information was found, a pointer to a non-empty
4820 plist is returned. As the plist is kept in the library, the
4821 caller must not modify nor free it.
4823 Otherwise (the specified input method or the specified command
4824 does not exist), @c NULL is returned. */
4826 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4828 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4829 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4830 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4831 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4833 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4834 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4835 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4836 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4837 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4839 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4840 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4843 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4845 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4848 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4850 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4852 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4855 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4856 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4857 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4858 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4859 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4860 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4863 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4864 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4865 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4866 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4868 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4869 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4873 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4874 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4877 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4882 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4884 /* Return a description of the command COMMAND of the input method
4885 specified by LANGUAGE and NAME. */
4886 MPlist *cmd = minput_get_command (langauge, name, command);
4891 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4892 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4893 return (mplist_key (plist) == Mtext
4894 ? (MText *) mplist_value (plist)
4900 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4902 MInputMethodInfo *im_info;
4906 im_info = get_im_info (language, name, Mnil, Mcommand);
4908 || ! im_info->configured_cmds
4909 || MPLIST_TAIL_P (im_info->configured_cmds))
4911 if (command == Mnil)
4912 return im_info->configured_cmds;
4913 return mplist__assq (im_info->configured_cmds, command);
4919 @brief Configure the key sequence of an input method command.
4921 The minput_config_command () function assigns a list of key
4922 sequences $KEYSEQLIST to the command $COMMAND of the input method
4923 specified by $LANGUAGE and $NAME.
4925 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4926 sequences, and each key sequence must be a plist of symbols.
4928 If $KEYSEQLIST is an empty plist, any configuration and
4929 customization of the command are cancelled, and default key
4930 sequences become effective.
4932 If $KEYSEQLIST is NULL, the configuration of the command is
4933 canceled, and the original key sequences (what saved in per-user
4934 customization file, or the default one) become effective.
4936 In the latter two cases, $COMMAND can be #Mnil to make all the
4937 commands of the input method the target of the operation.
4939 If $NAME is #Mnil, this function configures the key assignment of a
4940 global command, not that of a specific input method.
4942 The configuration takes effect for input methods opened or
4943 re-opened later in the current session. In order to make the
4944 configuration take effect for the future session, it must be saved
4945 in a per-user customization file by the function
4946 minput_save_config ().
4949 If the operation was successful, this function returns 0,
4950 otherwise returns -1. The operation fails in these cases:
4952 <li>$KEYSEQLIST is not in a valid form.
4953 <li>$COMMAND is not available for the input method.
4954 <li>$LANGUAGE and $NAME do not specify an existing input method.
4958 minput_get_commands (), minput_save_config ().
4961 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4963 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4964 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4965 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4967 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4968 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4970 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
4971 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
4973 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
4974 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
4975 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
4977 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
4978 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
4980 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4981 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4983 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4984 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4985 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
4986 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4990 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4992 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4993 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4994 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4998 minput_get_commands (), minput_save_config ().
5002 /* Add "C-x u" to the "start" command of Unicode input method. */
5004 MSymbol start_command = msymbol ("start");
5005 MSymbol unicode = msymbol ("unicode");
5006 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5008 /* At first get the current key-sequence assignment. */
5009 cmd = minput_get_command (Mt, unicode, start_command);
5012 /* The input method does not have the command "start". Here
5013 should come some error handling code. */
5015 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5016 Extract the part (KEY-SEQUENCE ...). */
5017 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5018 /* Copy it because we should not modify it directly. */
5019 key_seq_list = mplist_copy (plist);
5021 key_seq = mplist ();
5022 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5023 mplist_add (key_seq, Msymbol, msymbol ("u"));
5024 mplist_add (key_seq_list, Mplist, key_seq);
5025 m17n_object_unref (key_seq);
5027 minput_config_command (Mt, unicode, start_command, key_seq_list);
5028 m17n_object_unref (key_seq_list);
5033 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5036 MInputMethodInfo *im_info, *config;
5041 im_info = get_im_info (language, name, Mnil, Mcommand);
5043 MERROR (MERROR_IM, -1);
5044 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5046 || ! mplist__assq (im_info->configured_cmds, command)))
5047 MERROR (MERROR_IM, -1);
5048 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5050 MPLIST_DO (plist, keyseqlist)
5051 if (! check_command_keyseq (plist))
5052 MERROR (MERROR_IM, -1);
5055 config = get_config_info (im_info);
5058 if (! im_config_list)
5059 im_config_list = mplist ();
5060 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5061 config->cmds = mplist ();
5062 config->vars = mplist ();
5065 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5066 /* Nothing to do. */
5069 if (command == Mnil)
5073 /* Cancal the configuration. */
5074 if (MPLIST_TAIL_P (config->cmds))
5076 mplist_set (config->cmds, Mnil, NULL);
5080 /* Cancal the customization. */
5081 MInputMethodInfo *custom = get_custom_info (im_info);
5083 if (MPLIST_TAIL_P (config->cmds)
5084 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5085 /* Nothing to do. */
5087 mplist_set (config->cmds, Mnil, NULL);
5088 MPLIST_DO (plist, custom->cmds)
5090 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5092 mplist_add (plist, Msymbol, command);
5093 mplist_push (config->cmds, Mplist, plist);
5094 M17N_OBJECT_UNREF (plist);
5100 plist = mplist__assq (config->cmds, command);
5103 /* Cancel the configuration. */
5106 mplist__pop_unref (plist);
5108 else if (MPLIST_TAIL_P (keyseqlist))
5110 /* Cancel the customization. */
5111 MInputMethodInfo *custom = get_custom_info (im_info);
5112 int no_custom = (! custom || ! custom->cmds
5113 || ! mplist__assq (custom->cmds, command));
5119 mplist_add (config->cmds, Mplist, plist);
5120 M17N_OBJECT_UNREF (plist);
5121 plist = mplist_add (plist, Msymbol, command);
5126 mplist__pop_unref (plist);
5129 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5130 plist = MPLIST_NEXT (plist);
5131 mplist_set (plist, Mnil, NULL);
5141 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5142 if (! MPLIST_TAIL_P (plist))
5143 mplist_set (plist, Mnil, NULL);
5148 mplist_add (config->cmds, Mplist, plist);
5149 M17N_OBJECT_UNREF (plist);
5150 plist = mplist_add (plist, Msymbol, command);
5151 plist = MPLIST_NEXT (plist);
5153 MPLIST_DO (keyseqlist, keyseqlist)
5155 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5156 plist = mplist_add (plist, Mplist, pl);
5157 M17N_OBJECT_UNREF (pl);
5161 config_all_commands (im_info);
5162 im_info->tick = time (NULL);
5169 @brief Get information about input method variable(s).
5171 The minput_get_variable () function returns information about
5172 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5173 An input method variable controls behavior of an input method.
5175 There are two kinds of variables, global and local. A global
5176 variable has a global definition, and the description and the value
5177 may be inherited by a local variable. Each input method defines a
5178 local variable which has local value. It may also declare a
5179 local variable that inherits definition of a global variable of
5182 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5183 variable is returned. Otherwise information about a local variable
5186 If $VARIABLE is #Mnil, information about all variables is
5189 The return value is a @e well-formed plist (#m17nPlist) of this
5192 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5194 @c NAME is a symbol representing the variable name.
5196 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5197 variable has no description.
5199 @c STATUS is a symbol representing how the value is decided. The
5200 value is #Mnil (the default value), #Mcustomized (the value is
5201 customized by per-user customization file), or #Mconfigured (the
5202 value is set by the call of minput_config_variable ()). For a
5203 local variable only, it may also be #Minherited (the value is
5204 inherited from the corresponding global variable).
5206 @c VALUE is the initial value of the variable. If the key of this
5207 element is #Mt, the variable has no initial value. Otherwise, the
5208 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5211 @c VALID-VALUEs (if any) specify which values the variable can have.
5212 They have the same type (i.e. having the same key) as @c VALUE except
5213 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5214 may be a plist of two integers specifying the range of possible
5217 If there no @c VALID-VALUE, the variable can have any value as long
5218 as the type is the same as @c VALUE.
5220 If $VARIABLE is not #Mnil, the first element of the returned plist
5221 contains the information about $VARIABLE.
5225 If the requested information was found, a pointer to a non-empty
5226 plist is returned. As the plist is kept in the library, the
5227 caller must not modify nor free it.
5229 Otherwise (the specified input method or the specified variable
5230 does not exist), @c NULL is returned. */
5232 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5234 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5235 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5236 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5238 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5239 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5240 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5241 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5244 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5245 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5247 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5249 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5251 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5254 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5256 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5259 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5260 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5261 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5262 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5263 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5264 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5266 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5267 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5268 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5270 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5271 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5272 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5273 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5275 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5278 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5279 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5283 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5284 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5287 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5291 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5293 MInputMethodInfo *im_info;
5297 im_info = get_im_info (language, name, Mnil, Mvariable);
5298 if (! im_info || ! im_info->configured_vars)
5300 if (variable == Mnil)
5301 return im_info->configured_vars;
5302 return mplist__assq (im_info->configured_vars, variable);
5308 @brief Configure the value of an input method variable.
5310 The minput_config_variable () function assigns $VALUE to the
5311 variable $VARIABLE of the input method specified by $LANGUAGE and
5314 If $VALUE is a non-empty plist, it must be a plist of one element
5315 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5316 the corresponding type. That value is assigned to the variable.
5318 If $VALUE is an empty plist, any configuration and customization
5319 of the variable are canceled, and the default value is assigned to
5322 If $VALUE is NULL, the configuration of the variable is canceled,
5323 and the original value (what saved in per-user customization file,
5324 or the default value) is assigned to the variable.
5326 In the latter two cases, $VARIABLE can be #Mnil to make all the
5327 variables of the input method the target of the operation.
5329 If $NAME is #Mnil, this function configures the value of global
5330 variable, not that of a specific input method.
5332 The configuration takes effect for input methods opened or
5333 re-opened later in the current session. To make the configuration
5334 take effect for the future session, it must be saved in a per-user
5335 customization file by the function minput_save_config ().
5339 If the operation was successful, this function returns 0,
5340 otherwise returns -1. The operation fails in these cases:
5342 <li>$VALUE is not in a valid form, the type does not match the
5343 definition, or the value is our of range.
5344 <li>$VARIABLE is not available for the input method.
5345 <li>$LANGUAGE and $NAME do not specify an existing input method.
5349 minput_get_variable (), minput_save_config (). */
5351 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5353 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5354 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5356 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5357 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5358 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5360 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5361 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5363 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5364 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5366 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5367 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5369 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5370 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5372 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5373 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5374 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5375 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5379 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5381 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5382 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5383 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5387 minput_get_commands (), minput_save_config ().
5390 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5393 MInputMethodInfo *im_info, *config;
5398 im_info = get_im_info (language, name, Mnil, Mvariable);
5400 MERROR (MERROR_IM, -1);
5401 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5403 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5404 MERROR (MERROR_IM, -1);
5406 if (value && ! MPLIST_TAIL_P (value))
5408 plist = MPLIST_PLIST (plist);
5409 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5410 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5411 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5412 if (MPLIST_KEY (plist) != Mt
5413 && ! check_variable_value (value, plist))
5414 MERROR (MERROR_IM, -1);
5417 config = get_config_info (im_info);
5420 if (! im_config_list)
5421 im_config_list = mplist ();
5422 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5423 config->cmds = mplist ();
5424 config->vars = mplist ();
5427 if (! value && MPLIST_TAIL_P (config->vars))
5428 /* Nothing to do. */
5431 if (variable == Mnil)
5435 /* Cancel the configuration. */
5436 if (MPLIST_TAIL_P (config->vars))
5438 mplist_set (config->vars, Mnil, NULL);
5442 /* Cancel the customization. */
5443 MInputMethodInfo *custom = get_custom_info (im_info);
5445 if (MPLIST_TAIL_P (config->vars)
5446 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5447 /* Nothing to do. */
5449 mplist_set (config->vars, Mnil, NULL);
5450 MPLIST_DO (plist, custom->vars)
5452 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5454 mplist_add (plist, Msymbol, variable);
5455 mplist_push (config->vars, Mplist, plist);
5456 M17N_OBJECT_UNREF (plist);
5462 plist = mplist__assq (config->vars, variable);
5465 /* Cancel the configuration. */
5468 mplist__pop_unref (plist);
5470 else if (MPLIST_TAIL_P (value))
5472 /* Cancel the customization. */
5473 MInputMethodInfo *custom = get_custom_info (im_info);
5474 int no_custom = (! custom || ! custom->vars
5475 || ! mplist__assq (custom->vars, variable));
5481 mplist_add (config->vars, Mplist, plist);
5482 M17N_OBJECT_UNREF (plist);
5483 plist = mplist_add (plist, Msymbol, variable);
5488 mplist__pop_unref (plist);
5491 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5492 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5493 mplist_set (plist, Mnil ,NULL);
5501 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5502 if (! MPLIST_TAIL_P (plist))
5503 mplist_set (plist, Mnil, NULL);
5508 mplist_add (config->vars, Mplist, plist);
5509 M17N_OBJECT_UNREF (plist);
5510 plist = mplist_add (plist, Msymbol, variable);
5511 plist = MPLIST_NEXT (plist);
5513 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5516 config_all_variables (im_info);
5517 im_info->tick = time (NULL);
5524 @brief Get the name of per-user customization file.
5526 The minput_config_file () function returns the absolute path name
5527 of per-user customization file into which minput_save_config ()
5528 save configurations. It is usually @c "config.mic" under the
5529 directory @c ".m17n.d" of user's home directory. It is not assured
5530 that the file of the returned name exists nor is
5531 readable/writable. If minput_save_config () fails and returns -1,
5532 an application program might check the file, make it
5533 writable (if possible), and try minput_save_config () again.
5537 This function returns a string. As the string is kept in the
5538 library, the caller must not modify nor free it.
5541 minput_save_config ()
5544 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5546 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5547 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5548 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5549 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5550 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5551 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5552 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5557 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5558 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5561 minput_save_config ()
5565 minput_config_file ()
5569 return mdatabase__file (im_custom_mdb);
5575 @brief Save configurations in per-user customization file.
5577 The minput_save_config () function saves the configurations done
5578 so far in the current session into the per-user customization
5583 If the operation was successful, 1 is returned. If the per-user
5584 customization file is currently locked, 0 is returned. In that
5585 case, the caller may wait for a while and try again. If the
5586 configuration file is not writable, -1 is returned. In that case,
5587 the caller may check the name of the file by calling
5588 minput_config_file (), make it writable if possible, and try
5592 minput_config_file () */
5594 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5596 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5597 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5601 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5602 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5603 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5604 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5608 minput_config_file () */
5611 minput_save_config (void)
5613 MPlist *data, *tail, *plist, *p, *elt;
5617 ret = mdatabase__lock (im_custom_mdb);
5620 if (! im_config_list)
5622 update_custom_info ();
5623 if (! im_custom_list)
5624 im_custom_list = mplist ();
5626 /* At first, reflect configuration in customization. */
5627 MPLIST_DO (plist, im_config_list)
5629 MPlist *pl = MPLIST_PLIST (plist);
5630 MSymbol language, name, extra, command, variable;
5631 MInputMethodInfo *custom, *config;
5633 language = MPLIST_SYMBOL (pl);
5634 pl = MPLIST_NEXT (pl);
5635 name = MPLIST_SYMBOL (pl);
5636 pl = MPLIST_NEXT (pl);
5637 extra = MPLIST_SYMBOL (pl);
5638 pl = MPLIST_NEXT (pl);
5639 config = MPLIST_VAL (pl);
5640 custom = get_custom_info (config);
5642 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5644 MPLIST_DO (pl, config->cmds)
5646 elt = MPLIST_PLIST (pl);
5647 command = MPLIST_SYMBOL (elt);
5649 p = mplist__assq (custom->cmds, command);
5651 custom->cmds = mplist (), p = NULL;
5652 elt = MPLIST_NEXT (elt);
5655 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5656 mplist_set (p, Mnil, NULL);
5661 mplist_add (custom->cmds, Mplist, p);
5662 M17N_OBJECT_UNREF (p);
5663 mplist_add (p, Msymbol, command);
5664 p = mplist_add (p, Msymbol, Mnil);
5665 p = MPLIST_NEXT (p);
5667 mplist__conc (p, elt);
5670 MPLIST_DO (pl, config->vars)
5672 elt = MPLIST_PLIST (pl);
5673 variable = MPLIST_SYMBOL (elt);
5675 p = mplist__assq (custom->vars, variable);
5677 custom->vars = mplist (), p = NULL;
5678 elt = MPLIST_NEXT (elt);
5681 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5682 mplist_set (p, Mnil, NULL);
5687 mplist_add (custom->vars, Mplist, p);
5688 M17N_OBJECT_UNREF (p);
5689 mplist_add (p, Msymbol, variable);
5690 p = mplist_add (p, Msymbol, Mnil);
5691 p = MPLIST_NEXT (p);
5693 mplist__conc (p, elt);
5696 free_im_list (im_config_list);
5697 im_config_list = NULL;
5699 /* Next, reflect customization to the actual plist to be written. */
5700 data = tail = mplist ();
5701 MPLIST_DO (plist, im_custom_list)
5703 MPlist *pl = MPLIST_PLIST (plist);
5704 MSymbol language, name, extra;
5705 MInputMethodInfo *custom, *im_info;
5707 language = MPLIST_SYMBOL (pl);
5708 pl = MPLIST_NEXT (pl);
5709 name = MPLIST_SYMBOL (pl);
5710 pl = MPLIST_NEXT (pl);
5711 extra = MPLIST_SYMBOL (pl);
5712 pl = MPLIST_NEXT (pl);
5713 custom = MPLIST_VAL (pl);
5714 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5715 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5717 im_info = lookup_im_info (im_info_list, language, name, extra);
5721 config_all_commands (im_info);
5723 config_all_variables (im_info);
5727 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5729 MPLIST_DO (p, custom->cmds)
5730 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5732 if (! MPLIST_TAIL_P (p))
5736 mplist_add (elt, Mplist, pl);
5737 M17N_OBJECT_UNREF (pl);
5738 pl = mplist_add (pl, Msymbol, Mcommand);
5739 MPLIST_DO (p, custom->cmds)
5740 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5741 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5744 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5746 MPLIST_DO (p, custom->vars)
5747 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5749 if (! MPLIST_TAIL_P (p))
5754 mplist_add (elt, Mplist, pl);
5755 M17N_OBJECT_UNREF (pl);
5756 pl = mplist_add (pl, Msymbol, Mvariable);
5757 MPLIST_DO (p, custom->vars)
5758 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5759 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5765 mplist_push (elt, Mplist, pl);
5766 M17N_OBJECT_UNREF (pl);
5767 pl = mplist_add (pl, Msymbol, Minput_method);
5768 pl = mplist_add (pl, Msymbol, language);
5769 pl = mplist_add (pl, Msymbol, name);
5771 pl = mplist_add (pl, Msymbol, extra);
5772 tail = mplist_add (tail, Mplist, elt);
5773 M17N_OBJECT_UNREF (elt);
5777 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5778 ret = mdatabase__save (im_custom_mdb, data);
5779 mdatabase__unlock (im_custom_mdb);
5780 M17N_OBJECT_UNREF (data);
5781 return (ret < 0 ? -1 : 1);
5788 @name Obsolete functions
5791 @name Obsolete ¤Ê´Ø¿ô
5797 @brief Get a list of variables of an input method (obsolete).
5799 This function is obsolete. Use minput_get_variable () instead.
5801 The minput_get_variables () function returns a plist (#MPlist) of
5802 variables used to control the behavior of the input method
5803 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5804 (#m17nPlist) of the following format:
5807 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5808 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5812 @c VARNAME is a symbol representing the variable name.
5814 @c DOC-MTEXT is an M-text describing the variable.
5816 @c DEFAULT-VALUE is the default value of the variable. It is a
5817 symbol, integer, or M-text.
5819 @c VALUEs (if any) specifies the possible values of the variable.
5820 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5821 @c TO), where @c FROM and @c TO specifies a range of possible
5824 For instance, suppose an input method has the variables:
5826 @li name:intvar, description:"value is an integer",
5827 initial value:0, value-range:0..3,10,20
5829 @li name:symvar, description:"value is a symbol",
5830 initial value:nil, value-range:a, b, c, nil
5832 @li name:txtvar, description:"value is an M-text",
5833 initial value:empty text, no value-range (i.e. any text)
5835 Then, the returned plist is as follows.
5838 (intvar ("value is an integer" 0 (0 3) 10 20)
5839 symvar ("value is a symbol" nil a b c nil)
5840 txtvar ("value is an M-text" ""))
5844 If the input method uses any variables, a pointer to #MPlist is
5845 returned. As the plist is kept in the library, the caller must not
5846 modify nor free it. If the input method does not use any
5847 variable, @c NULL is returned. */
5849 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5851 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5852 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5853 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5857 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5858 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5862 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5864 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5866 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5869 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5870 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5871 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5873 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5875 @li name:intvar, ÀâÌÀ:"value is an integer",
5876 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5878 @li name:symvar, ÀâÌÀ:"value is a symbol",
5879 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5881 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5882 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5884 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5887 (intvar ("value is an integer" 0 (0 3) 10 20)
5888 symvar ("value is a symbol" nil a b c nil)
5889 txtvar ("value is an M-text" ""))
5893 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5894 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5895 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5898 minput_get_variables (MSymbol language, MSymbol name)
5900 MInputMethodInfo *im_info;
5905 im_info = get_im_info (language, name, Mnil, Mvariable);
5906 if (! im_info || ! im_info->configured_vars)
5909 M17N_OBJECT_UNREF (im_info->bc_vars);
5910 im_info->bc_vars = mplist ();
5911 MPLIST_DO (vars, im_info->configured_vars)
5913 MPlist *plist = MPLIST_PLIST (vars);
5914 MPlist *elt = mplist ();
5916 mplist_push (im_info->bc_vars, Mplist, elt);
5917 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5918 elt = MPLIST_NEXT (elt);
5919 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5920 M17N_OBJECT_UNREF (elt);
5922 return im_info->bc_vars;
5928 @brief Set the initial value of an input method variable.
5930 The minput_set_variable () function sets the initial value of
5931 input method variable $VARIABLE to $VALUE for the input method
5932 specified by $LANGUAGE and $NAME.
5934 By default, the initial value is 0.
5936 This setting gets effective in a newly opened input method.
5939 If the operation was successful, 0 is returned. Otherwise -1 is
5940 returned, and #merror_code is set to #MERROR_IM. */
5942 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5944 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5945 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5946 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5948 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5950 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5953 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5954 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5957 minput_set_variable (MSymbol language, MSymbol name,
5958 MSymbol variable, void *value)
5961 MInputMethodInfo *im_info;
5966 if (variable == Mnil)
5967 MERROR (MERROR_IM, -1);
5968 plist = minput_get_variable (language, name, variable);
5969 plist = MPLIST_PLIST (plist);
5970 plist = MPLIST_NEXT (plist);
5972 mplist_add (pl, MPLIST_KEY (plist), value);
5973 ret = minput_config_variable (language, name, variable, pl);
5974 M17N_OBJECT_UNREF (pl);
5977 im_info = get_im_info (language, name, Mnil, Mvariable);
5986 @brief Get information about input method commands.
5988 The minput_get_commands () function returns information about
5989 input method commands of the input method specified by $LANGUAGE
5990 and $NAME. An input method command is a pseudo key event to which
5991 one or more actual input key sequences are assigned.
5993 There are two kinds of commands, global and local. Global
5994 commands are used by multiple input methods for the same purpose,
5995 and have global key assignments. Local commands are used only by
5996 a specific input method, and have only local key assignments.
5998 Each input method may locally change key assignments for global
5999 commands. The global key assignment for a global command is
6000 effective only when the current input method does not have local
6001 key assignments for that command.
6003 If $NAME is #Mnil, information about global commands is returned.
6004 In this case $LANGUAGE is ignored.
6006 If $NAME is not #Mnil, information about those commands that have
6007 local key assignments in the input method specified by $LANGUAGE
6008 and $NAME is returned.
6011 If no input method commands are found, this function returns @c NULL.
6013 Otherwise, a pointer to a plist is returned. The key of each
6014 element in the plist is a symbol representing a command, and the
6015 value is a plist of the form COMMAND-INFO described below.
6017 The first element of COMMAND-INFO has the key #Mtext, and the
6018 value is an M-text describing the command.
6020 If there are no more elements, that means no key sequences are
6021 assigned to the command. Otherwise, each of the remaining
6022 elements has the key #Mplist, and the value is a plist whose keys are
6023 #Msymbol and values are symbols representing input keys, which are
6024 currently assigned to the command.
6026 As the returned plist is kept in the library, the caller must not
6027 modify nor free it. */
6029 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6031 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6032 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6033 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6034 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6036 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6037 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6038 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6039 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6041 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6042 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6043 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6046 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6047 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6049 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6050 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6054 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6056 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6057 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6058 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6060 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6061 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6062 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6065 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6066 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6067 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6068 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6069 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6071 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6072 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6075 minput_get_commands (MSymbol language, MSymbol name)
6077 MInputMethodInfo *im_info;
6082 im_info = get_im_info (language, name, Mnil, Mcommand);
6083 if (! im_info || ! im_info->configured_vars)
6085 M17N_OBJECT_UNREF (im_info->bc_cmds);
6086 im_info->bc_cmds = mplist ();
6087 MPLIST_DO (cmds, im_info->configured_cmds)
6089 MPlist *plist = MPLIST_PLIST (cmds);
6090 MPlist *elt = mplist ();
6092 mplist_push (im_info->bc_cmds, Mplist, elt);
6093 mplist_add (elt, MPLIST_SYMBOL (plist),
6094 mplist_copy (MPLIST_NEXT (plist)));
6095 M17N_OBJECT_UNREF (elt);
6097 return im_info->bc_cmds;
6103 @brief Assign a key sequence to an input method command (obsolete).
6105 This function is obsolete. Use minput_config_command () instead.
6107 The minput_assign_command_keys () function assigns input key
6108 sequence $KEYSEQ to input method command $COMMAND for the input
6109 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6110 key sequence is assigned globally no matter what $LANGUAGE is.
6111 Otherwise the key sequence is assigned locally.
6113 Each element of $KEYSEQ must have the key $Msymbol and the value
6114 must be a symbol representing an input key.
6116 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6117 globally or locally.
6119 This assignment gets effective in a newly opened input method.
6122 If the operation was successful, 0 is returned. Otherwise -1 is
6123 returned, and #merror_code is set to #MERROR_IM. */
6125 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6127 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6128 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6129 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6130 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6131 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6133 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6134 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6136 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6137 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6139 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6142 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6143 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6146 minput_assign_command_keys (MSymbol language, MSymbol name,
6147 MSymbol command, MPlist *keyseq)
6153 if (command == Mnil)
6154 MERROR (MERROR_IM, -1);
6159 if (! check_command_keyseq (keyseq))
6160 MERROR (MERROR_IM, -1);
6162 mplist_add (plist, Mplist, keyseq);
6167 ret = minput_config_command (language, name, command, keyseq);
6168 M17N_OBJECT_UNREF (keyseq);
6175 @brief Call a callback function
6177 The minput_callback () functions calls a callback function
6178 $COMMAND assigned for the input context $IC. The caller must set
6179 specific elements in $IC->plist if the callback function requires.
6182 If there exists a specified callback function, 0 is returned.
6183 Otherwise -1 is returned. By side effects, $IC->plist may be
6187 minput_callback (MInputContext *ic, MSymbol command)
6189 MInputCallbackFunc func;
6191 if (! ic->im->driver.callback_list)
6193 func = ((MInputCallbackFunc)
6194 mplist_get_func (ic->im->driver.callback_list, command));
6197 (func) (ic, command);
6204 /*** @addtogroup m17nDebug */
6210 @brief Dump an input method.
6212 The mdebug_dump_im () function prints the input method $IM in a
6213 human readable way to the stderr. $INDENT specifies how many
6214 columns to indent the lines but the first one.
6217 This function returns $IM. */
6219 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6221 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6222 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6225 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6228 mdebug_dump_im (MInputMethod *im, int indent)
6230 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6233 prefix = (char *) alloca (indent + 1);
6234 memset (prefix, 32, indent);
6235 prefix[indent] = '\0';
6237 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6238 msymbol_name (im->name));
6239 mdebug_dump_mtext (im_info->title, 0, 0);
6240 if (im->name != Mnil)
6244 MPLIST_DO (state, im_info->states)
6246 fprintf (stderr, "\n%s ", prefix);
6247 dump_im_state (MPLIST_VAL (state), indent + 2);
6250 fprintf (stderr, ")");