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);
1076 if (! plist && im_info->configured_vars)
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);
1498 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1500 if (! global_info->mdb
1501 || ! (plist = mdatabase_load (global_info->mdb)))
1504 load_im_info (plist, global_info);
1505 M17N_OBJECT_UNREF (plist);
1510 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1511 and EXTRA. KEY, if not Mnil, tells which kind of information about
1512 the input method is necessary, and the returned IM_INFO may contain
1513 only that information. */
1515 static MInputMethodInfo *
1516 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1519 MInputMethodInfo *im_info;
1522 if (name == Mnil && extra == Mnil)
1523 language = Mt, extra = Mglobal;
1524 im_info = lookup_im_info (im_info_list, language, name, extra);
1527 if (key == Mnil ? im_info->states != NULL
1528 : key == Mcommand ? im_info->cmds != NULL
1529 : key == Mvariable ? im_info->vars != NULL
1530 : key == Mtitle ? im_info->title != NULL
1531 : key == Mdescription ? im_info->description != NULL
1533 /* IM_INFO already contains required information. */
1535 /* We have not yet loaded required information. */
1539 mdb = mdatabase_find (Minput_method, language, name, extra);
1542 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1547 plist = mdatabase_load (im_info->mdb);
1551 mplist_push (load_im_info_keys, key, Mt);
1552 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1553 mplist_pop (load_im_info_keys);
1557 MERROR (MERROR_IM, im_info);
1558 update_global_info ();
1559 load_im_info (plist, im_info);
1560 M17N_OBJECT_UNREF (plist);
1563 if (! im_info->cmds)
1564 im_info->cmds = mplist ();
1565 if (! im_info->vars)
1566 im_info->vars = mplist ();
1568 if (! im_info->title
1569 && (key == Mnil || key == Mtitle))
1570 im_info->title = (name == Mnil ? mtext ()
1571 : mtext_from_data (MSYMBOL_NAME (name),
1572 MSYMBOL_NAMELEN (name),
1573 MTEXT_FORMAT_US_ASCII));
1577 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1578 If updated, but got unloadable, return -1. Otherwise, update
1579 contents of IM_INFO from the new database, and return 1. */
1582 reload_im_info (MInputMethodInfo *im_info)
1587 update_custom_info ();
1588 update_global_info ();
1589 check = mdatabase__check (im_info->mdb);
1592 plist = mdatabase_load (im_info->mdb);
1595 fini_im_info (im_info);
1596 load_im_info (plist, im_info);
1597 M17N_OBJECT_UNREF (plist);
1598 if (! im_info->cmds)
1599 im_info->cmds = mplist ();
1600 if (! im_info->vars)
1601 im_info->vars = mplist ();
1602 if (! im_info->title)
1604 MSymbol name = im_info->name;
1606 im_info->title = (name == Mnil ? mtext ()
1607 : mtext_from_data (MSYMBOL_NAME (name),
1608 MSYMBOL_NAMELEN (name),
1609 MTEXT_FORMAT_US_ASCII));
1614 static MInputMethodInfo *
1615 get_im_info_by_tags (MPlist *plist)
1620 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1621 i++, plist = MPLIST_NEXT (plist))
1622 tag[i] = MPLIST_SYMBOL (plist);
1627 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1632 check_description (MPlist *plist)
1636 if (MPLIST_MTEXT_P (plist))
1638 if (MPLIST_PLIST_P (plist))
1640 MPlist *pl = MPLIST_PLIST (plist);
1642 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1644 pl =MPLIST_NEXT (pl);
1645 if (MFAILP (MPLIST_MTEXT_P (pl)))
1647 mt = MPLIST_MTEXT (pl);
1648 M17N_OBJECT_REF (mt);
1651 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1653 if (translated == (char *) MTEXT_DATA (mt))
1654 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1655 if (translated != (char *) MTEXT_DATA (mt))
1657 M17N_OBJECT_UNREF (mt);
1658 mt = mtext__from_data (translated, strlen (translated),
1659 MTEXT_FORMAT_UTF_8, 1);
1663 mplist_set (plist, Mtext, mt);
1664 M17N_OBJECT_UNREF (mt);
1667 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1673 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1677 check_command_keyseq (MPlist *keyseq)
1679 if (MPLIST_PLIST_P (keyseq))
1681 MPlist *p = MPLIST_PLIST (keyseq);
1684 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1688 if (MPLIST_MTEXT_P (keyseq))
1690 MText *mt = MPLIST_MTEXT (keyseq);
1693 for (i = 0; i < mtext_nchars (mt); i++)
1694 if (mtext_ref_char (mt, i) >= 256)
1701 /* Load command defitions from PLIST into IM_INFO->cmds.
1703 PLIST is well-formed and has this form;
1704 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1705 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1706 M-text or a plist of symbols.
1708 The returned list has the same form, but for each element...
1710 (1) If DESCRIPTION and the rest are omitted, the element is not
1711 stored in the returned list.
1713 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1714 description in global_info->cmds (if any). */
1717 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1721 im_info->cmds = tail = mplist ();
1723 MPLIST_DO (plist, MPLIST_NEXT (plist))
1725 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1728 if (MFAILP (MPLIST_PLIST_P (plist)))
1730 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1731 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1733 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1734 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1736 if (MFAILP (im_info != global_info))
1737 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1741 if (! check_description (p))
1742 mplist_set (p, Msymbol, Mnil);
1743 p = MPLIST_NEXT (p);
1744 while (! MPLIST_TAIL_P (p))
1746 if (MFAILP (check_command_keyseq (p)))
1747 mplist__pop_unref (p);
1749 p = MPLIST_NEXT (p);
1752 tail = mplist_add (tail, Mplist, pl);
1757 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1758 MPlist *config_cmds)
1760 MPlist *global = NULL, *custom = NULL, *config = NULL;
1761 MSymbol name = MPLIST_SYMBOL (plist);
1763 MPlist *description, *keyseq;
1765 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1766 global = MPLIST_NEXT (MPLIST_PLIST (global));
1768 plist = MPLIST_NEXT (plist);
1769 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1771 description = plist;
1772 plist = MPLIST_NEXT (plist);
1776 description = global;
1777 if (! MPLIST_TAIL_P (plist))
1778 plist = MPLIST_NEXT (plist);
1780 if (MPLIST_TAIL_P (plist) && global)
1782 keyseq = MPLIST_NEXT (global);
1783 status = Minherited;
1791 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1793 status = Mconfigured;
1794 config = MPLIST_NEXT (MPLIST_PLIST (config));
1795 if (! MPLIST_TAIL_P (config))
1798 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1800 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1802 if (MPLIST_TAIL_P (this_keyseq))
1803 mplist__pop_unref (custom);
1806 status = Mcustomized;
1807 keyseq = this_keyseq;
1812 mplist_add (plist, Msymbol, name);
1814 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1816 mplist_add (plist, Msymbol, Mnil);
1817 mplist_add (plist, Msymbol, status);
1818 mplist__conc (plist, keyseq);
1823 config_all_commands (MInputMethodInfo *im_info)
1825 MPlist *global_cmds, *custom_cmds, *config_cmds;
1826 MInputMethodInfo *temp;
1827 MPlist *tail, *plist;
1829 M17N_OBJECT_UNREF (im_info->configured_cmds);
1831 if (MPLIST_TAIL_P (im_info->cmds)
1835 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1836 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1837 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1839 im_info->configured_cmds = tail = mplist ();
1840 MPLIST_DO (plist, im_info->cmds)
1842 MPlist *pl = config_command (MPLIST_PLIST (plist),
1843 global_cmds, custom_cmds, config_cmds);
1846 tail = mplist_add (tail, Mplist, pl);
1847 M17N_OBJECT_UNREF (pl);
1852 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1853 valid, return 0 if not. */
1856 check_variable_value (MPlist *val, MPlist *global)
1858 MSymbol type = MPLIST_KEY (val);
1859 MPlist *valids = MPLIST_NEXT (val);
1861 if (type != Minteger && type != Mtext && type != Msymbol)
1865 if (MPLIST_KEY (global) != Mt
1866 && MPLIST_KEY (global) != MPLIST_KEY (val))
1868 if (MPLIST_TAIL_P (valids))
1869 valids = MPLIST_NEXT (global);
1871 if (MPLIST_TAIL_P (valids))
1874 if (type == Minteger)
1876 int n = MPLIST_INTEGER (val);
1878 MPLIST_DO (valids, valids)
1880 if (MPLIST_INTEGER_P (valids))
1882 if (n == MPLIST_INTEGER (valids))
1885 else if (MPLIST_PLIST_P (valids))
1887 MPlist *p = MPLIST_PLIST (valids);
1888 int min_bound, max_bound;
1890 if (! MPLIST_INTEGER_P (p))
1891 MERROR (MERROR_IM, 0);
1892 min_bound = MPLIST_INTEGER (p);
1893 p = MPLIST_NEXT (p);
1894 if (! MPLIST_INTEGER_P (p))
1895 MERROR (MERROR_IM, 0);
1896 max_bound = MPLIST_INTEGER (p);
1897 if (n >= min_bound && n <= max_bound)
1902 else if (type == Msymbol)
1904 MSymbol sym = MPLIST_SYMBOL (val);
1906 MPLIST_DO (valids, valids)
1908 if (! MPLIST_SYMBOL_P (valids))
1909 MERROR (MERROR_IM, 0);
1910 if (sym == MPLIST_SYMBOL (valids))
1916 MText *mt = MPLIST_MTEXT (val);
1918 MPLIST_DO (valids, valids)
1920 if (! MPLIST_MTEXT_P (valids))
1921 MERROR (MERROR_IM, 0);
1922 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1927 return (! MPLIST_TAIL_P (valids));
1930 /* Load variable defitions from PLIST into IM_INFO->vars.
1932 PLIST is well-formed and has this form;
1933 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1935 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1937 The returned list has the same form, but for each element...
1939 (1) If DESCRIPTION and the rest are omitted, the element is not
1940 stored in the returned list.
1942 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1943 description in global_info->vars (if any). */
1946 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1948 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1949 ? global_info->vars : NULL);
1952 im_info->vars = tail = mplist ();
1953 MPLIST_DO (plist, MPLIST_NEXT (plist))
1957 if (MFAILP (MPLIST_PLIST_P (plist)))
1959 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1960 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1962 if (im_info == global_info)
1964 /* Loading a global variable. */
1965 p = MPLIST_NEXT (pl);
1966 if (MPLIST_TAIL_P (p))
1967 mplist_add (p, Msymbol, Mnil);
1970 if (! check_description (p))
1971 mplist_set (p, Msymbol, Mnil);
1972 p = MPLIST_NEXT (p);
1973 if (MFAILP (! MPLIST_TAIL_P (p)
1974 && check_variable_value (p, NULL)))
1975 mplist_set (p, Mt, NULL);
1978 else if (im_info->mdb)
1980 /* Loading a local variable. */
1981 MSymbol name = MPLIST_SYMBOL (pl);
1982 MPlist *global = NULL;
1985 && (p = mplist__assq (global_vars, name)))
1987 /* P ::= ((NAME DESC ...) ...) */
1988 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1989 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1990 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1993 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1994 if (! MPLIST_TAIL_P (p))
1996 if (! check_description (p))
1997 mplist_set (p, Msymbol, Mnil);
1998 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1999 if (MFAILP (! MPLIST_TAIL_P (p)))
2000 mplist_set (p, Mt, NULL);
2003 MPlist *valid_values = MPLIST_NEXT (p);
2005 if (! MPLIST_TAIL_P (valid_values)
2006 ? MFAILP (check_variable_value (p, NULL))
2007 : global && MFAILP (check_variable_value (p, global)))
2008 mplist_set (p, Mt, NULL);
2014 /* Loading a variable customization. */
2015 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2016 if (MFAILP (! MPLIST_TAIL_P (p)))
2018 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2019 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2020 || MPLIST_MTEXT_P (p)))
2023 tail = mplist_add (tail, Mplist, pl);
2028 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2029 MPlist *config_vars)
2031 MPlist *global = NULL, *custom = NULL, *config = NULL;
2032 MSymbol name = MPLIST_SYMBOL (plist);
2034 MPlist *description = NULL, *value, *valids;
2038 global = mplist__assq (global_vars, name);
2040 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2043 plist = MPLIST_NEXT (plist);
2044 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2045 description = plist;
2047 description = global;
2049 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2051 if (MPLIST_TAIL_P (plist))
2053 /* Inherit from global (if any). */
2057 if (MPLIST_KEY (value) == Mt)
2059 valids = MPLIST_NEXT (global);
2060 status = Minherited;
2072 value = plist = MPLIST_NEXT (plist);
2073 valids = MPLIST_NEXT (value);
2074 if (MPLIST_KEY (value) == Mt)
2076 if (! MPLIST_TAIL_P (valids))
2079 valids = MPLIST_NEXT (global);
2083 if (config_vars && (config = mplist__assq (config_vars, name)))
2085 status = Mconfigured;
2086 config = MPLIST_NEXT (MPLIST_PLIST (config));
2087 if (! MPLIST_TAIL_P (config))
2090 if (MFAILP (check_variable_value (value, global ? global : plist)))
2094 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2096 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2098 if (MPLIST_TAIL_P (this_value))
2099 mplist__pop_unref (custom);
2103 if (MFAILP (check_variable_value (value, global ? global : plist)))
2105 status = Mcustomized;
2110 mplist_add (plist, Msymbol, name);
2112 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2114 mplist_add (plist, Msymbol, Mnil);
2115 mplist_add (plist, Msymbol, status);
2117 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2119 mplist_add (plist, Mt, NULL);
2120 if (valids && ! MPLIST_TAIL_P (valids))
2121 mplist__conc (plist, valids);
2125 /* Return a configured variable definition list based on
2126 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2127 get it from global_info->vars. */
2130 config_all_variables (MInputMethodInfo *im_info)
2132 MPlist *global_vars, *custom_vars, *config_vars;
2133 MInputMethodInfo *temp;
2134 MPlist *tail, *plist;
2136 M17N_OBJECT_UNREF (im_info->configured_vars);
2138 if (MPLIST_TAIL_P (im_info->vars)
2142 global_vars = im_info != global_info ? global_info->vars : NULL;
2143 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2144 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2146 im_info->configured_vars = tail = mplist ();
2147 MPLIST_DO (plist, im_info->vars)
2149 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2150 global_vars, custom_vars, config_vars);
2153 tail = mplist_add (tail, Mplist, pl);
2154 M17N_OBJECT_UNREF (pl);
2159 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2160 CONFIG contains configuration information of the input method. */
2163 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2167 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2169 load_commands (im_info, MPLIST_PLIST (pl));
2170 config_all_commands (im_info);
2171 pl = mplist_pop (pl);
2172 M17N_OBJECT_UNREF (pl);
2175 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2177 load_variables (im_info, MPLIST_PLIST (pl));
2178 config_all_variables (im_info);
2179 pl = mplist_pop (pl);
2180 M17N_OBJECT_UNREF (pl);
2183 MPLIST_DO (plist, plist)
2184 if (MPLIST_PLIST_P (plist))
2186 MPlist *elt = MPLIST_PLIST (plist);
2189 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2191 key = MPLIST_SYMBOL (elt);
2196 elt = MPLIST_NEXT (elt);
2197 if (MFAILP (MPLIST_MTEXT_P (elt)))
2199 im_info->title = MPLIST_MTEXT (elt);
2200 M17N_OBJECT_REF (im_info->title);
2202 else if (key == Mmap)
2204 pl = mplist__from_alist (MPLIST_NEXT (elt));
2207 if (! im_info->maps)
2211 mplist__conc (im_info->maps, pl);
2212 M17N_OBJECT_UNREF (pl);
2215 else if (key == Mmacro)
2217 if (! im_info->macros)
2218 im_info->macros = mplist ();
2219 MPLIST_DO (elt, MPLIST_NEXT (elt))
2221 if (MFAILP (MPLIST_PLIST_P (elt)))
2223 load_macros (im_info, MPLIST_PLIST (elt));
2226 else if (key == Mmodule)
2228 if (! im_info->externals)
2229 im_info->externals = mplist ();
2230 MPLIST_DO (elt, MPLIST_NEXT (elt))
2232 if (MFAILP (MPLIST_PLIST_P (elt)))
2234 load_external_module (im_info, MPLIST_PLIST (elt));
2237 else if (key == Mstate)
2239 MPLIST_DO (elt, MPLIST_NEXT (elt))
2243 if (MFAILP (MPLIST_PLIST_P (elt)))
2245 pl = MPLIST_PLIST (elt);
2246 if (! im_info->states)
2247 im_info->states = mplist ();
2248 state = load_state (im_info, MPLIST_PLIST (elt));
2251 mplist_put (im_info->states, state->name, state);
2254 else if (key == Minclude)
2256 /* elt ::= include (tag1 tag2 ...) key item ... */
2258 MInputMethodInfo *temp;
2260 elt = MPLIST_NEXT (elt);
2261 if (MFAILP (MPLIST_PLIST_P (elt)))
2263 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2266 elt = MPLIST_NEXT (elt);
2267 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2269 key = MPLIST_SYMBOL (elt);
2270 elt = MPLIST_NEXT (elt);
2273 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2275 if (! im_info->maps)
2276 im_info->maps = mplist ();
2277 MPLIST_DO (pl, temp->maps)
2279 p = MPLIST_VAL (pl);
2280 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2281 M17N_OBJECT_REF (p);
2284 else if (key == Mmacro)
2286 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2288 if (! im_info->macros)
2289 im_info->macros = mplist ();
2290 MPLIST_DO (pl, temp->macros)
2292 p = MPLIST_VAL (pl);
2293 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2294 M17N_OBJECT_REF (p);
2297 else if (key == Mstate)
2299 if (! temp->states || MPLIST_TAIL_P (temp->states))
2301 if (! im_info->states)
2302 im_info->states = mplist ();
2303 MPLIST_DO (pl, temp->states)
2305 MIMState *state = MPLIST_VAL (pl);
2307 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2308 M17N_OBJECT_REF (state);
2312 else if (key == Mdescription)
2314 if (im_info->description)
2316 elt = MPLIST_NEXT (elt);
2317 if (! check_description (elt))
2319 im_info->description = MPLIST_MTEXT (elt);
2320 M17N_OBJECT_REF (im_info->description);
2323 im_info->tick = time (NULL);
2328 static int take_action_list (MInputContext *ic, MPlist *action_list);
2329 static void preedit_commit (MInputContext *ic);
2332 shift_state (MInputContext *ic, MSymbol state_name)
2334 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2335 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2336 MIMState *orig_state = ic_info->state, *state;
2338 /* Find a state to shift to. If not found, shift to the initial
2340 if (state_name == Mt)
2342 if (! ic_info->prev_state)
2344 state = ic_info->prev_state;
2346 else if (state_name == Mnil)
2348 state = (MIMState *) MPLIST_VAL (im_info->states);
2352 state = (MIMState *) mplist_get (im_info->states, state_name);
2354 state = (MIMState *) MPLIST_VAL (im_info->states);
2357 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2359 /* Enter the new state. */
2360 ic_info->state = state;
2361 ic_info->map = state->map;
2362 ic_info->state_key_head = ic_info->key_head;
2363 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2365 /* We have shifted to the initial state. */
2366 preedit_commit (ic);
2367 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2368 ic_info->state_pos = ic->cursor_pos;
2369 if (state != orig_state)
2371 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2373 /* Shifted to the initial state. */
2374 ic_info->prev_state = NULL;
2375 M17N_OBJECT_UNREF (ic_info->vars_saved);
2376 ic_info->vars_saved = mplist_copy (ic_info->vars);
2379 ic_info->prev_state = orig_state;
2382 ic->status = state->title;
2384 ic->status = im_info->title;
2385 ic->status_changed = 1;
2386 if (ic_info->map == ic_info->state->map
2387 && ic_info->map->map_actions)
2389 MDEBUG_PRINT (" init-actions:");
2390 take_action_list (ic, ic_info->map->map_actions);
2395 /* Find a candidate group that contains a candidate number INDEX from
2396 PLIST. Set START_INDEX to the first candidate number of the group,
2397 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2398 candidate group number if they are non-NULL. If INDEX is -1, find
2399 the last candidate group. */
2402 find_candidates_group (MPlist *plist, int index,
2403 int *start_index, int *end_index, int *group_index)
2405 int i = 0, gidx = 0, len;
2407 MPLIST_DO (plist, plist)
2409 if (MPLIST_MTEXT_P (plist))
2410 len = mtext_nchars (MPLIST_MTEXT (plist));
2412 len = mplist_length (MPLIST_PLIST (plist));
2413 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2419 *end_index = i + len;
2421 *group_index = gidx;
2430 /* Adjust markers for the change of preedit text.
2431 If FROM == TO, the change is insertion of INS chars.
2432 If FROM < TO and INS == 0, the change is deletion of the range.
2433 If FROM < TO and INS > 0, the change is replacement. */
2436 adjust_markers (MInputContext *ic, int from, int to, int ins)
2438 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2443 MPLIST_DO (markers, ic_info->markers)
2444 if (MPLIST_INTEGER (markers) > from)
2445 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2446 if (ic->cursor_pos >= from)
2447 ic->cursor_pos += ins;
2451 MPLIST_DO (markers, ic_info->markers)
2453 if (MPLIST_INTEGER (markers) >= to)
2454 MPLIST_VAL (markers)
2455 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2456 else if (MPLIST_INTEGER (markers) > from)
2457 MPLIST_VAL (markers) = (void *) from;
2459 if (ic->cursor_pos >= to)
2460 ic->cursor_pos += ins - (to - from);
2461 else if (ic->cursor_pos > from)
2462 ic->cursor_pos = from;
2468 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2470 int nchars = mt ? mtext_nchars (mt) : 1;
2473 mtext_ins (ic->preedit, pos, mt);
2475 mtext_ins_char (ic->preedit, pos, c, 1);
2476 adjust_markers (ic, pos, pos, nchars);
2477 ic->preedit_changed = 1;
2482 preedit_delete (MInputContext *ic, int from, int to)
2484 mtext_del (ic->preedit, from, to);
2485 adjust_markers (ic, from, to, 0);
2486 ic->preedit_changed = 1;
2490 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2494 mtext_del (ic->preedit, from, to);
2497 mtext_ins (ic->preedit, from, mt);
2498 ins = mtext_nchars (mt);
2502 mtext_ins_char (ic->preedit, from, c, 1);
2505 adjust_markers (ic, from, to, ins);
2506 ic->preedit_changed = 1;
2511 preedit_commit (MInputContext *ic)
2513 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2514 int preedit_len = mtext_nchars (ic->preedit);
2516 if (preedit_len > 0)
2520 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2521 Mcandidate_list, NULL, 0);
2522 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2523 Mcandidate_index, NULL, 0);
2524 mtext_cat (ic->produced, ic->preedit);
2525 if (mdebug__flag & mdebug_mask)
2529 MDEBUG_PRINT (" (commit");
2530 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2531 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2535 mtext_reset (ic->preedit);
2536 mtext_reset (ic_info->preedit_saved);
2537 MPLIST_DO (p, ic_info->markers)
2539 ic->cursor_pos = ic_info->state_pos = 0;
2540 ic->preedit_changed = 1;
2541 ic_info->commit_key_head = ic_info->key_head;
2543 if (ic->candidate_list)
2545 M17N_OBJECT_UNREF (ic->candidate_list);
2546 ic->candidate_list = NULL;
2547 ic->candidate_index = 0;
2548 ic->candidate_from = ic->candidate_to = 0;
2549 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2550 if (ic->candidate_show)
2552 ic->candidate_show = 0;
2553 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2559 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2561 int code = marker_code (sym, 0);
2563 if (mt && (code == '[' || code == ']'))
2567 if (code == '[' && current > 0)
2569 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2573 else if (code == ']' && current < mtext_nchars (mt))
2575 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2581 return (code == '<' ? 0
2582 : code == '>' ? limit
2583 : code == '-' ? current - 1
2584 : code == '+' ? current + 1
2585 : code == '=' ? current
2586 : code - '0' > limit ? limit
2590 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2594 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2596 int from = mtext_property_start (prop);
2597 int to = mtext_property_end (prop);
2599 MPlist *candidate_list = mtext_property_value (prop);
2600 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2602 int ingroup_index = idx - start;
2605 if (MPLIST_MTEXT_P (group))
2607 mt = MPLIST_MTEXT (group);
2608 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2616 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2617 i++, plist = MPLIST_NEXT (plist));
2618 mt = MPLIST_MTEXT (plist);
2619 preedit_replace (ic, from, to, mt, 0);
2620 to = from + mtext_nchars (mt);
2622 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2623 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2624 ic->cursor_pos = to;
2628 get_select_charset (MInputContextInfo * ic_info)
2630 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2633 if (! MPLIST_VAL (plist))
2635 sym = MPLIST_SYMBOL (plist);
2638 return MCHARSET (sym);
2642 adjust_candidates (MPlist *plist, MCharset *charset)
2646 /* plist ::= MTEXT ... | PLIST ... */
2647 plist = mplist_copy (plist);
2648 if (MPLIST_MTEXT_P (plist))
2651 while (! MPLIST_TAIL_P (pl))
2653 /* pl ::= MTEXT ... */
2654 MText *mt = MPLIST_MTEXT (pl);
2658 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2660 c = mtext_ref_char (mt, i);
2661 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2665 mt = mtext_dup (mt);
2666 mplist_set (pl, Mtext, mt);
2667 M17N_OBJECT_UNREF (mt);
2670 mtext_del (mt, i, i + 1);
2673 if (mtext_len (mt) > 0)
2674 pl = MPLIST_NEXT (pl);
2678 M17N_OBJECT_UNREF (mt);
2682 else /* MPLIST_PLIST_P (plist) */
2685 while (! MPLIST_TAIL_P (pl))
2687 /* pl ::= (MTEXT ...) ... */
2688 MPlist *p = MPLIST_PLIST (pl);
2690 /* p ::= MTEXT ... */
2694 while (! MPLIST_TAIL_P (p0))
2696 MText *mt = MPLIST_MTEXT (p0);
2699 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2701 c = mtext_ref_char (mt, i);
2702 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2707 p0 = MPLIST_NEXT (p0);
2714 p = mplist_copy (p);
2715 mplist_set (pl, Mplist, p);
2716 M17N_OBJECT_UNREF (p);
2720 p0 = MPLIST_NEXT (p0);
2723 M17N_OBJECT_UNREF (mt);
2726 if (! MPLIST_TAIL_P (p))
2727 pl = MPLIST_NEXT (pl);
2731 M17N_OBJECT_UNREF (p);
2735 if (MPLIST_TAIL_P (plist))
2737 M17N_OBJECT_UNREF (plist);
2744 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2746 MCharset *charset = get_select_charset (ic_info);
2751 plist = resolve_variable (ic_info, Mcandidates_group_size);
2752 column = MPLIST_INTEGER (plist);
2754 plist = MPLIST_PLIST (args);
2756 plist = adjust_candidates (plist, charset);
2758 if (plist && column > 0)
2760 if (MPLIST_MTEXT_P (plist))
2762 MText *mt = MPLIST_MTEXT (plist);
2763 MPlist *next = MPLIST_NEXT (plist);
2765 if (MPLIST_TAIL_P (next))
2766 M17N_OBJECT_REF (mt);
2769 mt = mtext_dup (mt);
2770 while (! MPLIST_TAIL_P (next))
2772 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2773 next = MPLIST_NEXT (next);
2777 M17N_OBJECT_UNREF (plist);
2779 len = mtext_nchars (mt);
2781 mplist_add (plist, Mtext, mt);
2784 for (i = 0; i < len; i += column)
2786 int to = (i + column < len ? i + column : len);
2787 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2789 mplist_add (plist, Mtext, sub);
2790 M17N_OBJECT_UNREF (sub);
2793 M17N_OBJECT_UNREF (mt);
2795 else if (! MPLIST_TAIL_P (plist))
2797 MPlist *tail = plist;
2798 MPlist *new = mplist ();
2799 MPlist *this = mplist ();
2802 MPLIST_DO (tail, tail)
2804 MPlist *p = MPLIST_PLIST (tail);
2808 MText *mt = MPLIST_MTEXT (p);
2810 if (count == column)
2812 mplist_add (new, Mplist, this);
2813 M17N_OBJECT_UNREF (this);
2817 mplist_add (this, Mtext, mt);
2821 mplist_add (new, Mplist, this);
2822 M17N_OBJECT_UNREF (this);
2823 mplist_set (plist, Mnil, NULL);
2824 MPLIST_DO (tail, new)
2826 MPlist *elt = MPLIST_PLIST (tail);
2828 mplist_add (plist, Mplist, elt);
2830 M17N_OBJECT_UNREF (new);
2839 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2841 MPlist *action = NULL;
2845 if (MPLIST_SYMBOL_P (action_list))
2847 MSymbol var = MPLIST_SYMBOL (action_list);
2850 MPLIST_DO (p, ic_info->vars)
2851 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2853 if (MPLIST_TAIL_P (p))
2855 action = MPLIST_NEXT (MPLIST_PLIST (p));
2856 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2859 if (MPLIST_PLIST_P (action_list))
2861 action = MPLIST_PLIST (action_list);
2862 if (MPLIST_SYMBOL_P (action))
2864 name = MPLIST_SYMBOL (action);
2865 args = MPLIST_NEXT (action);
2867 && MPLIST_PLIST_P (args))
2868 mplist_set (action, Msymbol, M_candidates);
2870 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2873 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2874 mplist_push (action, Msymbol, M_candidates);
2875 mplist_set (action_list, Mplist, action);
2876 M17N_OBJECT_UNREF (action);
2879 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2882 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2883 mplist_push (action, Msymbol, Minsert);
2884 mplist_set (action_list, Mplist, action);
2885 M17N_OBJECT_UNREF (action);
2890 /* Perform list of actions in ACTION_LIST for the current input
2891 context IC. If unhandle action was not performed, return 0.
2892 Otherwise, return -1. */
2895 take_action_list (MInputContext *ic, MPlist *action_list)
2897 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2898 MPlist *candidate_list = ic->candidate_list;
2899 int candidate_index = ic->candidate_index;
2900 int candidate_show = ic->candidate_show;
2901 MTextProperty *prop;
2903 MPLIST_DO (action_list, action_list)
2905 MPlist *action = regularize_action (action_list, ic_info);
2911 name = MPLIST_SYMBOL (action);
2912 args = MPLIST_NEXT (action);
2914 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2915 if (name == Minsert)
2917 if (MPLIST_SYMBOL_P (args))
2919 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2920 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2923 if (MPLIST_MTEXT_P (args))
2924 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2925 else /* MPLIST_INTEGER_P (args)) */
2926 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2928 else if (name == M_candidates)
2930 MPlist *plist = get_candidate_list (ic_info, args);
2933 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2935 if (MPLIST_MTEXT_P (plist))
2937 preedit_insert (ic, ic->cursor_pos, NULL,
2938 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2941 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2945 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2947 preedit_insert (ic, ic->cursor_pos, mt, 0);
2948 len = mtext_nchars (mt);
2950 mtext_put_prop (ic->preedit,
2951 ic->cursor_pos - len, ic->cursor_pos,
2952 Mcandidate_list, plist);
2953 mtext_put_prop (ic->preedit,
2954 ic->cursor_pos - len, ic->cursor_pos,
2955 Mcandidate_index, (void *) 0);
2957 else if (name == Mselect)
2960 int code, idx, gindex;
2961 int pos = ic->cursor_pos;
2963 int idx_decided = 0;
2966 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2969 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2970 group = find_candidates_group (mtext_property_value (prop), idx,
2971 &start, &end, &gindex);
2972 if (MPLIST_SYMBOL_P (args))
2974 code = marker_code (MPLIST_SYMBOL (args), 0);
2977 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2978 if (! MPLIST_INTEGER_P (args))
2980 idx = start + MPLIST_INTEGER (args);
2981 if (idx < start || idx >= end)
2989 if (code != '[' && code != ']')
2994 ? new_index (NULL, ic->candidate_index - start,
2995 end - start - 1, MPLIST_SYMBOL (args),
2997 : MPLIST_INTEGER (args)));
3000 find_candidates_group (mtext_property_value (prop), -1,
3005 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3010 int ingroup_index = idx - start;
3013 group = mtext_property_value (prop);
3014 len = mplist_length (group);
3027 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3028 idx += (MPLIST_MTEXT_P (group)
3029 ? mtext_nchars (MPLIST_MTEXT (group))
3030 : mplist_length (MPLIST_PLIST (group)));
3031 len = (MPLIST_MTEXT_P (group)
3032 ? mtext_nchars (MPLIST_MTEXT (group))
3033 : mplist_length (MPLIST_PLIST (group)));
3034 if (ingroup_index >= len)
3035 ingroup_index = len - 1;
3036 idx += ingroup_index;
3038 update_candidate (ic, prop, idx);
3039 MDEBUG_PRINT1 ("(%d)", idx);
3041 else if (name == Mshow)
3042 ic->candidate_show = 1;
3043 else if (name == Mhide)
3044 ic->candidate_show = 0;
3045 else if (name == Mdelete)
3047 int len = mtext_nchars (ic->preedit);
3051 if (MPLIST_SYMBOL_P (args)
3052 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3054 to = ic->cursor_pos + pos;
3057 delete_surrounding_text (ic, to);
3062 delete_surrounding_text (ic, to - len);
3068 to = (MPLIST_SYMBOL_P (args)
3069 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3071 : MPLIST_INTEGER (args));
3077 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3078 if (to < ic->cursor_pos)
3079 preedit_delete (ic, to, ic->cursor_pos);
3080 else if (to > ic->cursor_pos)
3081 preedit_delete (ic, ic->cursor_pos, to);
3083 else if (name == Mmove)
3085 int len = mtext_nchars (ic->preedit);
3087 = (MPLIST_SYMBOL_P (args)
3088 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3090 : MPLIST_INTEGER (args));
3096 if (pos != ic->cursor_pos)
3098 ic->cursor_pos = pos;
3099 ic->preedit_changed = 1;
3101 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3103 else if (name == Mmark)
3105 int code = marker_code (MPLIST_SYMBOL (args), 0);
3109 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3110 (void *) ic->cursor_pos);
3111 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3114 else if (name == Mpushback)
3116 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3120 if (MPLIST_SYMBOL_P (args))
3122 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3123 if (MPLIST_INTEGER_P (args))
3124 num = MPLIST_INTEGER (args);
3129 num = MPLIST_INTEGER (args);
3132 ic_info->key_head -= num;
3134 ic_info->key_head = 0;
3136 ic_info->key_head = - num;
3137 if (ic_info->key_head > ic_info->used)
3138 ic_info->key_head = ic_info->used;
3140 else if (MPLIST_MTEXT_P (args))
3142 MText *mt = MPLIST_MTEXT (args);
3143 int i, len = mtext_nchars (mt);
3146 ic_info->key_head--;
3147 for (i = 0; i < len; i++)
3149 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3150 if (ic_info->key_head + i < ic_info->used)
3151 ic_info->keys[ic_info->key_head + i] = key;
3153 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3158 MPlist *plist = MPLIST_PLIST (args), *pl;
3162 ic_info->key_head--;
3164 MPLIST_DO (pl, plist)
3166 key = MPLIST_SYMBOL (pl);
3167 if (ic_info->key_head < ic_info->used)
3168 ic_info->keys[ic_info->key_head + i] = key;
3170 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3175 else if (name == Mpop)
3177 if (ic_info->key_head < ic_info->used)
3178 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3180 else if (name == Mcall)
3182 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3183 MIMExternalFunc func = NULL;
3184 MSymbol module, func_name;
3185 MPlist *func_args, *val;
3188 module = MPLIST_SYMBOL (args);
3189 args = MPLIST_NEXT (args);
3190 func_name = MPLIST_SYMBOL (args);
3192 if (im_info->externals)
3194 MIMExternalModule *external
3195 = (MIMExternalModule *) mplist_get (im_info->externals,
3198 func = ((MIMExternalFunc)
3199 mplist_get_func (external->func_list, func_name));
3203 func_args = mplist ();
3204 mplist_add (func_args, Mt, ic);
3205 MPLIST_DO (args, MPLIST_NEXT (args))
3209 if (MPLIST_KEY (args) == Msymbol
3210 && MPLIST_KEY (args) != Mnil
3211 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3213 code = new_index (ic, ic->cursor_pos,
3214 mtext_nchars (ic->preedit),
3215 MPLIST_SYMBOL (args), ic->preedit);
3216 mplist_add (func_args, Minteger, (void *) code);
3219 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3221 val = (func) (func_args);
3222 M17N_OBJECT_UNREF (func_args);
3223 if (val && ! MPLIST_TAIL_P (val))
3224 ret = take_action_list (ic, val);
3225 M17N_OBJECT_UNREF (val);
3229 else if (name == Mshift)
3231 shift_state (ic, MPLIST_SYMBOL (args));
3233 else if (name == Mundo)
3235 int intarg = (MPLIST_TAIL_P (args)
3237 : integer_value (ic, args, NULL, 0));
3239 mtext_reset (ic->preedit);
3240 mtext_reset (ic_info->preedit_saved);
3241 mtext_reset (ic->produced);
3242 M17N_OBJECT_UNREF (ic_info->vars);
3243 ic_info->vars = mplist_copy (ic_info->vars_saved);
3244 ic->cursor_pos = ic_info->state_pos = 0;
3245 ic_info->state_key_head = ic_info->key_head
3246 = ic_info->commit_key_head = 0;
3248 shift_state (ic, Mnil);
3251 if (MPLIST_TAIL_P (args))
3256 ic_info->used += intarg;
3259 ic_info->used = intarg;
3262 else if (name == Mset || name == Madd || name == Msub
3263 || name == Mmul || name == Mdiv)
3265 MSymbol sym = MPLIST_SYMBOL (args);
3270 val1 = integer_value (ic, args, &value, 0);
3271 args = MPLIST_NEXT (args);
3272 val2 = resolve_expression (ic, args);
3274 val1 = val2, op = "=";
3275 else if (name == Madd)
3276 val1 += val2, op = "+=";
3277 else if (name == Msub)
3278 val1 -= val2, op = "-=";
3279 else if (name == Mmul)
3280 val1 *= val2, op = "*=";
3282 val1 /= val2, op = "/=";
3283 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3284 MSYMBOL_NAME (sym), op, val1, val1);
3286 mplist_set (value, Minteger, (void *) val1);
3288 else if (name == Mequal || name == Mless || name == Mgreater
3289 || name == Mless_equal || name == Mgreater_equal)
3292 MPlist *actions1, *actions2;
3295 val1 = resolve_expression (ic, args);
3296 args = MPLIST_NEXT (args);
3297 val2 = resolve_expression (ic, args);
3298 args = MPLIST_NEXT (args);
3299 actions1 = MPLIST_PLIST (args);
3300 args = MPLIST_NEXT (args);
3301 if (MPLIST_TAIL_P (args))
3304 actions2 = MPLIST_PLIST (args);
3305 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3306 if (name == Mequal ? val1 == val2
3307 : name == Mless ? val1 < val2
3308 : name == Mgreater ? val1 > val2
3309 : name == Mless_equal ? val1 <= val2
3312 MDEBUG_PRINT ("ok");
3313 ret = take_action_list (ic, actions1);
3317 MDEBUG_PRINT ("no");
3319 ret = take_action_list (ic, actions2);
3324 else if (name == Mcond)
3328 MPLIST_DO (args, args)
3333 if (! MPLIST_PLIST (args))
3335 cond = MPLIST_PLIST (args);
3336 if (resolve_expression (ic, cond) != 0)
3338 MDEBUG_PRINT1 ("(%dth)", idx);
3339 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3345 else if (name == Mcommit)
3347 preedit_commit (ic);
3349 else if (name == Munhandle)
3351 preedit_commit (ic);
3356 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3360 && (actions = mplist_get (im_info->macros, name)))
3362 if (take_action_list (ic, actions) < 0)
3368 if (ic->candidate_list)
3370 M17N_OBJECT_UNREF (ic->candidate_list);
3371 ic->candidate_list = NULL;
3373 if (ic->cursor_pos > 0
3374 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3377 ic->candidate_list = mtext_property_value (prop);
3378 M17N_OBJECT_REF (ic->candidate_list);
3380 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3382 ic->candidate_from = mtext_property_start (prop);
3383 ic->candidate_to = mtext_property_end (prop);
3386 if (candidate_list != ic->candidate_list)
3387 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3388 if (candidate_index != ic->candidate_index)
3389 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3390 if (candidate_show != ic->candidate_show)
3391 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3396 /* Handle the input key KEY in the current state and map specified in
3397 the input context IC. If KEY is handled correctly, return 0.
3398 Otherwise, return -1. */
3401 handle_key (MInputContext *ic)
3403 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3404 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3405 MIMMap *map = ic_info->map;
3406 MIMMap *submap = NULL;
3407 MSymbol key = ic_info->keys[ic_info->key_head];
3408 MSymbol alias = Mnil;
3411 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3412 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3416 submap = mplist_get (map->submaps, key);
3419 && (alias = msymbol_get (alias, M_key_alias))
3421 submap = mplist_get (map->submaps, alias);
3426 if (! alias || alias == key)
3427 MDEBUG_PRINT (" submap-found");
3429 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3430 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3431 ic->preedit_changed = 1;
3432 ic->cursor_pos = ic_info->state_pos;
3433 ic_info->key_head++;
3434 ic_info->map = map = submap;
3435 if (map->map_actions)
3437 MDEBUG_PRINT (" map-actions:");
3438 if (take_action_list (ic, map->map_actions) < 0)
3440 MDEBUG_PRINT ("\n");
3444 else if (map->submaps)
3446 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3448 MSymbol key = ic_info->keys[i];
3449 char *name = msymbol_name (key);
3451 if (! name[0] || ! name[1])
3452 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3456 /* If this is the terminal map or we have shifted to another
3457 state, perform branch actions (if any). */
3458 if (! map->submaps || map != ic_info->map)
3460 if (map->branch_actions)
3462 MDEBUG_PRINT (" branch-actions:");
3463 if (take_action_list (ic, map->branch_actions) < 0)
3465 MDEBUG_PRINT ("\n");
3469 /* If MAP is still not the root map, shift to the current
3471 if (ic_info->map != ic_info->state->map)
3472 shift_state (ic, ic_info->state->name);
3477 /* MAP can not handle KEY. */
3479 /* Perform branch actions if any. */
3480 if (map->branch_actions)
3482 MDEBUG_PRINT (" branch-actions:");
3483 if (take_action_list (ic, map->branch_actions) < 0)
3485 MDEBUG_PRINT ("\n");
3490 if (map == ic_info->map)
3492 /* The above branch actions didn't change the state. */
3494 /* If MAP is the root map of the initial state, and there
3495 still exist an unhandled key, it means that the current
3496 input method can not handle it. */
3497 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3498 && ic_info->key_head < ic_info->used)
3500 MDEBUG_PRINT (" unhandled\n");
3504 if (map != ic_info->state->map)
3506 /* MAP is not the root map. Shift to the root map of the
3508 shift_state (ic, ic_info->state->name);
3510 else if (! map->branch_actions)
3512 /* MAP is the root map without any default branch
3513 actions. Shift to the initial state. */
3514 shift_state (ic, Mnil);
3518 MDEBUG_PRINT ("\n");
3522 /* Initialize IC->ic_info. */
3525 init_ic_info (MInputContext *ic)
3527 MInputMethodInfo *im_info = ic->im->info;
3528 MInputContextInfo *ic_info = ic->info;
3531 MLIST_INIT1 (ic_info, keys, 8);;
3533 ic_info->markers = mplist ();
3535 ic_info->vars = mplist ();
3536 if (im_info->configured_vars)
3537 MPLIST_DO (plist, im_info->configured_vars)
3539 MPlist *pl = MPLIST_PLIST (plist);
3540 MSymbol name = MPLIST_SYMBOL (pl);
3542 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3543 if (MPLIST_KEY (pl) != Mt)
3545 MPlist *p = mplist ();
3547 mplist_push (ic_info->vars, Mplist, p);
3548 M17N_OBJECT_UNREF (p);
3549 mplist_add (p, Msymbol, name);
3550 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3553 ic_info->vars_saved = mplist_copy (ic_info->vars);
3555 if (im_info->externals)
3557 MPlist *func_args = mplist (), *plist;
3559 mplist_add (func_args, Mt, ic);
3560 MPLIST_DO (plist, im_info->externals)
3562 MIMExternalModule *external = MPLIST_VAL (plist);
3563 MIMExternalFunc func
3564 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3569 M17N_OBJECT_UNREF (func_args);
3572 ic_info->preedit_saved = mtext ();
3573 ic_info->tick = im_info->tick;
3576 /* Finalize IC->ic_info. */
3579 fini_ic_info (MInputContext *ic)
3581 MInputMethodInfo *im_info = ic->im->info;
3582 MInputContextInfo *ic_info = ic->info;
3584 if (im_info->externals)
3586 MPlist *func_args = mplist (), *plist;
3588 mplist_add (func_args, Mt, ic);
3589 MPLIST_DO (plist, im_info->externals)
3591 MIMExternalModule *external = MPLIST_VAL (plist);
3592 MIMExternalFunc func
3593 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3598 M17N_OBJECT_UNREF (func_args);
3601 MLIST_FREE1 (ic_info, keys);
3602 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3603 M17N_OBJECT_UNREF (ic_info->markers);
3604 M17N_OBJECT_UNREF (ic_info->vars);
3605 M17N_OBJECT_UNREF (ic_info->vars_saved);
3606 M17N_OBJECT_UNREF (ic_info->preceding_text);
3607 M17N_OBJECT_UNREF (ic_info->following_text);
3609 memset (ic_info, 0, sizeof (MInputContextInfo));
3613 re_init_ic (MInputContext *ic, int reload)
3615 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3616 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3617 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3619 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3620 preedit_changed = mtext_nchars (ic->preedit) > 0;
3621 cursor_pos_changed = ic->cursor_pos > 0;
3622 candidates_changed = 0;
3623 if (ic->candidate_list)
3625 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3626 M17N_OBJECT_UNREF (ic->candidate_list);
3627 ic->candidate_list = NULL;
3629 if (ic->candidate_show)
3631 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3632 ic->candidate_show = 0;
3634 if (ic->candidate_index > 0)
3636 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3637 ic->candidate_index = 0;
3638 ic->candidate_from = ic->candidate_to = 0;
3640 if (mtext_nchars (ic->produced) > 0)
3641 mtext_reset (ic->produced);
3642 if (mtext_nchars (ic->preedit) > 0)
3643 mtext_reset (ic->preedit);
3645 M17N_OBJECT_UNREF (ic->plist);
3646 ic->plist = mplist ();
3650 reload_im_info (im_info);
3652 shift_state (ic, Mnil);
3653 ic->status_changed = status_changed;
3654 ic->preedit_changed = preedit_changed;
3655 ic->cursor_pos_changed = cursor_pos_changed;
3656 ic->candidates_changed = candidates_changed;
3660 reset_ic (MInputContext *ic, MSymbol ignore)
3662 MDEBUG_PRINT ("\n [IM] reset\n");
3667 open_im (MInputMethod *im)
3669 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3672 MERROR (MERROR_IM, -1);
3679 close_im (MInputMethod *im)
3685 create_ic (MInputContext *ic)
3687 MInputContextInfo *ic_info;
3689 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3692 shift_state (ic, Mnil);
3697 destroy_ic (MInputContext *ic)
3704 check_reload (MInputContext *ic, MSymbol key)
3706 MInputMethodInfo *im_info = ic->im->info;
3707 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3711 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3715 MPLIST_DO (plist, plist)
3717 MSymbol this_key, alias;
3719 if (MPLIST_MTEXT_P (plist))
3721 MText *mt = MPLIST_MTEXT (plist);
3722 int c = mtext_ref_char (mt, 0);
3726 this_key = one_char_symbol[c];
3730 MPlist *pl = MPLIST_PLIST (plist);
3732 this_key = MPLIST_SYMBOL (pl);
3736 && (alias = msymbol_get (alias, M_key_alias))
3737 && alias != this_key);
3741 if (MPLIST_TAIL_P (plist))
3744 MDEBUG_PRINT ("\n [IM] reload");
3750 /** Handle the input key KEY in the current state and map of IC->info.
3751 If KEY is handled but no text is produced, return 0, otherwise
3757 filter (MInputContext *ic, MSymbol key, void *arg)
3759 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3760 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3763 if (check_reload (ic, key))
3766 if (! ic_info->state)
3768 ic_info->key_unhandled = 1;
3771 mtext_reset (ic->produced);
3772 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3773 M17N_OBJECT_UNREF (ic_info->preceding_text);
3774 M17N_OBJECT_UNREF (ic_info->following_text);
3775 ic_info->preceding_text = ic_info->following_text = NULL;
3776 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3777 ic_info->key_unhandled = 0;
3780 if (handle_key (ic) < 0)
3782 /* KEY was not handled. Delete it from the current key sequence. */
3783 if (ic_info->used > 0)
3785 memmove (ic_info->keys, ic_info->keys + 1,
3786 sizeof (int) * (ic_info->used - 1));
3788 if (ic_info->state_key_head > 0)
3789 ic_info->state_key_head--;
3790 if (ic_info->commit_key_head > 0)
3791 ic_info->commit_key_head--;
3793 /* This forces returning 1. */
3794 ic_info->key_unhandled = 1;
3800 reset_ic (ic, Mnil);
3801 ic_info->key_unhandled = 1;
3804 /* Break the loop if all keys were handled. */
3805 } while (ic_info->key_head < ic_info->used);
3807 /* If the current map is the root of the initial state, we should
3808 produce any preedit text in ic->produced. */
3809 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3810 preedit_commit (ic);
3812 if (mtext_nchars (ic->produced) > 0)
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));
3822 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3823 Mlanguage, ic->im->language);
3825 if (ic_info->commit_key_head > 0)
3827 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3828 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3829 ic_info->used -= ic_info->commit_key_head;
3830 ic_info->key_head -= ic_info->commit_key_head;
3831 ic_info->state_key_head -= ic_info->commit_key_head;
3832 ic_info->commit_key_head = 0;
3834 if (ic_info->key_unhandled)
3837 ic_info->key_head = ic_info->state_key_head
3838 = ic_info->commit_key_head = 0;
3841 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3845 /** Return 1 if the last event or key was not handled, otherwise
3848 There is no need of looking up because ic->produced should already
3849 contain the produced text (if any).
3854 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3856 mtext_cat (mt, ic->produced);
3857 mtext_reset (ic->produced);
3858 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3862 /* Input method command handler. */
3864 /* List of all (global and local) commands.
3865 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3866 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3867 Global commands are stored as (t (t COMMAND ...)) */
3870 /* Input method variable handler. */
3873 /* Support functions for mdebug_dump_im. */
3876 dump_im_map (MPlist *map_list, int indent)
3879 MSymbol key = MPLIST_KEY (map_list);
3880 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3882 prefix = (char *) alloca (indent + 1);
3883 memset (prefix, 32, indent);
3884 prefix[indent] = '\0';
3886 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3887 if (map->map_actions)
3888 mdebug_dump_plist (map->map_actions, indent + 2);
3891 MPLIST_DO (map_list, map->submaps)
3893 fprintf (stderr, "\n%s ", prefix);
3894 dump_im_map (map_list, indent + 2);
3897 if (map->branch_actions)
3899 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3900 mdebug_dump_plist (map->branch_actions, indent + 4);
3901 fprintf (stderr, ")");
3903 fprintf (stderr, ")");
3908 dump_im_state (MIMState *state, int indent)
3913 prefix = (char *) alloca (indent + 1);
3914 memset (prefix, 32, indent);
3915 prefix[indent] = '\0';
3917 fprintf (stderr, "(%s", msymbol_name (state->name));
3918 if (state->map->submaps)
3920 MPLIST_DO (map_list, state->map->submaps)
3922 fprintf (stderr, "\n%s ", prefix);
3923 dump_im_map (map_list, indent + 2);
3926 fprintf (stderr, ")");
3934 Minput_driver = msymbol ("input-driver");
3936 Minput_preedit_start = msymbol ("input-preedit-start");
3937 Minput_preedit_done = msymbol ("input-preedit-done");
3938 Minput_preedit_draw = msymbol ("input-preedit-draw");
3939 Minput_status_start = msymbol ("input-status-start");
3940 Minput_status_done = msymbol ("input-status-done");
3941 Minput_status_draw = msymbol ("input-status-draw");
3942 Minput_candidates_start = msymbol ("input-candidates-start");
3943 Minput_candidates_done = msymbol ("input-candidates-done");
3944 Minput_candidates_draw = msymbol ("input-candidates-draw");
3945 Minput_set_spot = msymbol ("input-set-spot");
3946 Minput_focus_move = msymbol ("input-focus-move");
3947 Minput_focus_in = msymbol ("input-focus-in");
3948 Minput_focus_out = msymbol ("input-focus-out");
3949 Minput_toggle = msymbol ("input-toggle");
3950 Minput_reset = msymbol ("input-reset");
3951 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3952 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3953 Mcustomized = msymbol ("customized");
3954 Mconfigured = msymbol ("configured");
3955 Minherited = msymbol ("inherited");
3957 minput_default_driver.open_im = open_im;
3958 minput_default_driver.close_im = close_im;
3959 minput_default_driver.create_ic = create_ic;
3960 minput_default_driver.destroy_ic = destroy_ic;
3961 minput_default_driver.filter = filter;
3962 minput_default_driver.lookup = lookup;
3963 minput_default_driver.callback_list = mplist ();
3964 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
3965 M17N_FUNC (reset_ic));
3966 minput_driver = &minput_default_driver;
3968 fully_initialized = 0;
3975 if (fully_initialized)
3977 free_im_list (im_info_list);
3979 free_im_list (im_custom_list);
3981 free_im_list (im_config_list);
3982 M17N_OBJECT_UNREF (load_im_info_keys);
3985 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3986 M17N_OBJECT_UNREF (minput_driver->callback_list);
3991 minput__char_to_key (int c)
3993 if (c < 0 || c >= 0x100)
3996 return one_char_symbol[c];
4000 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4005 /*** @addtogroup m17nInputMethod */
4010 @name Variables: Predefined symbols for callback commands.
4012 These are the predefined symbols that are used as the @c COMMAND
4013 argument of callback functions of an input method driver (see
4014 #MInputDriver::callback_list).
4016 Most of them do not require extra argument nor return any value;
4017 exceptions are these:
4019 Minput_get_surrounding_text: When a callback function assigned for
4020 this command is called, the first element of #MInputContext::plist
4021 has key #Minteger and the value specifies which portion of the
4022 surrounding text should be retrieved. If the value is positive,
4023 it specifies the number of characters following the current cursor
4024 position. If the value is negative, the absolute value specifies
4025 the number of characters preceding the current cursor position.
4026 If the value is zero, it means that the caller just wants to know
4027 if the surrounding text is currently supported or not.
4029 If the surrounding text is currently supported, the callback
4030 function must set the key of this element to #Mtext and the value
4031 to the retrieved M-text. The length of the M-text may be shorter
4032 than the requested number of characters, if the available text is
4033 not that long. The length can be zero in the worst case. Or, the
4034 length may be longer if an application thinks it is more efficient
4035 to return that length.
4037 If the surrounding text is not currently supported, the callback
4038 function should return without changing the first element of
4039 #MInputContext::plist.
4041 Minput_delete_surrounding_text: When a callback function assigned
4042 for this command is called, the first element of
4043 #MInputContext::plist has key #Minteger and the value specifies
4044 which portion of the surrounding text should be deleted in the
4045 same way as the case of Minput_get_surrounding_text. The callback
4046 function must delete the specified text. It should not alter
4047 #MInputContext::plist. */
4049 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4051 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4052 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4054 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4056 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4057 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4058 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4059 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4060 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4061 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4062 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4064 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4065 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4066 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4067 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4068 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4070 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4071 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4073 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4074 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4075 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4076 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4077 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4078 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4082 MSymbol Minput_preedit_start;
4083 MSymbol Minput_preedit_done;
4084 MSymbol Minput_preedit_draw;
4085 MSymbol Minput_status_start;
4086 MSymbol Minput_status_done;
4087 MSymbol Minput_status_draw;
4088 MSymbol Minput_candidates_start;
4089 MSymbol Minput_candidates_done;
4090 MSymbol Minput_candidates_draw;
4091 MSymbol Minput_set_spot;
4092 MSymbol Minput_toggle;
4093 MSymbol Minput_reset;
4094 MSymbol Minput_get_surrounding_text;
4095 MSymbol Minput_delete_surrounding_text;
4101 @name Variables: Predefined symbols for special input events.
4103 These are the predefined symbols that are used as the @c KEY
4104 argument of minput_filter (). */
4106 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4108 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4113 MSymbol Minput_focus_out;
4114 MSymbol Minput_focus_in;
4115 MSymbol Minput_focus_move;
4121 @name Variables: Predefined symbols used in input method information.
4123 These are the predefined symbols describing status of input method
4124 command and variable, and are used in a return value of
4125 minput_get_command () and minput_get_variable (). */
4127 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4129 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4130 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4134 MSymbol Mcustomized;
4135 MSymbol Mconfigured;
4141 @brief The default driver for internal input methods.
4143 The variable #minput_default_driver is the default driver for
4144 internal input methods.
4146 The member MInputDriver::open_im () searches the m17n database for
4147 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4148 $NAME\> and loads it.
4150 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4151 programmers responsibility to set it to a plist of proper callback
4152 functions. Otherwise, no feedback information (e.g. preedit text)
4153 can be shown to users.
4155 The macro M17N_INIT () sets the variable #minput_driver to the
4156 pointer to this driver so that all internal input methods use it.
4158 Therefore, unless @c minput_driver is set differently, the driver
4159 dependent arguments $ARG of the functions whose name begins with
4160 "minput_" are all ignored. */
4162 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4164 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4166 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4167 \< #Minput_method, $LANGUAGE, $NAME\>
4168 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4170 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4171 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4172 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4173 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4175 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4176 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4178 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4179 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4181 MInputDriver minput_default_driver;
4185 @brief The driver for internal input methods.
4187 The variable #minput_driver is a pointer to the input method
4188 driver that is used by internal input methods. The macro
4189 M17N_INIT () initializes it to a pointer to #minput_default_driver
4190 if <m17n<EM></EM>.h> is included. */
4192 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4194 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4195 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4196 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4197 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4199 MInputDriver *minput_driver;
4201 MSymbol Minput_driver;
4216 @brief Open an input method.
4218 The minput_open_im () function opens an input method whose
4219 language and name match $LANGUAGE and $NAME, and returns a pointer
4220 to the input method object newly allocated.
4222 This function at first decides a driver for the input method as
4225 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4226 #minput_driver is used.
4228 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4229 driver pointed to by the property value is used to open the input
4230 method. If $NAME has no such a property, @c NULL is returned.
4232 Then, the member MInputDriver::open_im () of the driver is
4235 $ARG is set in the member @c arg of the structure MInputMethod so
4236 that the driver can refer to it. */
4238 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4240 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4241 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4243 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4245 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4246 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4248 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4249 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4250 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4252 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4254 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4256 @latexonly \IPAlabel{minput_open} @endlatexonly
4261 minput_open_im (MSymbol language, MSymbol name, void *arg)
4264 MInputDriver *driver;
4268 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4269 msymbol_name (language), msymbol_name (name));
4271 driver = minput_driver;
4274 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4276 MERROR (MERROR_IM, NULL);
4279 MSTRUCT_CALLOC (im, MERROR_IM);
4280 im->language = language;
4283 im->driver = *driver;
4284 if ((*im->driver.open_im) (im) < 0)
4286 MDEBUG_PRINT (" failed\n");
4290 MDEBUG_PRINT (" ok\n");
4297 @brief Close an input method.
4299 The minput_close_im () function closes the input method $IM, which
4300 must have been created by minput_open_im (). */
4303 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4305 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4306 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4309 minput_close_im (MInputMethod *im)
4311 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4312 msymbol_name (im->name), msymbol_name (im->language));
4313 (*im->driver.close_im) (im);
4315 MDEBUG_PRINT (" done\n");
4321 @brief Create an input context.
4323 The minput_create_ic () function creates an input context object
4324 associated with input method $IM, and calls callback functions
4325 corresponding to #Minput_preedit_start, #Minput_status_start, and
4326 #Minput_status_draw in this order.
4329 If an input context is successfully created, minput_create_ic ()
4330 returns a pointer to it. Otherwise it returns @c NULL. */
4333 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4335 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4336 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4337 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4338 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4341 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4342 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4346 minput_create_ic (MInputMethod *im, void *arg)
4350 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4351 msymbol_name (im->name), msymbol_name (im->language));
4352 MSTRUCT_CALLOC (ic, MERROR_IM);
4355 ic->preedit = mtext ();
4356 ic->candidate_list = NULL;
4357 ic->produced = mtext ();
4358 ic->spot.x = ic->spot.y = 0;
4360 ic->plist = mplist ();
4361 if ((*im->driver.create_ic) (ic) < 0)
4363 MDEBUG_PRINT (" failed\n");
4364 M17N_OBJECT_UNREF (ic->preedit);
4365 M17N_OBJECT_UNREF (ic->produced);
4366 M17N_OBJECT_UNREF (ic->plist);
4371 if (im->driver.callback_list)
4373 minput_callback (ic, Minput_preedit_start);
4374 minput_callback (ic, Minput_status_start);
4375 minput_callback (ic, Minput_status_draw);
4378 MDEBUG_PRINT (" ok\n");
4385 @brief Destroy an input context.
4387 The minput_destroy_ic () function destroys the input context $IC,
4388 which must have been created by minput_create_ic (). It calls
4389 callback functions corresponding to #Minput_preedit_done,
4390 #Minput_status_done, and #Minput_candidates_done in this order. */
4393 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4395 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4396 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4397 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4398 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4399 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4403 minput_destroy_ic (MInputContext *ic)
4405 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4406 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4407 if (ic->im->driver.callback_list)
4409 minput_callback (ic, Minput_preedit_done);
4410 minput_callback (ic, Minput_status_done);
4411 minput_callback (ic, Minput_candidates_done);
4413 (*ic->im->driver.destroy_ic) (ic);
4414 M17N_OBJECT_UNREF (ic->preedit);
4415 M17N_OBJECT_UNREF (ic->produced);
4416 M17N_OBJECT_UNREF (ic->plist);
4417 MDEBUG_PRINT (" done\n");
4424 @brief Filter an input key.
4426 The minput_filter () function filters input key $KEY according to
4427 input context $IC, and calls callback functions corresponding to
4428 #Minput_preedit_draw, #Minput_status_draw, and
4429 #Minput_candidates_draw if the preedit text, the status, and the
4430 current candidate are changed respectively.
4432 To make the input method commit the current preedit text (if any)
4433 and shift to the initial state, call this function with #Mnil as
4436 To inform the input method about the focus-out event, call this
4437 function with #Minput_focus_out as $KEY.
4439 To inform the input method about the focus-in event, call this
4440 function with #Minput_focus_in as $KEY.
4442 To inform the input method about the focus-move event (i.e. input
4443 spot change within the same input context), call this function
4444 with #Minput_focus_move as $KEY.
4447 If $KEY is filtered out, this function returns 1. In that case,
4448 the caller should discard the key. Otherwise, it returns 0, and
4449 the caller should handle the key, for instance, by calling the
4450 function minput_lookup () with the same key. */
4453 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4455 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4456 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4457 #Minput_preedit_draw, #Minput_status_draw,
4458 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4461 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4462 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4463 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4464 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4466 @latexonly \IPAlabel{minput_filter} @endlatexonly
4470 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4477 if (ic->im->driver.callback_list
4478 && mtext_nchars (ic->preedit) > 0)
4479 minput_callback (ic, Minput_preedit_draw);
4481 ret = (*ic->im->driver.filter) (ic, key, arg);
4483 if (ic->im->driver.callback_list)
4485 if (ic->preedit_changed)
4486 minput_callback (ic, Minput_preedit_draw);
4487 if (ic->status_changed)
4488 minput_callback (ic, Minput_status_draw);
4489 if (ic->candidates_changed)
4490 minput_callback (ic, Minput_candidates_draw);
4499 @brief Look up a text produced in the input context.
4501 The minput_lookup () function looks up a text in the input context
4502 $IC. $KEY must be identical to the one that was used in the previous call of
4505 If a text was produced by the input method, it is concatenated
4508 This function calls #MInputDriver::lookup .
4511 If $KEY was correctly handled by the input method, this function
4512 returns 0. Otherwise, it returns -1, even though some text
4513 might be produced in $MT. */
4516 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4518 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4519 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4521 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4524 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4527 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4528 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4529 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4531 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4534 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4536 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4541 @brief Set the spot of the input context.
4543 The minput_set_spot () function sets the spot of input context $IC
4544 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4545 The semantics of these values depends on the input method driver.
4547 For instance, a driver designed to work in a CUI environment may
4548 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4549 $DESCENT . A driver designed to work in a window system may
4550 interpret $X and $Y as the pixel offsets relative to the origin of the
4551 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4552 descent pixels of the line at ($X . $Y ).
4554 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4556 $MT and $POS are the M-text and the character position at the spot.
4557 $MT may be @c NULL, in which case, the input method cannot get
4558 information about the text around the spot. */
4561 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4563 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4564 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4565 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4567 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4568 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4569 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4570 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4571 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4572 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4574 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4576 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4577 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4581 minput_set_spot (MInputContext *ic, int x, int y,
4582 int ascent, int descent, int fontsize,
4587 ic->spot.ascent = ascent;
4588 ic->spot.descent = descent;
4589 ic->spot.fontsize = fontsize;
4592 if (ic->im->driver.callback_list)
4593 minput_callback (ic, Minput_set_spot);
4598 @brief Toggle input method.
4600 The minput_toggle () function toggles the input method associated
4601 with input context $IC. */
4603 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4605 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4606 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4610 minput_toggle (MInputContext *ic)
4612 if (ic->im->driver.callback_list)
4613 minput_callback (ic, Minput_toggle);
4614 ic->active = ! ic->active;
4620 @brief Reset an input context.
4622 The minput_reset_ic () function resets input context $IC by
4623 calling a callback function corresponding to #Minput_reset. It
4624 resets the status of $IC to its initial one. As the
4625 current preedit text is deleted without commitment, if necessary,
4626 call minput_filter () with the arg @r key #Mnil to force the input
4627 method to commit the preedit in advance. */
4630 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4632 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4633 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4634 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4635 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4636 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4637 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4640 minput_reset_ic (MInputContext *ic)
4642 if (ic->im->driver.callback_list)
4643 minput_callback (ic, Minput_reset);
4649 @brief Get title and icon filename of an input method.
4651 The minput_get_title_icon () function returns a plist containing a
4652 title and icon filename (if any) of an input method specified by
4653 $LANGUAGE and $NAME.
4655 The first element of the plist has key #Mtext and the value is an
4656 M-text of the title for identifying the input method. The second
4657 element (if any) has key #Mtext and the value is an M-text of the
4658 icon image (absolute) filename for the same purpose.
4661 If there exists a specified input method and it defines an title,
4662 a plist is returned. Otherwise, NULL is returned. The caller
4663 must free the plist by m17n_object_unref (). */
4665 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4667 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4668 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4671 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4672 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4673 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4676 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4677 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4678 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4681 minput_get_title_icon (MSymbol language, MSymbol name)
4683 MInputMethodInfo *im_info;
4690 im_info = get_im_info (language, name, Mnil, Mtitle);
4691 if (! im_info || !im_info->title)
4693 mt = mtext_get_prop (im_info->title, 0, Mtext);
4695 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4698 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4701 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4702 (char *) MSYMBOL_NAME (name));
4703 file = mdatabase__find_file (buf);
4704 if (! file && language == Mt)
4706 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4707 file = mdatabase__find_file (buf);
4712 mplist_add (plist, Mtext, im_info->title);
4715 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4717 mplist_add (plist, Mtext, mt);
4718 M17N_OBJECT_UNREF (mt);
4726 @brief Get description text of an input method.
4728 The minput_get_description () function returns an M-text that
4729 describes the input method specified by $LANGUAGE and $NAME.
4732 If the specified input method has a description text, a pointer to
4733 #MText is returned. The caller has to free it by m17n_object_unref ().
4734 If the input method does not have a description text, @c NULL is
4737 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4739 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4740 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4742 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4743 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4744 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4745 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4748 minput_get_description (MSymbol language, MSymbol name)
4750 MInputMethodInfo *im_info;
4758 extra = language, language = Mt;
4760 im_info = get_im_info (language, name, extra, Mdescription);
4761 if (! im_info || ! im_info->description)
4763 M17N_OBJECT_REF (im_info->description);
4764 return im_info->description;
4770 @brief Get information about input method command(s).
4772 The minput_get_command () function returns information about
4773 the command $COMMAND of the input method specified by $LANGUAGE and
4774 $NAME. An input method command is a pseudo key event to which one
4775 or more actual input key sequences are assigned.
4777 There are two kinds of commands, global and local. A global
4778 command has a global definition, and the description and the key
4779 assignment may be inherited by a local command. Each input method
4780 defines a local command which has a local key assignment. It may
4781 also declare a local command that inherits the definition of a
4782 global command of the same name.
4784 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4785 information about a global command. Otherwise information about a
4786 local command is returned.
4788 If $COMMAND is #Mnil, information about all commands is returned.
4790 The return value is a @e well-formed plist (#m17nPlist) of this
4793 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4795 @c NAME is a symbol representing the command name.
4797 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4798 command has no description.
4800 @c STATUS is a symbol representing how the key assignment is decided.
4801 The value is #Mnil (the default key assignment), #Mcustomized (the
4802 key assignment is customized by per-user customization file), or
4803 #Mconfigured (the key assignment is set by the call of
4804 minput_config_command ()). For a local command only, it may also
4805 be #Minherited (the key assignment is inherited from the
4806 corresponding global command).
4808 @c KEYSEQ is a plist of one or more symbols representing a key
4809 sequence assigned to the command. If there's no KEYSEQ, the
4810 command is currently disabled (i.e. no key sequence can trigger
4811 actions of the command).
4813 If $COMMAND is not #Mnil, the first element of the returned plist
4814 contains the information about $COMMAND.
4818 If the requested information was found, a pointer to a non-empty
4819 plist is returned. As the plist is kept in the library, the
4820 caller must not modify nor free it.
4822 Otherwise (the specified input method or the specified command
4823 does not exist), @c NULL is returned. */
4825 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4827 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4828 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4829 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4830 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4832 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4833 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4834 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4835 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4836 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4838 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4839 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4842 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4844 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4847 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4849 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4851 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4854 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4855 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4856 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4857 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4858 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4859 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4862 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4863 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4864 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4865 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4867 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4868 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4872 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4873 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4876 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4881 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4883 /* Return a description of the command COMMAND of the input method
4884 specified by LANGUAGE and NAME. */
4885 MPlist *cmd = minput_get_command (langauge, name, command);
4890 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4891 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4892 return (mplist_key (plist) == Mtext
4893 ? (MText *) mplist_value (plist)
4899 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4901 MInputMethodInfo *im_info;
4905 im_info = get_im_info (language, name, Mnil, Mcommand);
4907 || ! im_info->configured_cmds
4908 || MPLIST_TAIL_P (im_info->configured_cmds))
4910 if (command == Mnil)
4911 return im_info->configured_cmds;
4912 return mplist__assq (im_info->configured_cmds, command);
4918 @brief Configure the key sequence of an input method command.
4920 The minput_config_command () function assigns a list of key
4921 sequences $KEYSEQLIST to the command $COMMAND of the input method
4922 specified by $LANGUAGE and $NAME.
4924 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4925 sequences, and each key sequence must be a plist of symbols.
4927 If $KEYSEQLIST is an empty plist, any configuration and
4928 customization of the command are cancelled, and default key
4929 sequences become effective.
4931 If $KEYSEQLIST is NULL, the configuration of the command is
4932 canceled, and the original key sequences (what saved in per-user
4933 customization file, or the default one) become effective.
4935 In the latter two cases, $COMMAND can be #Mnil to make all the
4936 commands of the input method the target of the operation.
4938 If $NAME is #Mnil, this function configures the key assignment of a
4939 global command, not that of a specific input method.
4941 The configuration takes effect for input methods opened or
4942 re-opened later in the current session. In order to make the
4943 configuration take effect for the future session, it must be saved
4944 in a per-user customization file by the function
4945 minput_save_config ().
4948 If the operation was successful, this function returns 0,
4949 otherwise returns -1. The operation fails in these cases:
4951 <li>$KEYSEQLIST is not in a valid form.
4952 <li>$COMMAND is not available for the input method.
4953 <li>$LANGUAGE and $NAME do not specify an existing input method.
4957 minput_get_commands (), minput_save_config ().
4960 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4962 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4963 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4964 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4966 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4967 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4969 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
4970 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
4972 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
4973 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
4974 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
4976 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
4977 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
4979 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4980 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4982 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4983 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4984 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
4985 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4989 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4991 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4992 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4993 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4997 minput_get_commands (), minput_save_config ().
5001 /* Add "C-x u" to the "start" command of Unicode input method. */
5003 MSymbol start_command = msymbol ("start");
5004 MSymbol unicode = msymbol ("unicode");
5005 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5007 /* At first get the current key-sequence assignment. */
5008 cmd = minput_get_command (Mt, unicode, start_command);
5011 /* The input method does not have the command "start". Here
5012 should come some error handling code. */
5014 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5015 Extract the part (KEY-SEQUENCE ...). */
5016 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5017 /* Copy it because we should not modify it directly. */
5018 key_seq_list = mplist_copy (plist);
5020 key_seq = mplist ();
5021 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5022 mplist_add (key_seq, Msymbol, msymbol ("u"));
5023 mplist_add (key_seq_list, Mplist, key_seq);
5024 m17n_object_unref (key_seq);
5026 minput_config_command (Mt, unicode, start_command, key_seq_list);
5027 m17n_object_unref (key_seq_list);
5032 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5035 MInputMethodInfo *im_info, *config;
5040 im_info = get_im_info (language, name, Mnil, Mcommand);
5042 MERROR (MERROR_IM, -1);
5043 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5045 || ! mplist__assq (im_info->configured_cmds, command)))
5046 MERROR (MERROR_IM, -1);
5047 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5049 MPLIST_DO (plist, keyseqlist)
5050 if (! check_command_keyseq (plist))
5051 MERROR (MERROR_IM, -1);
5054 config = get_config_info (im_info);
5057 if (! im_config_list)
5058 im_config_list = mplist ();
5059 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5060 config->cmds = mplist ();
5061 config->vars = mplist ();
5064 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5065 /* Nothing to do. */
5068 if (command == Mnil)
5072 /* Cancal the configuration. */
5073 if (MPLIST_TAIL_P (config->cmds))
5075 mplist_set (config->cmds, Mnil, NULL);
5079 /* Cancal the customization. */
5080 MInputMethodInfo *custom = get_custom_info (im_info);
5082 if (MPLIST_TAIL_P (config->cmds)
5083 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5084 /* Nothing to do. */
5086 mplist_set (config->cmds, Mnil, NULL);
5087 MPLIST_DO (plist, custom->cmds)
5089 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5091 mplist_add (plist, Msymbol, command);
5092 mplist_push (config->cmds, Mplist, plist);
5093 M17N_OBJECT_UNREF (plist);
5099 plist = mplist__assq (config->cmds, command);
5102 /* Cancel the configuration. */
5105 mplist__pop_unref (plist);
5107 else if (MPLIST_TAIL_P (keyseqlist))
5109 /* Cancel the customization. */
5110 MInputMethodInfo *custom = get_custom_info (im_info);
5111 int no_custom = (! custom || ! custom->cmds
5112 || ! mplist__assq (custom->cmds, command));
5118 mplist_add (config->cmds, Mplist, plist);
5119 M17N_OBJECT_UNREF (plist);
5120 plist = mplist_add (plist, Msymbol, command);
5125 mplist__pop_unref (plist);
5128 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5129 plist = MPLIST_NEXT (plist);
5130 mplist_set (plist, Mnil, NULL);
5140 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5141 if (! MPLIST_TAIL_P (plist))
5142 mplist_set (plist, Mnil, NULL);
5147 mplist_add (config->cmds, Mplist, plist);
5148 M17N_OBJECT_UNREF (plist);
5149 plist = mplist_add (plist, Msymbol, command);
5150 plist = MPLIST_NEXT (plist);
5152 MPLIST_DO (keyseqlist, keyseqlist)
5154 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5155 plist = mplist_add (plist, Mplist, pl);
5156 M17N_OBJECT_UNREF (pl);
5160 config_all_commands (im_info);
5161 im_info->tick = time (NULL);
5168 @brief Get information about input method variable(s).
5170 The minput_get_variable () function returns information about
5171 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5172 An input method variable controls behavior of an input method.
5174 There are two kinds of variables, global and local. A global
5175 variable has a global definition, and the description and the value
5176 may be inherited by a local variable. Each input method defines a
5177 local variable which has local value. It may also declare a
5178 local variable that inherits definition of a global variable of
5181 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5182 variable is returned. Otherwise information about a local variable
5185 If $VARIABLE is #Mnil, information about all variables is
5188 The return value is a @e well-formed plist (#m17nPlist) of this
5191 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5193 @c NAME is a symbol representing the variable name.
5195 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5196 variable has no description.
5198 @c STATUS is a symbol representing how the value is decided. The
5199 value is #Mnil (the default value), #Mcustomized (the value is
5200 customized by per-user customization file), or #Mconfigured (the
5201 value is set by the call of minput_config_variable ()). For a
5202 local variable only, it may also be #Minherited (the value is
5203 inherited from the corresponding global variable).
5205 @c VALUE is the initial value of the variable. If the key of this
5206 element is #Mt, the variable has no initial value. Otherwise, the
5207 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5210 @c VALID-VALUEs (if any) specify which values the variable can have.
5211 They have the same type (i.e. having the same key) as @c VALUE except
5212 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5213 may be a plist of two integers specifying the range of possible
5216 If there no @c VALID-VALUE, the variable can have any value as long
5217 as the type is the same as @c VALUE.
5219 If $VARIABLE is not #Mnil, the first element of the returned plist
5220 contains the information about $VARIABLE.
5224 If the requested information was found, a pointer to a non-empty
5225 plist is returned. As the plist is kept in the library, the
5226 caller must not modify nor free it.
5228 Otherwise (the specified input method or the specified variable
5229 does not exist), @c NULL is returned. */
5231 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5233 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5234 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5235 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5237 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5238 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5239 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5240 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5243 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5244 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5246 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5248 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5250 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5253 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5255 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5258 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5259 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5260 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5261 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5262 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5263 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5265 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5266 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5267 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5269 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5270 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5271 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5272 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5274 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5277 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5278 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5282 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5283 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5286 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5290 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5292 MInputMethodInfo *im_info;
5296 im_info = get_im_info (language, name, Mnil, Mvariable);
5297 if (! im_info || ! im_info->configured_vars)
5299 if (variable == Mnil)
5300 return im_info->configured_vars;
5301 return mplist__assq (im_info->configured_vars, variable);
5307 @brief Configure the value of an input method variable.
5309 The minput_config_variable () function assigns $VALUE to the
5310 variable $VARIABLE of the input method specified by $LANGUAGE and
5313 If $VALUE is a non-empty plist, it must be a plist of one element
5314 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5315 the corresponding type. That value is assigned to the variable.
5317 If $VALUE is an empty plist, any configuration and customization
5318 of the variable are canceled, and the default value is assigned to
5321 If $VALUE is NULL, the configuration of the variable is canceled,
5322 and the original value (what saved in per-user customization file,
5323 or the default value) is assigned to the variable.
5325 In the latter two cases, $VARIABLE can be #Mnil to make all the
5326 variables of the input method the target of the operation.
5328 If $NAME is #Mnil, this function configures the value of global
5329 variable, not that of a specific input method.
5331 The configuration takes effect for input methods opened or
5332 re-opened later in the current session. To make the configuration
5333 take effect for the future session, it must be saved in a per-user
5334 customization file by the function minput_save_config ().
5338 If the operation was successful, this function returns 0,
5339 otherwise returns -1. The operation fails in these cases:
5341 <li>$VALUE is not in a valid form, the type does not match the
5342 definition, or the value is our of range.
5343 <li>$VARIABLE is not available for the input method.
5344 <li>$LANGUAGE and $NAME do not specify an existing input method.
5348 minput_get_variable (), minput_save_config (). */
5350 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5352 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5353 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5355 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5356 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5357 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5359 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5360 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5362 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5363 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5365 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5366 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5368 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5369 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5371 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5372 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5373 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5374 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5378 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5380 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5381 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5382 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5386 minput_get_commands (), minput_save_config ().
5389 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5392 MInputMethodInfo *im_info, *config;
5397 im_info = get_im_info (language, name, Mnil, Mvariable);
5399 MERROR (MERROR_IM, -1);
5400 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5402 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5403 MERROR (MERROR_IM, -1);
5405 if (value && ! MPLIST_TAIL_P (value))
5407 plist = MPLIST_PLIST (plist);
5408 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5409 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5410 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5411 if (MPLIST_KEY (plist) != Mt
5412 && ! check_variable_value (value, plist))
5413 MERROR (MERROR_IM, -1);
5416 config = get_config_info (im_info);
5419 if (! im_config_list)
5420 im_config_list = mplist ();
5421 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5422 config->cmds = mplist ();
5423 config->vars = mplist ();
5426 if (! value && MPLIST_TAIL_P (config->vars))
5427 /* Nothing to do. */
5430 if (variable == Mnil)
5434 /* Cancel the configuration. */
5435 if (MPLIST_TAIL_P (config->vars))
5437 mplist_set (config->vars, Mnil, NULL);
5441 /* Cancel the customization. */
5442 MInputMethodInfo *custom = get_custom_info (im_info);
5444 if (MPLIST_TAIL_P (config->vars)
5445 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5446 /* Nothing to do. */
5448 mplist_set (config->vars, Mnil, NULL);
5449 MPLIST_DO (plist, custom->vars)
5451 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5453 mplist_add (plist, Msymbol, variable);
5454 mplist_push (config->vars, Mplist, plist);
5455 M17N_OBJECT_UNREF (plist);
5461 plist = mplist__assq (config->vars, variable);
5464 /* Cancel the configuration. */
5467 mplist__pop_unref (plist);
5469 else if (MPLIST_TAIL_P (value))
5471 /* Cancel the customization. */
5472 MInputMethodInfo *custom = get_custom_info (im_info);
5473 int no_custom = (! custom || ! custom->vars
5474 || ! mplist__assq (custom->vars, variable));
5480 mplist_add (config->vars, Mplist, plist);
5481 M17N_OBJECT_UNREF (plist);
5482 plist = mplist_add (plist, Msymbol, variable);
5487 mplist__pop_unref (plist);
5490 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5491 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5492 mplist_set (plist, Mnil ,NULL);
5500 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5501 if (! MPLIST_TAIL_P (plist))
5502 mplist_set (plist, Mnil, NULL);
5507 mplist_add (config->vars, Mplist, plist);
5508 M17N_OBJECT_UNREF (plist);
5509 plist = mplist_add (plist, Msymbol, variable);
5510 plist = MPLIST_NEXT (plist);
5512 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5515 config_all_variables (im_info);
5516 im_info->tick = time (NULL);
5523 @brief Get the name of per-user customization file.
5525 The minput_config_file () function returns the absolute path name
5526 of per-user customization file into which minput_save_config ()
5527 save configurations. It is usually @c "config.mic" under the
5528 directory @c ".m17n.d" of user's home directory. It is not assured
5529 that the file of the returned name exists nor is
5530 readable/writable. If minput_save_config () fails and returns -1,
5531 an application program might check the file, make it
5532 writable (if possible), and try minput_save_config () again.
5536 This function returns a string. As the string is kept in the
5537 library, the caller must not modify nor free it.
5540 minput_save_config ()
5543 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5545 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5546 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5547 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5548 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5549 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5550 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5551 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5556 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5557 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5560 minput_save_config ()
5564 minput_config_file ()
5568 return mdatabase__file (im_custom_mdb);
5574 @brief Save configurations in per-user customization file.
5576 The minput_save_config () function saves the configurations done
5577 so far in the current session into the per-user customization
5582 If the operation was successful, 1 is returned. If the per-user
5583 customization file is currently locked, 0 is returned. In that
5584 case, the caller may wait for a while and try again. If the
5585 configuration file is not writable, -1 is returned. In that case,
5586 the caller may check the name of the file by calling
5587 minput_config_file (), make it writable if possible, and try
5591 minput_config_file () */
5593 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5595 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5596 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5600 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5601 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5602 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5603 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5607 minput_config_file () */
5610 minput_save_config (void)
5612 MPlist *data, *tail, *plist, *p, *elt;
5616 ret = mdatabase__lock (im_custom_mdb);
5619 if (! im_config_list)
5621 update_custom_info ();
5622 if (! im_custom_list)
5623 im_custom_list = mplist ();
5625 /* At first, reflect configuration in customization. */
5626 MPLIST_DO (plist, im_config_list)
5628 MPlist *pl = MPLIST_PLIST (plist);
5629 MSymbol language, name, extra, command, variable;
5630 MInputMethodInfo *custom, *config;
5632 language = MPLIST_SYMBOL (pl);
5633 pl = MPLIST_NEXT (pl);
5634 name = MPLIST_SYMBOL (pl);
5635 pl = MPLIST_NEXT (pl);
5636 extra = MPLIST_SYMBOL (pl);
5637 pl = MPLIST_NEXT (pl);
5638 config = MPLIST_VAL (pl);
5639 custom = get_custom_info (config);
5641 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5643 MPLIST_DO (pl, config->cmds)
5645 elt = MPLIST_PLIST (pl);
5646 command = MPLIST_SYMBOL (elt);
5648 p = mplist__assq (custom->cmds, command);
5650 custom->cmds = mplist (), p = NULL;
5651 elt = MPLIST_NEXT (elt);
5654 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5655 mplist_set (p, Mnil, NULL);
5660 mplist_add (custom->cmds, Mplist, p);
5661 M17N_OBJECT_UNREF (p);
5662 mplist_add (p, Msymbol, command);
5663 p = mplist_add (p, Msymbol, Mnil);
5664 p = MPLIST_NEXT (p);
5666 mplist__conc (p, elt);
5669 MPLIST_DO (pl, config->vars)
5671 elt = MPLIST_PLIST (pl);
5672 variable = MPLIST_SYMBOL (elt);
5674 p = mplist__assq (custom->vars, variable);
5676 custom->vars = mplist (), p = NULL;
5677 elt = MPLIST_NEXT (elt);
5680 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5681 mplist_set (p, Mnil, NULL);
5686 mplist_add (custom->vars, Mplist, p);
5687 M17N_OBJECT_UNREF (p);
5688 mplist_add (p, Msymbol, variable);
5689 p = mplist_add (p, Msymbol, Mnil);
5690 p = MPLIST_NEXT (p);
5692 mplist__conc (p, elt);
5695 free_im_list (im_config_list);
5696 im_config_list = NULL;
5698 /* Next, reflect customization to the actual plist to be written. */
5699 data = tail = mplist ();
5700 MPLIST_DO (plist, im_custom_list)
5702 MPlist *pl = MPLIST_PLIST (plist);
5703 MSymbol language, name, extra;
5704 MInputMethodInfo *custom, *im_info;
5706 language = MPLIST_SYMBOL (pl);
5707 pl = MPLIST_NEXT (pl);
5708 name = MPLIST_SYMBOL (pl);
5709 pl = MPLIST_NEXT (pl);
5710 extra = MPLIST_SYMBOL (pl);
5711 pl = MPLIST_NEXT (pl);
5712 custom = MPLIST_VAL (pl);
5713 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5714 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5716 im_info = lookup_im_info (im_info_list, language, name, extra);
5720 config_all_commands (im_info);
5722 config_all_variables (im_info);
5726 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5728 MPLIST_DO (p, custom->cmds)
5729 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5731 if (! MPLIST_TAIL_P (p))
5735 mplist_add (elt, Mplist, pl);
5736 M17N_OBJECT_UNREF (pl);
5737 pl = mplist_add (pl, Msymbol, Mcommand);
5738 MPLIST_DO (p, custom->cmds)
5739 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5740 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5743 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5745 MPLIST_DO (p, custom->vars)
5746 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5748 if (! MPLIST_TAIL_P (p))
5753 mplist_add (elt, Mplist, pl);
5754 M17N_OBJECT_UNREF (pl);
5755 pl = mplist_add (pl, Msymbol, Mvariable);
5756 MPLIST_DO (p, custom->vars)
5757 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5758 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5764 mplist_push (elt, Mplist, pl);
5765 M17N_OBJECT_UNREF (pl);
5766 pl = mplist_add (pl, Msymbol, Minput_method);
5767 pl = mplist_add (pl, Msymbol, language);
5768 pl = mplist_add (pl, Msymbol, name);
5770 pl = mplist_add (pl, Msymbol, extra);
5771 tail = mplist_add (tail, Mplist, elt);
5772 M17N_OBJECT_UNREF (elt);
5776 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5777 ret = mdatabase__save (im_custom_mdb, data);
5778 mdatabase__unlock (im_custom_mdb);
5779 M17N_OBJECT_UNREF (data);
5780 return (ret < 0 ? -1 : 1);
5787 @name Obsolete functions
5790 @name Obsolete ¤Ê´Ø¿ô
5796 @brief Get a list of variables of an input method (obsolete).
5798 This function is obsolete. Use minput_get_variable () instead.
5800 The minput_get_variables () function returns a plist (#MPlist) of
5801 variables used to control the behavior of the input method
5802 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5803 (#m17nPlist) of the following format:
5806 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5807 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5811 @c VARNAME is a symbol representing the variable name.
5813 @c DOC-MTEXT is an M-text describing the variable.
5815 @c DEFAULT-VALUE is the default value of the variable. It is a
5816 symbol, integer, or M-text.
5818 @c VALUEs (if any) specifies the possible values of the variable.
5819 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5820 @c TO), where @c FROM and @c TO specifies a range of possible
5823 For instance, suppose an input method has the variables:
5825 @li name:intvar, description:"value is an integer",
5826 initial value:0, value-range:0..3,10,20
5828 @li name:symvar, description:"value is a symbol",
5829 initial value:nil, value-range:a, b, c, nil
5831 @li name:txtvar, description:"value is an M-text",
5832 initial value:empty text, no value-range (i.e. any text)
5834 Then, the returned plist is as follows.
5837 (intvar ("value is an integer" 0 (0 3) 10 20)
5838 symvar ("value is a symbol" nil a b c nil)
5839 txtvar ("value is an M-text" ""))
5843 If the input method uses any variables, a pointer to #MPlist is
5844 returned. As the plist is kept in the library, the caller must not
5845 modify nor free it. If the input method does not use any
5846 variable, @c NULL is returned. */
5848 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5850 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5851 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5852 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5856 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5857 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5861 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5863 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5865 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5868 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5869 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5870 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5872 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5874 @li name:intvar, ÀâÌÀ:"value is an integer",
5875 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5877 @li name:symvar, ÀâÌÀ:"value is a symbol",
5878 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5880 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5881 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5883 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5886 (intvar ("value is an integer" 0 (0 3) 10 20)
5887 symvar ("value is a symbol" nil a b c nil)
5888 txtvar ("value is an M-text" ""))
5892 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5893 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5894 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5897 minput_get_variables (MSymbol language, MSymbol name)
5899 MInputMethodInfo *im_info;
5904 im_info = get_im_info (language, name, Mnil, Mvariable);
5905 if (! im_info || ! im_info->configured_vars)
5908 M17N_OBJECT_UNREF (im_info->bc_vars);
5909 im_info->bc_vars = mplist ();
5910 MPLIST_DO (vars, im_info->configured_vars)
5912 MPlist *plist = MPLIST_PLIST (vars);
5913 MPlist *elt = mplist ();
5915 mplist_push (im_info->bc_vars, Mplist, elt);
5916 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5917 elt = MPLIST_NEXT (elt);
5918 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5919 M17N_OBJECT_UNREF (elt);
5921 return im_info->bc_vars;
5927 @brief Set the initial value of an input method variable.
5929 The minput_set_variable () function sets the initial value of
5930 input method variable $VARIABLE to $VALUE for the input method
5931 specified by $LANGUAGE and $NAME.
5933 By default, the initial value is 0.
5935 This setting gets effective in a newly opened input method.
5938 If the operation was successful, 0 is returned. Otherwise -1 is
5939 returned, and #merror_code is set to #MERROR_IM. */
5941 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5943 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5944 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5945 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5947 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5949 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5952 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5953 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5956 minput_set_variable (MSymbol language, MSymbol name,
5957 MSymbol variable, void *value)
5960 MInputMethodInfo *im_info;
5965 if (variable == Mnil)
5966 MERROR (MERROR_IM, -1);
5967 plist = minput_get_variable (language, name, variable);
5968 plist = MPLIST_PLIST (plist);
5969 plist = MPLIST_NEXT (plist);
5971 mplist_add (pl, MPLIST_KEY (plist), value);
5972 ret = minput_config_variable (language, name, variable, pl);
5973 M17N_OBJECT_UNREF (pl);
5976 im_info = get_im_info (language, name, Mnil, Mvariable);
5985 @brief Get information about input method commands.
5987 The minput_get_commands () function returns information about
5988 input method commands of the input method specified by $LANGUAGE
5989 and $NAME. An input method command is a pseudo key event to which
5990 one or more actual input key sequences are assigned.
5992 There are two kinds of commands, global and local. Global
5993 commands are used by multiple input methods for the same purpose,
5994 and have global key assignments. Local commands are used only by
5995 a specific input method, and have only local key assignments.
5997 Each input method may locally change key assignments for global
5998 commands. The global key assignment for a global command is
5999 effective only when the current input method does not have local
6000 key assignments for that command.
6002 If $NAME is #Mnil, information about global commands is returned.
6003 In this case $LANGUAGE is ignored.
6005 If $NAME is not #Mnil, information about those commands that have
6006 local key assignments in the input method specified by $LANGUAGE
6007 and $NAME is returned.
6010 If no input method commands are found, this function returns @c NULL.
6012 Otherwise, a pointer to a plist is returned. The key of each
6013 element in the plist is a symbol representing a command, and the
6014 value is a plist of the form COMMAND-INFO described below.
6016 The first element of COMMAND-INFO has the key #Mtext, and the
6017 value is an M-text describing the command.
6019 If there are no more elements, that means no key sequences are
6020 assigned to the command. Otherwise, each of the remaining
6021 elements has the key #Mplist, and the value is a plist whose keys are
6022 #Msymbol and values are symbols representing input keys, which are
6023 currently assigned to the command.
6025 As the returned plist is kept in the library, the caller must not
6026 modify nor free it. */
6028 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6030 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6031 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6032 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6033 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6035 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6036 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6037 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6038 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6040 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6041 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6042 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6045 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6046 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6048 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6049 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6053 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6055 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6056 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6057 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6059 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6060 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6061 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6064 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6065 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6066 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6067 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6068 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6070 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6071 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6074 minput_get_commands (MSymbol language, MSymbol name)
6076 MInputMethodInfo *im_info;
6081 im_info = get_im_info (language, name, Mnil, Mcommand);
6082 if (! im_info || ! im_info->configured_vars)
6084 M17N_OBJECT_UNREF (im_info->bc_cmds);
6085 im_info->bc_cmds = mplist ();
6086 MPLIST_DO (cmds, im_info->configured_cmds)
6088 MPlist *plist = MPLIST_PLIST (cmds);
6089 MPlist *elt = mplist ();
6091 mplist_push (im_info->bc_cmds, Mplist, elt);
6092 mplist_add (elt, MPLIST_SYMBOL (plist),
6093 mplist_copy (MPLIST_NEXT (plist)));
6094 M17N_OBJECT_UNREF (elt);
6096 return im_info->bc_cmds;
6102 @brief Assign a key sequence to an input method command (obsolete).
6104 This function is obsolete. Use minput_config_command () instead.
6106 The minput_assign_command_keys () function assigns input key
6107 sequence $KEYSEQ to input method command $COMMAND for the input
6108 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6109 key sequence is assigned globally no matter what $LANGUAGE is.
6110 Otherwise the key sequence is assigned locally.
6112 Each element of $KEYSEQ must have the key $Msymbol and the value
6113 must be a symbol representing an input key.
6115 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6116 globally or locally.
6118 This assignment gets effective in a newly opened input method.
6121 If the operation was successful, 0 is returned. Otherwise -1 is
6122 returned, and #merror_code is set to #MERROR_IM. */
6124 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6126 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6127 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6128 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6129 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6130 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6132 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6133 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6135 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6136 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6138 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6141 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6142 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6145 minput_assign_command_keys (MSymbol language, MSymbol name,
6146 MSymbol command, MPlist *keyseq)
6152 if (command == Mnil)
6153 MERROR (MERROR_IM, -1);
6158 if (! check_command_keyseq (keyseq))
6159 MERROR (MERROR_IM, -1);
6161 mplist_add (plist, Mplist, keyseq);
6166 ret = minput_config_command (language, name, command, keyseq);
6167 M17N_OBJECT_UNREF (keyseq);
6174 @brief Call a callback function
6176 The minput_callback () functions calls a callback function
6177 $COMMAND assigned for the input context $IC. The caller must set
6178 specific elements in $IC->plist if the callback function requires.
6181 If there exists a specified callback function, 0 is returned.
6182 Otherwise -1 is returned. By side effects, $IC->plist may be
6186 minput_callback (MInputContext *ic, MSymbol command)
6188 MInputCallbackFunc func;
6190 if (! ic->im->driver.callback_list)
6192 func = ((MInputCallbackFunc)
6193 mplist_get_func (ic->im->driver.callback_list, command));
6196 (func) (ic, command);
6203 /*** @addtogroup m17nDebug */
6209 @brief Dump an input method.
6211 The mdebug_dump_im () function prints the input method $IM in a
6212 human readable way to the stderr. $INDENT specifies how many
6213 columns to indent the lines but the first one.
6216 This function returns $IM. */
6218 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6220 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6221 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6224 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6227 mdebug_dump_im (MInputMethod *im, int indent)
6229 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6232 prefix = (char *) alloca (indent + 1);
6233 memset (prefix, 32, indent);
6234 prefix[indent] = '\0';
6236 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6237 msymbol_name (im->name));
6238 mdebug_dump_mtext (im_info->title, 0, 0);
6239 if (im->name != Mnil)
6243 MPLIST_DO (state, im_info->states)
6245 fprintf (stderr, "\n%s ", prefix);
6246 dump_im_state (MPLIST_VAL (state), indent + 2);
6249 fprintf (stderr, ")");