1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mpop = msymbol ("pop");
406 Mundo = msymbol ("undo");
407 Mcall = msymbol ("call");
408 Mshift = msymbol ("shift");
409 Mselect = msymbol ("select");
410 Mshow = msymbol ("show");
411 Mhide = msymbol ("hide");
412 Mcommit = msymbol ("commit");
413 Munhandle = msymbol ("unhandle");
414 Mset = msymbol ("set");
415 Madd = msymbol ("add");
416 Msub = msymbol ("sub");
417 Mmul = msymbol ("mul");
418 Mdiv = msymbol ("div");
419 Mequal = msymbol ("=");
420 Mless = msymbol ("<");
421 Mgreater = msymbol (">");
422 Mless_equal = msymbol ("<=");
423 Mgreater_equal = msymbol (">=");
424 Mcond = msymbol ("cond");
425 Mplus = msymbol ("+");
426 Mminus = msymbol ("-");
427 Mstar = msymbol ("*");
428 Mslash = msymbol ("/");
429 Mand = msymbol ("&");
431 Mnot = msymbol ("!");
433 Mat_reload = msymbol ("@reload");
435 Mcandidates_group_size = msymbol ("candidates-group-size");
436 Mcandidates_charset = msymbol ("candidates-charset");
438 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
439 Mcandidate_index = msymbol (" candidate-index");
441 Minit = msymbol ("init");
442 Mfini = msymbol ("fini");
444 Mdescription = msymbol ("description");
445 Mcommand = msymbol ("command");
446 Mvariable = msymbol ("variable");
447 Mglobal = msymbol ("global");
448 Mconfig = msymbol ("config");
449 M_gettext = msymbol ("_");
451 load_im_info_keys = mplist ();
452 mplist_add (load_im_info_keys, Mstate, Mnil);
453 mplist_push (load_im_info_keys, Mmap, Mnil);
455 im_info_list = mplist ();
456 im_config_list = im_custom_list = NULL;
457 im_custom_mdb = NULL;
458 update_custom_info ();
460 update_global_info ();
462 fully_initialized = 1;
465 #define MINPUT__INIT() \
467 if (! fully_initialized) \
468 fully_initialize (); \
473 marker_code (MSymbol sym, int surrounding)
479 name = MSYMBOL_NAME (sym);
480 return (name[0] != '@' ? -1
481 : (((name[1] >= '0' && name[1] <= '9')
482 || name[1] == '<' || name[1] == '>' || name[1] == '='
483 || name[1] == '[' || name[1] == ']'
485 && name[2] == '\0') ? name[1]
486 : (name[1] != '+' && name[1] != '-') ? -1
487 : (name[2] == '\0' || surrounding) ? name[1]
492 /* Return a plist containing an integer value of VAR. */
495 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
497 MPlist *plist = mplist__assq (ic_info->vars, var);
501 plist = MPLIST_PLIST (plist);
502 return MPLIST_NEXT (plist);
506 mplist_push (ic_info->vars, Mplist, plist);
507 M17N_OBJECT_UNREF (plist);
508 plist = mplist_add (plist, Msymbol, var);
509 plist = mplist_add (plist, Minteger, (void *) 0);
514 get_surrounding_text (MInputContext *ic, int len)
518 mplist_push (ic->plist, Minteger, (void *) len);
519 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
520 && MPLIST_MTEXT_P (ic->plist))
521 mt = MPLIST_MTEXT (ic->plist);
522 mplist_pop (ic->plist);
527 delete_surrounding_text (MInputContext *ic, int pos)
529 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
531 mplist_push (ic->plist, Minteger, (void *) pos);
532 minput_callback (ic, Minput_delete_surrounding_text);
533 mplist_pop (ic->plist);
536 M17N_OBJECT_UNREF (ic_info->preceding_text);
537 ic_info->preceding_text = NULL;
541 M17N_OBJECT_UNREF (ic_info->following_text);
542 ic_info->following_text = NULL;
547 get_preceding_char (MInputContext *ic, int pos)
549 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
553 if (pos && ic_info->preceding_text)
555 len = mtext_nchars (ic_info->preceding_text);
557 return mtext_ref_char (ic_info->preceding_text, len - pos);
559 mt = get_surrounding_text (ic, - pos);
562 len = mtext_nchars (mt);
563 if (ic_info->preceding_text)
565 if (mtext_nchars (ic_info->preceding_text) < len)
567 M17N_OBJECT_UNREF (ic_info->preceding_text);
568 ic_info->preceding_text = mt;
571 M17N_OBJECT_UNREF (mt);
574 ic_info->preceding_text = mt;
577 return mtext_ref_char (ic_info->preceding_text, len - pos);
581 get_following_char (MInputContext *ic, int pos)
583 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
587 if (ic_info->following_text)
589 len = mtext_nchars (ic_info->following_text);
591 return mtext_ref_char (ic_info->following_text, pos);
593 mt = get_surrounding_text (ic, pos + 1);
596 len = mtext_nchars (mt);
597 if (ic_info->following_text)
599 if (mtext_nchars (ic_info->following_text) < len)
601 M17N_OBJECT_UNREF (ic_info->following_text);
602 ic_info->following_text = mt;
605 M17N_OBJECT_UNREF (mt);
608 ic_info->following_text = mt;
611 return mtext_ref_char (ic_info->following_text, pos);
615 surrounding_pos (MSymbol sym)
621 name = MSYMBOL_NAME (sym);
623 && (name[1] == '-' || name[1] == '+')
624 && name[2] >= '1' && name[2] <= '9')
625 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
630 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
632 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
634 MText *preedit = ic->preedit;
635 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));
645 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
648 return ic_info->key_head;
649 if ((code == '-' || code == '+'))
651 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
655 pos = atoi (name + 1);
657 return get_preceding_char (ic, 0);
659 pos = ic->cursor_pos + pos;
661 pos = ic->cursor_pos + pos - 1;
664 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
665 return mtext_ref_char (ic->produced,
666 mtext_len (ic->produced) + pos);
667 return get_preceding_char (ic, - pos);
670 return get_following_char (ic, pos - len);
673 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
675 else if (code >= '0' && code <= '9')
677 else if (code == '=')
678 pos = ic->cursor_pos;
679 else if (code == '[')
680 pos = ic->cursor_pos - 1;
681 else if (code == ']')
682 pos = ic->cursor_pos + 1;
683 else if (code == '<')
685 else if (code == '>')
687 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
691 parse_expression (MPlist *plist)
695 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
697 if (! MPLIST_PLIST_P (plist))
699 plist = MPLIST_PLIST (plist);
700 op = MPLIST_SYMBOL (plist);
701 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
702 && op != Mand && op != Mor && op != Mnot
703 && op != Mless && op != Mgreater && op != Mequal
704 && op != Mless_equal && op != Mgreater_equal)
705 MERROR (MERROR_IM, -1);
706 MPLIST_DO (plist, MPLIST_NEXT (plist))
707 if (parse_expression (plist) < 0)
713 resolve_expression (MInputContext *ic, MPlist *plist)
718 if (MPLIST_INTEGER_P (plist))
719 return MPLIST_INTEGER (plist);
720 if (MPLIST_SYMBOL_P (plist))
721 return integer_value (ic, plist, 1);
722 if (! MPLIST_PLIST_P (plist))
724 plist = MPLIST_PLIST (plist);
725 if (! MPLIST_SYMBOL_P (plist))
727 op = MPLIST_SYMBOL (plist);
728 plist = MPLIST_NEXT (plist);
729 val = resolve_expression (ic, plist);
731 MPLIST_DO (plist, MPLIST_NEXT (plist))
732 val += resolve_expression (ic, plist);
733 else if (op == Mminus)
734 MPLIST_DO (plist, MPLIST_NEXT (plist))
735 val -= resolve_expression (ic, plist);
736 else if (op == Mstar)
737 MPLIST_DO (plist, MPLIST_NEXT (plist))
738 val *= resolve_expression (ic, plist);
739 else if (op == Mslash)
740 MPLIST_DO (plist, MPLIST_NEXT (plist))
741 val /= resolve_expression (ic, plist);
743 MPLIST_DO (plist, MPLIST_NEXT (plist))
744 val &= resolve_expression (ic, plist);
746 MPLIST_DO (plist, MPLIST_NEXT (plist))
747 val |= resolve_expression (ic, plist);
750 else if (op == Mless)
751 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
752 else if (op == Mequal)
753 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
754 else if (op == Mgreater)
755 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
756 else if (op == Mless_equal)
757 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
758 else if (op == Mgreater_equal)
759 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
763 /* Parse PLIST as an action list. PLIST should have this form:
764 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
765 Return 0 if successfully parsed, otherwise return -1. */
768 parse_action_list (MPlist *plist, MPlist *macros)
770 MPLIST_DO (plist, plist)
772 if (MPLIST_MTEXT_P (plist))
774 /* This is a short form of (insert MTEXT). */
775 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
776 MERROR (MERROR_IM, -1); */
778 else if (MPLIST_PLIST_P (plist)
779 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
780 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
784 /* This is a short form of (insert (GROUPS *)). */
785 MPLIST_DO (pl, MPLIST_PLIST (plist))
787 if (MPLIST_PLIST_P (pl))
791 MPLIST_DO (elt, MPLIST_PLIST (pl))
792 if (! MPLIST_MTEXT_P (elt)
793 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
794 MERROR (MERROR_IM, -1);
798 if (! MPLIST_MTEXT_P (pl)
799 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
800 MERROR (MERROR_IM, -1);
804 else if (MPLIST_INTEGER_P (plist))
806 int c = MPLIST_INTEGER (plist);
808 if (c < 0 || c > MCHAR_MAX)
809 MERROR (MERROR_IM, -1);
811 else if (MPLIST_PLIST_P (plist)
812 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
814 MPlist *pl = MPLIST_PLIST (plist);
815 MSymbol action_name = MPLIST_SYMBOL (pl);
817 pl = MPLIST_NEXT (pl);
819 if (action_name == M_candidates)
821 /* This is an already regularised action. */
824 if (action_name == Minsert)
826 if (MPLIST_MTEXT_P (pl))
828 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
829 MERROR (MERROR_IM, -1);
831 else if (MPLIST_INTEGER_P (pl))
833 int c = MPLIST_INTEGER (pl);
835 if (c < 0 || c > MCHAR_MAX)
836 MERROR (MERROR_IM, -1);
838 else if (MPLIST_PLIST_P (pl))
840 MPLIST_DO (pl, MPLIST_PLIST (pl))
842 if (MPLIST_PLIST_P (pl))
846 MPLIST_DO (elt, MPLIST_PLIST (pl))
847 if (! MPLIST_MTEXT_P (elt)
848 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
849 MERROR (MERROR_IM, -1);
853 if (! MPLIST_MTEXT_P (pl)
854 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
855 MERROR (MERROR_IM, -1);
859 else if (! MPLIST_SYMBOL_P (pl))
860 MERROR (MERROR_IM, -1);
862 else if (action_name == Mselect
863 || action_name == Mdelete
864 || action_name == Mmove)
866 if (parse_expression (pl) < 0)
869 else if (action_name == Mmark
870 || action_name == Mcall
871 || action_name == Mshift)
873 if (! MPLIST_SYMBOL_P (pl))
874 MERROR (MERROR_IM, -1);
876 else if (action_name == Mundo)
878 if (! MPLIST_TAIL_P (pl))
880 if (! MPLIST_SYMBOL_P (pl)
881 && ! MPLIST_INTEGER_P (pl))
882 MERROR (MERROR_IM, -1);
885 else if (action_name == Mpushback)
887 if (MPLIST_MTEXT_P (pl))
889 MText *mt = MPLIST_MTEXT (pl);
891 if (mtext_nchars (mt) != mtext_nbytes (mt))
892 MERROR (MERROR_IM, -1);
894 else if (MPLIST_PLIST_P (pl))
898 MPLIST_DO (p, MPLIST_PLIST (pl))
899 if (! MPLIST_SYMBOL_P (p))
900 MERROR (MERROR_IM, -1);
902 else if (! MPLIST_INTEGER_P (pl))
903 MERROR (MERROR_IM, -1);
905 else if (action_name == Mset || action_name == Madd
906 || action_name == Msub || action_name == Mmul
907 || action_name == Mdiv)
909 if (! MPLIST_SYMBOL_P (pl))
910 MERROR (MERROR_IM, -1);
911 if (parse_expression (MPLIST_NEXT (pl)) < 0)
914 else if (action_name == Mequal || action_name == Mless
915 || action_name == Mgreater || action_name == Mless_equal
916 || action_name == Mgreater_equal)
918 if (parse_expression (pl) < 0
919 || parse_expression (MPLIST_NEXT (pl)) < 0)
921 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
922 if (! MPLIST_PLIST_P (pl))
923 MERROR (MERROR_IM, -1);
924 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
925 MERROR (MERROR_IM, -1);
926 pl = MPLIST_NEXT (pl);
927 if (MPLIST_PLIST_P (pl)
928 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
929 MERROR (MERROR_IM, -1);
931 else if (action_name == Mshow || action_name == Mhide
932 || action_name == Mcommit || action_name == Munhandle
933 || action_name == Mpop)
935 else if (action_name == Mcond)
938 if (! MPLIST_PLIST_P (pl))
939 MERROR (MERROR_IM, -1);
941 else if (! macros || ! mplist_get (macros, action_name))
942 MERROR (MERROR_IM, -1);
944 else if (! MPLIST_SYMBOL_P (plist))
945 MERROR (MERROR_IM, -1);
952 resolve_command (MPlist *cmds, MSymbol command)
956 if (! cmds || ! (plist = mplist__assq (cmds, command)))
958 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
959 plist = MPLIST_NEXT (plist);
960 plist = MPLIST_NEXT (plist);
961 plist = MPLIST_NEXT (plist);
965 /* Load a translation into MAP from PLIST.
967 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
970 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
971 MPlist *branch_actions, MPlist *macros)
976 if (MPLIST_MTEXT_P (keylist))
978 MText *mt = MPLIST_MTEXT (keylist);
980 len = mtext_nchars (mt);
981 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
983 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
984 for (i = 0; i < len; i++)
985 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
991 if (MFAILP (MPLIST_PLIST_P (keylist)))
993 elt = MPLIST_PLIST (keylist);
994 len = MPLIST_LENGTH (elt);
995 if (MFAILP (len > 0))
997 keyseq = (MSymbol *) alloca (sizeof (int) * len);
998 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1000 if (MPLIST_INTEGER_P (elt))
1002 int c = MPLIST_INTEGER (elt);
1004 if (MFAILP (c >= 0 && c < 0x100))
1006 keyseq[i] = one_char_symbol[c];
1010 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1012 keyseq[i] = MPLIST_SYMBOL (elt);
1017 for (i = 0; i < len; i++)
1019 MIMMap *deeper = NULL;
1022 deeper = mplist_get (map->submaps, keyseq[i]);
1024 map->submaps = mplist ();
1027 /* Fixme: It is better to make all deeper maps at once. */
1028 MSTRUCT_CALLOC (deeper, MERROR_IM);
1029 mplist_put (map->submaps, keyseq[i], deeper);
1034 /* We reach a terminal map. */
1035 if (map->map_actions
1036 || map->branch_actions)
1037 /* This map is already defined. We avoid overriding it. */
1040 if (! MPLIST_TAIL_P (map_actions))
1042 if (parse_action_list (map_actions, macros) < 0)
1043 MERROR (MERROR_IM, -1);
1044 map->map_actions = map_actions;
1048 map->branch_actions = branch_actions;
1049 M17N_OBJECT_REF (branch_actions);
1055 /* Load a branch from PLIST into MAP. PLIST has this form:
1056 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1059 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1062 MPlist *branch_actions;
1064 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1066 map_name = MPLIST_SYMBOL (plist);
1067 plist = MPLIST_NEXT (plist);
1068 if (MPLIST_TAIL_P (plist))
1069 branch_actions = NULL;
1070 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1073 branch_actions = plist;
1074 if (map_name == Mnil)
1076 map->branch_actions = branch_actions;
1078 M17N_OBJECT_REF (branch_actions);
1080 else if (map_name == Mt)
1082 map->map_actions = branch_actions;
1084 M17N_OBJECT_REF (branch_actions);
1086 else if (im_info->maps)
1088 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1089 if (! plist && im_info->configured_vars)
1091 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1093 if (p && MPLIST_PLIST_P (p))
1095 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1096 if (MPLIST_SYMBOL_P (p))
1097 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1102 MPLIST_DO (plist, plist)
1104 MPlist *keylist, *map_actions;
1106 if (! MPLIST_PLIST_P (plist))
1107 MERROR (MERROR_IM, -1);
1108 keylist = MPLIST_PLIST (plist);
1109 map_actions = MPLIST_NEXT (keylist);
1110 if (MPLIST_SYMBOL_P (keylist))
1112 MSymbol command = MPLIST_SYMBOL (keylist);
1115 if (MFAILP (command != Mat_reload))
1117 pl = resolve_command (im_info->configured_cmds, command);
1121 load_translation (map, pl, map_actions, branch_actions,
1125 load_translation (map, keylist, map_actions, branch_actions,
1134 /* Load a macro from PLIST into IM_INFO->macros.
1135 PLIST has this from:
1136 PLIST ::= ( MACRO-NAME ACTION * )
1137 IM_INFO->macros is a plist of macro names vs action list. */
1140 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1145 if (! MPLIST_SYMBOL_P (plist))
1146 MERROR (MERROR_IM, -1);
1147 name = MPLIST_SYMBOL (plist);
1148 plist = MPLIST_NEXT (plist);
1149 if (MPLIST_TAIL_P (plist)
1150 || parse_action_list (plist, im_info->macros) < 0)
1151 MERROR (MERROR_IM, -1);
1152 pl = mplist_get (im_info->macros, name);
1153 M17N_OBJECT_UNREF (pl);
1154 mplist_put (im_info->macros, name, plist);
1155 M17N_OBJECT_REF (plist);
1159 /* Load an external module from PLIST into IM_INFO->externals.
1160 PLIST has this form:
1161 PLIST ::= ( MODULE-NAME FUNCTION * )
1162 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1165 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1170 MIMExternalModule *external;
1174 if (MPLIST_MTEXT_P (plist))
1175 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1176 else if (MPLIST_SYMBOL_P (plist))
1177 module = MPLIST_SYMBOL (plist);
1178 module_file = alloca (strlen (MSYMBOL_NAME (module))
1179 + strlen (DLOPEN_SHLIB_EXT) + 1);
1180 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1182 handle = dlopen (module_file, RTLD_NOW);
1183 if (MFAILP (handle))
1185 fprintf (stderr, "%s\n", dlerror ());
1188 func_list = mplist ();
1189 MPLIST_DO (plist, MPLIST_NEXT (plist))
1191 if (! MPLIST_SYMBOL_P (plist))
1192 MERROR_GOTO (MERROR_IM, err_label);
1193 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1196 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1199 MSTRUCT_MALLOC (external, MERROR_IM);
1200 external->handle = handle;
1201 external->func_list = func_list;
1202 mplist_add (im_info->externals, module, external);
1207 M17N_OBJECT_UNREF (func_list);
1212 free_map (MIMMap *map, int top)
1217 M17N_OBJECT_UNREF (map->map_actions);
1220 MPLIST_DO (plist, map->submaps)
1221 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1222 M17N_OBJECT_UNREF (map->submaps);
1224 M17N_OBJECT_UNREF (map->branch_actions);
1229 free_state (void *object)
1231 MIMState *state = object;
1233 M17N_OBJECT_UNREF (state->title);
1235 free_map (state->map, 1);
1239 /** Load a state from PLIST into a newly allocated state object.
1240 PLIST has this form:
1241 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1242 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1243 Return the state object. */
1246 load_state (MInputMethodInfo *im_info, MPlist *plist)
1250 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1252 M17N_OBJECT (state, free_state, MERROR_IM);
1253 state->name = MPLIST_SYMBOL (plist);
1254 plist = MPLIST_NEXT (plist);
1255 if (MPLIST_MTEXT_P (plist))
1257 state->title = MPLIST_MTEXT (plist);
1258 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1259 Mlanguage, im_info->language);
1260 M17N_OBJECT_REF (state->title);
1261 plist = MPLIST_NEXT (plist);
1263 MSTRUCT_CALLOC (state->map, MERROR_IM);
1264 MPLIST_DO (plist, plist)
1266 if (MFAILP (MPLIST_PLIST_P (plist)))
1268 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1273 /* Return a newly created IM_INFO for an input method specified by
1274 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1276 static MInputMethodInfo *
1277 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1280 MInputMethodInfo *im_info;
1283 if (name == Mnil && extra == Mnil)
1284 language = Mt, extra = Mglobal;
1285 MSTRUCT_CALLOC (im_info, MERROR_IM);
1287 im_info->language = language;
1288 im_info->name = name;
1289 im_info->extra = extra;
1292 mplist_add (plist, Mplist, elt);
1293 M17N_OBJECT_UNREF (elt);
1294 elt = mplist_add (elt, Msymbol, language);
1295 elt = mplist_add (elt, Msymbol, name);
1296 elt = mplist_add (elt, Msymbol, extra);
1297 mplist_add (elt, Mt, im_info);
1303 fini_im_info (MInputMethodInfo *im_info)
1307 M17N_OBJECT_UNREF (im_info->cmds);
1308 M17N_OBJECT_UNREF (im_info->configured_cmds);
1309 M17N_OBJECT_UNREF (im_info->bc_cmds);
1310 M17N_OBJECT_UNREF (im_info->vars);
1311 M17N_OBJECT_UNREF (im_info->configured_vars);
1312 M17N_OBJECT_UNREF (im_info->bc_vars);
1313 M17N_OBJECT_UNREF (im_info->description);
1314 M17N_OBJECT_UNREF (im_info->title);
1315 if (im_info->states)
1317 MPLIST_DO (plist, im_info->states)
1319 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1321 M17N_OBJECT_UNREF (state);
1323 M17N_OBJECT_UNREF (im_info->states);
1326 if (im_info->macros)
1328 MPLIST_DO (plist, im_info->macros)
1329 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1330 M17N_OBJECT_UNREF (im_info->macros);
1333 if (im_info->externals)
1335 MPLIST_DO (plist, im_info->externals)
1337 MIMExternalModule *external = MPLIST_VAL (plist);
1339 dlclose (external->handle);
1340 M17N_OBJECT_UNREF (external->func_list);
1342 MPLIST_KEY (plist) = Mt;
1344 M17N_OBJECT_UNREF (im_info->externals);
1348 MPLIST_DO (plist, im_info->maps)
1350 MPlist *p = MPLIST_PLIST (plist);
1352 M17N_OBJECT_UNREF (p);
1354 M17N_OBJECT_UNREF (im_info->maps);
1361 free_im_info (MInputMethodInfo *im_info)
1363 fini_im_info (im_info);
1368 free_im_list (MPlist *plist)
1372 MPLIST_DO (pl, plist)
1374 MInputMethodInfo *im_info;
1376 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1377 im_info = MPLIST_VAL (elt);
1378 free_im_info (im_info);
1380 M17N_OBJECT_UNREF (plist);
1383 static MInputMethodInfo *
1384 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1386 if (name == Mnil && extra == Mnil)
1387 language = Mt, extra = Mglobal;
1388 while ((plist = mplist__assq (plist, language)))
1390 MPlist *elt = MPLIST_PLIST (plist);
1392 plist = MPLIST_NEXT (plist);
1393 elt = MPLIST_NEXT (elt);
1394 if (MPLIST_SYMBOL (elt) != name)
1396 elt = MPLIST_NEXT (elt);
1397 if (MPLIST_SYMBOL (elt) != extra)
1399 elt = MPLIST_NEXT (elt);
1400 return MPLIST_VAL (elt);
1405 static void load_im_info (MPlist *, MInputMethodInfo *);
1407 #define get_custom_info(im_info) \
1409 ? lookup_im_info (im_custom_list, (im_info)->language, \
1410 (im_info)->name, (im_info)->extra) \
1413 #define get_config_info(im_info) \
1415 ? lookup_im_info (im_config_list, (im_info)->language, \
1416 (im_info)->name, (im_info)->extra) \
1420 update_custom_info (void)
1426 if (mdatabase__check (im_custom_mdb) > 0)
1431 MDatabaseInfo *custom_dir_info;
1432 char custom_path[PATH_MAX + 1];
1434 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1435 if (! custom_dir_info->filename
1436 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1438 strcpy (custom_path, custom_dir_info->filename);
1439 strcat (custom_path, CUSTOM_FILE);
1440 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1446 free_im_list (im_custom_list);
1447 im_custom_list = NULL;
1449 plist = mdatabase_load (im_custom_mdb);
1452 im_custom_list = mplist ();
1454 MPLIST_DO (pl, plist)
1456 MSymbol language, name, extra;
1457 MInputMethodInfo *im_info;
1458 MPlist *im_data, *p;
1460 if (! MPLIST_PLIST_P (pl))
1462 p = MPLIST_PLIST (pl);
1463 im_data = MPLIST_NEXT (p);
1464 if (! MPLIST_PLIST_P (p))
1466 p = MPLIST_PLIST (p);
1467 if (! MPLIST_SYMBOL_P (p)
1468 || MPLIST_SYMBOL (p) != Minput_method)
1470 p = MPLIST_NEXT (p);
1471 if (! MPLIST_SYMBOL_P (p))
1473 language = MPLIST_SYMBOL (p);
1474 p = MPLIST_NEXT (p);
1475 if (! MPLIST_SYMBOL_P (p))
1477 name = MPLIST_SYMBOL (p);
1478 p = MPLIST_NEXT (p);
1479 if (MPLIST_TAIL_P (p))
1481 else if (MPLIST_SYMBOL_P (p))
1482 extra = MPLIST_SYMBOL (p);
1483 if (language == Mnil || (name == Mnil && extra == Mnil))
1485 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1486 load_im_info (im_data, im_info);
1488 M17N_OBJECT_UNREF (plist);
1493 update_global_info (void)
1499 int ret = mdatabase__check (global_info->mdb);
1503 fini_im_info (global_info);
1507 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1511 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1513 if (! global_info->mdb
1514 || ! (plist = mdatabase_load (global_info->mdb)))
1517 load_im_info (plist, global_info);
1518 M17N_OBJECT_UNREF (plist);
1523 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1524 and EXTRA. KEY, if not Mnil, tells which kind of information about
1525 the input method is necessary, and the returned IM_INFO may contain
1526 only that information. */
1528 static MInputMethodInfo *
1529 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1532 MInputMethodInfo *im_info;
1535 if (name == Mnil && extra == Mnil)
1536 language = Mt, extra = Mglobal;
1537 im_info = lookup_im_info (im_info_list, language, name, extra);
1540 if (key == Mnil ? im_info->states != NULL
1541 : key == Mcommand ? im_info->cmds != NULL
1542 : key == Mvariable ? im_info->vars != NULL
1543 : key == Mtitle ? im_info->title != NULL
1544 : key == Mdescription ? im_info->description != NULL
1546 /* IM_INFO already contains required information. */
1548 /* We have not yet loaded required information. */
1552 mdb = mdatabase_find (Minput_method, language, name, extra);
1555 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1560 plist = mdatabase_load (im_info->mdb);
1564 mplist_push (load_im_info_keys, key, Mt);
1565 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1566 mplist_pop (load_im_info_keys);
1570 MERROR (MERROR_IM, im_info);
1571 update_global_info ();
1572 load_im_info (plist, im_info);
1573 M17N_OBJECT_UNREF (plist);
1576 if (! im_info->cmds)
1577 im_info->cmds = mplist ();
1578 if (! im_info->vars)
1579 im_info->vars = mplist ();
1580 if (! im_info->states)
1581 im_info->states = mplist ();
1583 if (! im_info->title
1584 && (key == Mnil || key == Mtitle))
1585 im_info->title = (name == Mnil ? mtext ()
1586 : mtext_from_data (MSYMBOL_NAME (name),
1587 MSYMBOL_NAMELEN (name),
1588 MTEXT_FORMAT_US_ASCII));
1592 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1593 If updated, but got unloadable, return -1. Otherwise, update
1594 contents of IM_INFO from the new database, and return 1. */
1597 reload_im_info (MInputMethodInfo *im_info)
1602 update_custom_info ();
1603 update_global_info ();
1604 check = mdatabase__check (im_info->mdb);
1607 plist = mdatabase_load (im_info->mdb);
1610 fini_im_info (im_info);
1611 load_im_info (plist, im_info);
1612 M17N_OBJECT_UNREF (plist);
1613 if (! im_info->cmds)
1614 im_info->cmds = mplist ();
1615 if (! im_info->vars)
1616 im_info->vars = mplist ();
1617 if (! im_info->title)
1619 MSymbol name = im_info->name;
1621 im_info->title = (name == Mnil ? mtext ()
1622 : mtext_from_data (MSYMBOL_NAME (name),
1623 MSYMBOL_NAMELEN (name),
1624 MTEXT_FORMAT_US_ASCII));
1629 static MInputMethodInfo *
1630 get_im_info_by_tags (MPlist *plist)
1635 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1636 i++, plist = MPLIST_NEXT (plist))
1637 tag[i] = MPLIST_SYMBOL (plist);
1642 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1647 check_description (MPlist *plist)
1651 if (MPLIST_MTEXT_P (plist))
1653 if (MPLIST_PLIST_P (plist))
1655 MPlist *pl = MPLIST_PLIST (plist);
1657 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1659 pl =MPLIST_NEXT (pl);
1660 if (MFAILP (MPLIST_MTEXT_P (pl)))
1662 mt = MPLIST_MTEXT (pl);
1663 M17N_OBJECT_REF (mt);
1666 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1668 if (translated == (char *) MTEXT_DATA (mt))
1669 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1670 if (translated != (char *) MTEXT_DATA (mt))
1672 M17N_OBJECT_UNREF (mt);
1673 mt = mtext__from_data (translated, strlen (translated),
1674 MTEXT_FORMAT_UTF_8, 1);
1678 mplist_set (plist, Mtext, mt);
1679 M17N_OBJECT_UNREF (mt);
1682 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1688 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1692 check_command_keyseq (MPlist *keyseq)
1694 if (MPLIST_PLIST_P (keyseq))
1696 MPlist *p = MPLIST_PLIST (keyseq);
1699 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1703 if (MPLIST_MTEXT_P (keyseq))
1705 MText *mt = MPLIST_MTEXT (keyseq);
1708 for (i = 0; i < mtext_nchars (mt); i++)
1709 if (mtext_ref_char (mt, i) >= 256)
1716 /* Load command defitions from PLIST into IM_INFO->cmds.
1718 PLIST is well-formed and has this form;
1719 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1720 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1721 M-text or a plist of symbols.
1723 The returned list has the same form, but for each element...
1725 (1) If DESCRIPTION and the rest are omitted, the element is not
1726 stored in the returned list.
1728 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1729 description in global_info->cmds (if any). */
1732 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1736 im_info->cmds = tail = mplist ();
1738 MPLIST_DO (plist, MPLIST_NEXT (plist))
1740 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1743 if (MFAILP (MPLIST_PLIST_P (plist)))
1745 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1746 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1748 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1749 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1751 if (MFAILP (im_info != global_info))
1752 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1756 if (! check_description (p))
1757 mplist_set (p, Msymbol, Mnil);
1758 p = MPLIST_NEXT (p);
1759 while (! MPLIST_TAIL_P (p))
1761 if (MFAILP (check_command_keyseq (p)))
1762 mplist__pop_unref (p);
1764 p = MPLIST_NEXT (p);
1767 tail = mplist_add (tail, Mplist, pl);
1772 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1773 MPlist *config_cmds)
1775 MPlist *global = NULL, *custom = NULL, *config = NULL;
1776 MSymbol name = MPLIST_SYMBOL (plist);
1778 MPlist *description, *keyseq;
1780 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1781 global = MPLIST_NEXT (MPLIST_PLIST (global));
1783 plist = MPLIST_NEXT (plist);
1784 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1786 description = plist;
1787 plist = MPLIST_NEXT (plist);
1791 description = global;
1792 if (! MPLIST_TAIL_P (plist))
1793 plist = MPLIST_NEXT (plist);
1795 if (MPLIST_TAIL_P (plist) && global)
1797 keyseq = MPLIST_NEXT (global);
1798 status = Minherited;
1806 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1808 status = Mconfigured;
1809 config = MPLIST_NEXT (MPLIST_PLIST (config));
1810 if (! MPLIST_TAIL_P (config))
1813 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1815 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1817 if (MPLIST_TAIL_P (this_keyseq))
1818 mplist__pop_unref (custom);
1821 status = Mcustomized;
1822 keyseq = this_keyseq;
1827 mplist_add (plist, Msymbol, name);
1829 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1831 mplist_add (plist, Msymbol, Mnil);
1832 mplist_add (plist, Msymbol, status);
1833 mplist__conc (plist, keyseq);
1838 config_all_commands (MInputMethodInfo *im_info)
1840 MPlist *global_cmds, *custom_cmds, *config_cmds;
1841 MInputMethodInfo *temp;
1842 MPlist *tail, *plist;
1844 M17N_OBJECT_UNREF (im_info->configured_cmds);
1846 if (MPLIST_TAIL_P (im_info->cmds)
1850 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1851 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1852 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1854 im_info->configured_cmds = tail = mplist ();
1855 MPLIST_DO (plist, im_info->cmds)
1857 MPlist *pl = config_command (MPLIST_PLIST (plist),
1858 global_cmds, custom_cmds, config_cmds);
1861 tail = mplist_add (tail, Mplist, pl);
1862 M17N_OBJECT_UNREF (pl);
1867 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1868 valid, return 0 if not. */
1871 check_variable_value (MPlist *val, MPlist *global)
1873 MSymbol type = MPLIST_KEY (val);
1874 MPlist *valids = MPLIST_NEXT (val);
1876 if (type != Minteger && type != Mtext && type != Msymbol)
1880 if (MPLIST_KEY (global) != Mt
1881 && MPLIST_KEY (global) != MPLIST_KEY (val))
1883 if (MPLIST_TAIL_P (valids))
1884 valids = MPLIST_NEXT (global);
1886 if (MPLIST_TAIL_P (valids))
1889 if (type == Minteger)
1891 int n = MPLIST_INTEGER (val);
1893 MPLIST_DO (valids, valids)
1895 if (MPLIST_INTEGER_P (valids))
1897 if (n == MPLIST_INTEGER (valids))
1900 else if (MPLIST_PLIST_P (valids))
1902 MPlist *p = MPLIST_PLIST (valids);
1903 int min_bound, max_bound;
1905 if (! MPLIST_INTEGER_P (p))
1906 MERROR (MERROR_IM, 0);
1907 min_bound = MPLIST_INTEGER (p);
1908 p = MPLIST_NEXT (p);
1909 if (! MPLIST_INTEGER_P (p))
1910 MERROR (MERROR_IM, 0);
1911 max_bound = MPLIST_INTEGER (p);
1912 if (n >= min_bound && n <= max_bound)
1917 else if (type == Msymbol)
1919 MSymbol sym = MPLIST_SYMBOL (val);
1921 MPLIST_DO (valids, valids)
1923 if (! MPLIST_SYMBOL_P (valids))
1924 MERROR (MERROR_IM, 0);
1925 if (sym == MPLIST_SYMBOL (valids))
1931 MText *mt = MPLIST_MTEXT (val);
1933 MPLIST_DO (valids, valids)
1935 if (! MPLIST_MTEXT_P (valids))
1936 MERROR (MERROR_IM, 0);
1937 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1942 return (! MPLIST_TAIL_P (valids));
1945 /* Load variable defitions from PLIST into IM_INFO->vars.
1947 PLIST is well-formed and has this form;
1948 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1950 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1952 The returned list has the same form, but for each element...
1954 (1) If DESCRIPTION and the rest are omitted, the element is not
1955 stored in the returned list.
1957 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1958 description in global_info->vars (if any). */
1961 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1963 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1964 ? global_info->vars : NULL);
1967 im_info->vars = tail = mplist ();
1968 MPLIST_DO (plist, MPLIST_NEXT (plist))
1972 if (MFAILP (MPLIST_PLIST_P (plist)))
1974 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1975 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1977 if (im_info == global_info)
1979 /* Loading a global variable. */
1980 p = MPLIST_NEXT (pl);
1981 if (MPLIST_TAIL_P (p))
1982 mplist_add (p, Msymbol, Mnil);
1985 if (! check_description (p))
1986 mplist_set (p, Msymbol, Mnil);
1987 p = MPLIST_NEXT (p);
1988 if (MFAILP (! MPLIST_TAIL_P (p)
1989 && check_variable_value (p, NULL)))
1990 mplist_set (p, Mt, NULL);
1993 else if (im_info->mdb)
1995 /* Loading a local variable. */
1996 MSymbol name = MPLIST_SYMBOL (pl);
1997 MPlist *global = NULL;
2000 && (p = mplist__assq (global_vars, name)))
2002 /* P ::= ((NAME DESC ...) ...) */
2003 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2004 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2005 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2008 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2009 if (! MPLIST_TAIL_P (p))
2011 if (! check_description (p))
2012 mplist_set (p, Msymbol, Mnil);
2013 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2014 if (MFAILP (! MPLIST_TAIL_P (p)))
2015 mplist_set (p, Mt, NULL);
2018 MPlist *valid_values = MPLIST_NEXT (p);
2020 if (! MPLIST_TAIL_P (valid_values)
2021 ? MFAILP (check_variable_value (p, NULL))
2022 : global && MFAILP (check_variable_value (p, global)))
2023 mplist_set (p, Mt, NULL);
2029 /* Loading a variable customization. */
2030 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2031 if (MFAILP (! MPLIST_TAIL_P (p)))
2033 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2034 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2035 || MPLIST_MTEXT_P (p)))
2038 tail = mplist_add (tail, Mplist, pl);
2043 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2044 MPlist *config_vars)
2046 MPlist *global = NULL, *custom = NULL, *config = NULL;
2047 MSymbol name = MPLIST_SYMBOL (plist);
2049 MPlist *description = NULL, *value, *valids;
2053 global = mplist__assq (global_vars, name);
2055 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2058 plist = MPLIST_NEXT (plist);
2059 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2060 description = plist;
2062 description = global;
2064 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2066 if (MPLIST_TAIL_P (plist))
2068 /* Inherit from global (if any). */
2072 if (MPLIST_KEY (value) == Mt)
2074 valids = MPLIST_NEXT (global);
2075 status = Minherited;
2087 value = plist = MPLIST_NEXT (plist);
2088 valids = MPLIST_NEXT (value);
2089 if (MPLIST_KEY (value) == Mt)
2091 if (! MPLIST_TAIL_P (valids))
2094 valids = MPLIST_NEXT (global);
2098 if (config_vars && (config = mplist__assq (config_vars, name)))
2100 status = Mconfigured;
2101 config = MPLIST_NEXT (MPLIST_PLIST (config));
2102 if (! MPLIST_TAIL_P (config))
2105 if (MFAILP (check_variable_value (value, global ? global : plist)))
2109 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2111 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2113 if (MPLIST_TAIL_P (this_value))
2114 mplist__pop_unref (custom);
2118 if (MFAILP (check_variable_value (value, global ? global : plist)))
2120 status = Mcustomized;
2125 mplist_add (plist, Msymbol, name);
2127 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2129 mplist_add (plist, Msymbol, Mnil);
2130 mplist_add (plist, Msymbol, status);
2132 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2134 mplist_add (plist, Mt, NULL);
2135 if (valids && ! MPLIST_TAIL_P (valids))
2136 mplist__conc (plist, valids);
2140 /* Return a configured variable definition list based on
2141 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2142 get it from global_info->vars. */
2145 config_all_variables (MInputMethodInfo *im_info)
2147 MPlist *global_vars, *custom_vars, *config_vars;
2148 MInputMethodInfo *temp;
2149 MPlist *tail, *plist;
2151 M17N_OBJECT_UNREF (im_info->configured_vars);
2153 if (MPLIST_TAIL_P (im_info->vars)
2157 global_vars = im_info != global_info ? global_info->vars : NULL;
2158 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2159 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2161 im_info->configured_vars = tail = mplist ();
2162 MPLIST_DO (plist, im_info->vars)
2164 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2165 global_vars, custom_vars, config_vars);
2168 tail = mplist_add (tail, Mplist, pl);
2169 M17N_OBJECT_UNREF (pl);
2174 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2175 CONFIG contains configuration information of the input method. */
2178 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2182 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2184 load_commands (im_info, MPLIST_PLIST (pl));
2185 config_all_commands (im_info);
2186 pl = mplist_pop (pl);
2187 M17N_OBJECT_UNREF (pl);
2190 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2192 load_variables (im_info, MPLIST_PLIST (pl));
2193 config_all_variables (im_info);
2194 pl = mplist_pop (pl);
2195 M17N_OBJECT_UNREF (pl);
2198 MPLIST_DO (plist, plist)
2199 if (MPLIST_PLIST_P (plist))
2201 MPlist *elt = MPLIST_PLIST (plist);
2204 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2206 key = MPLIST_SYMBOL (elt);
2211 elt = MPLIST_NEXT (elt);
2212 if (MFAILP (MPLIST_MTEXT_P (elt)))
2214 im_info->title = MPLIST_MTEXT (elt);
2215 M17N_OBJECT_REF (im_info->title);
2217 else if (key == Mmap)
2219 pl = mplist__from_alist (MPLIST_NEXT (elt));
2222 if (! im_info->maps)
2226 mplist__conc (im_info->maps, pl);
2227 M17N_OBJECT_UNREF (pl);
2230 else if (key == Mmacro)
2232 if (! im_info->macros)
2233 im_info->macros = mplist ();
2234 MPLIST_DO (elt, MPLIST_NEXT (elt))
2236 if (MFAILP (MPLIST_PLIST_P (elt)))
2238 load_macros (im_info, MPLIST_PLIST (elt));
2241 else if (key == Mmodule)
2243 if (! im_info->externals)
2244 im_info->externals = mplist ();
2245 MPLIST_DO (elt, MPLIST_NEXT (elt))
2247 if (MFAILP (MPLIST_PLIST_P (elt)))
2249 load_external_module (im_info, MPLIST_PLIST (elt));
2252 else if (key == Mstate)
2254 MPLIST_DO (elt, MPLIST_NEXT (elt))
2258 if (MFAILP (MPLIST_PLIST_P (elt)))
2260 pl = MPLIST_PLIST (elt);
2261 if (! im_info->states)
2262 im_info->states = mplist ();
2263 state = load_state (im_info, MPLIST_PLIST (elt));
2266 mplist_put (im_info->states, state->name, state);
2269 else if (key == Minclude)
2271 /* elt ::= include (tag1 tag2 ...) key item ... */
2273 MInputMethodInfo *temp;
2275 elt = MPLIST_NEXT (elt);
2276 if (MFAILP (MPLIST_PLIST_P (elt)))
2278 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2281 elt = MPLIST_NEXT (elt);
2282 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2284 key = MPLIST_SYMBOL (elt);
2285 elt = MPLIST_NEXT (elt);
2288 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2290 if (! im_info->maps)
2291 im_info->maps = mplist ();
2292 MPLIST_DO (pl, temp->maps)
2294 p = MPLIST_VAL (pl);
2295 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2296 M17N_OBJECT_REF (p);
2299 else if (key == Mmacro)
2301 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2303 if (! im_info->macros)
2304 im_info->macros = mplist ();
2305 MPLIST_DO (pl, temp->macros)
2307 p = MPLIST_VAL (pl);
2308 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2309 M17N_OBJECT_REF (p);
2312 else if (key == Mstate)
2314 if (! temp->states || MPLIST_TAIL_P (temp->states))
2316 if (! im_info->states)
2317 im_info->states = mplist ();
2318 MPLIST_DO (pl, temp->states)
2320 MIMState *state = MPLIST_VAL (pl);
2322 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2323 M17N_OBJECT_REF (state);
2327 else if (key == Mdescription)
2329 if (im_info->description)
2331 elt = MPLIST_NEXT (elt);
2332 if (! check_description (elt))
2334 im_info->description = MPLIST_MTEXT (elt);
2335 M17N_OBJECT_REF (im_info->description);
2338 im_info->tick = time (NULL);
2343 static int take_action_list (MInputContext *ic, MPlist *action_list);
2344 static void preedit_commit (MInputContext *ic, int need_prefix);
2347 shift_state (MInputContext *ic, MSymbol state_name)
2349 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2350 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2351 MIMState *orig_state = ic_info->state, *state;
2353 /* Find a state to shift to. If not found, shift to the initial
2355 if (state_name == Mt)
2357 if (! ic_info->prev_state)
2359 state = ic_info->prev_state;
2361 else if (state_name == Mnil)
2363 state = (MIMState *) MPLIST_VAL (im_info->states);
2367 state = (MIMState *) mplist_get (im_info->states, state_name);
2369 state = (MIMState *) MPLIST_VAL (im_info->states);
2375 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2376 MSYMBOL_NAME (orig_state->name),
2377 MSYMBOL_NAME (state->name));
2379 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2382 /* Enter the new state. */
2383 ic_info->state = state;
2384 ic_info->map = state->map;
2385 ic_info->state_key_head = ic_info->key_head;
2386 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2388 /* We have shifted to the initial state. */
2389 preedit_commit (ic, 0);
2390 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2391 ic_info->state_pos = ic->cursor_pos;
2392 if (state != orig_state)
2394 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2396 /* Shifted to the initial state. */
2397 ic_info->prev_state = NULL;
2398 M17N_OBJECT_UNREF (ic_info->vars_saved);
2399 ic_info->vars_saved = mplist_copy (ic_info->vars);
2402 ic_info->prev_state = orig_state;
2405 ic->status = state->title;
2407 ic->status = im_info->title;
2408 ic->status_changed = 1;
2409 if (ic_info->map == ic_info->state->map
2410 && ic_info->map->map_actions)
2412 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2413 MSYMBOL_NAME (state->name));
2414 take_action_list (ic, ic_info->map->map_actions);
2419 /* Find a candidate group that contains a candidate number INDEX from
2420 PLIST. Set START_INDEX to the first candidate number of the group,
2421 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2422 candidate group number if they are non-NULL. If INDEX is -1, find
2423 the last candidate group. */
2426 find_candidates_group (MPlist *plist, int index,
2427 int *start_index, int *end_index, int *group_index)
2429 int i = 0, gidx = 0, len;
2431 MPLIST_DO (plist, plist)
2433 if (MPLIST_MTEXT_P (plist))
2434 len = mtext_nchars (MPLIST_MTEXT (plist));
2436 len = mplist_length (MPLIST_PLIST (plist));
2437 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2443 *end_index = i + len;
2445 *group_index = gidx;
2454 /* Adjust markers for the change of preedit text.
2455 If FROM == TO, the change is insertion of INS chars.
2456 If FROM < TO and INS == 0, the change is deletion of the range.
2457 If FROM < TO and INS > 0, the change is replacement. */
2460 adjust_markers (MInputContext *ic, int from, int to, int ins)
2462 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2467 MPLIST_DO (markers, ic_info->markers)
2468 if (MPLIST_INTEGER (markers) > from)
2469 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2470 if (ic->cursor_pos >= from)
2471 ic->cursor_pos += ins;
2475 MPLIST_DO (markers, ic_info->markers)
2477 if (MPLIST_INTEGER (markers) >= to)
2478 MPLIST_VAL (markers)
2479 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2480 else if (MPLIST_INTEGER (markers) > from)
2481 MPLIST_VAL (markers) = (void *) from;
2483 if (ic->cursor_pos >= to)
2484 ic->cursor_pos += ins - (to - from);
2485 else if (ic->cursor_pos > from)
2486 ic->cursor_pos = from;
2492 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2494 int nchars = mt ? mtext_nchars (mt) : 1;
2498 mtext_ins (ic->preedit, pos, mt);
2499 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2503 mtext_ins_char (ic->preedit, pos, c, 1);
2505 MDEBUG_PRINT1 ("('%c')", c);
2507 MDEBUG_PRINT1 ("(U+%04X)", c);
2509 adjust_markers (ic, pos, pos, nchars);
2510 ic->preedit_changed = 1;
2515 preedit_delete (MInputContext *ic, int from, int to)
2517 mtext_del (ic->preedit, from, to);
2518 adjust_markers (ic, from, to, 0);
2519 ic->preedit_changed = 1;
2523 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2527 mtext_del (ic->preedit, from, to);
2530 mtext_ins (ic->preedit, from, mt);
2531 ins = mtext_nchars (mt);
2535 mtext_ins_char (ic->preedit, from, c, 1);
2538 adjust_markers (ic, from, to, ins);
2539 ic->preedit_changed = 1;
2544 preedit_commit (MInputContext *ic, int need_prefix)
2546 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2547 int preedit_len = mtext_nchars (ic->preedit);
2549 if (preedit_len > 0)
2553 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2554 Mcandidate_list, NULL, 0);
2555 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2556 Mcandidate_index, NULL, 0);
2557 mtext_cat (ic->produced, ic->preedit);
2563 MDEBUG_PRINT1 ("\n [IM] [%s]",
2564 MSYMBOL_NAME (ic_info->state->name));
2565 MDEBUG_PRINT (" (commit");
2566 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2567 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2571 mtext_reset (ic->preedit);
2572 mtext_reset (ic_info->preedit_saved);
2573 MPLIST_DO (p, ic_info->markers)
2575 ic->cursor_pos = ic_info->state_pos = 0;
2576 ic->preedit_changed = 1;
2577 ic_info->commit_key_head = ic_info->key_head;
2579 if (ic->candidate_list)
2581 M17N_OBJECT_UNREF (ic->candidate_list);
2582 ic->candidate_list = NULL;
2583 ic->candidate_index = 0;
2584 ic->candidate_from = ic->candidate_to = 0;
2585 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2586 if (ic->candidate_show)
2588 ic->candidate_show = 0;
2589 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2595 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2597 int code = marker_code (sym, 0);
2599 if (mt && (code == '[' || code == ']'))
2603 if (code == '[' && current > 0)
2605 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2609 else if (code == ']' && current < mtext_nchars (mt))
2611 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2617 return (code == '<' ? 0
2618 : code == '>' ? limit
2619 : code == '-' ? current - 1
2620 : code == '+' ? current + 1
2621 : code == '=' ? current
2622 : code - '0' > limit ? limit
2626 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2630 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2632 int from = mtext_property_start (prop);
2633 int to = mtext_property_end (prop);
2635 MPlist *candidate_list = mtext_property_value (prop);
2636 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2638 int ingroup_index = idx - start;
2641 candidate_list = mplist_copy (candidate_list);
2642 if (MPLIST_MTEXT_P (group))
2644 mt = MPLIST_MTEXT (group);
2645 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2653 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2654 i++, plist = MPLIST_NEXT (plist));
2655 mt = MPLIST_MTEXT (plist);
2656 preedit_replace (ic, from, to, mt, 0);
2657 to = from + mtext_nchars (mt);
2659 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2660 M17N_OBJECT_UNREF (candidate_list);
2661 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2662 ic->cursor_pos = to;
2666 get_select_charset (MInputContextInfo * ic_info)
2668 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2671 if (! MPLIST_VAL (plist))
2673 sym = MPLIST_SYMBOL (plist);
2676 return MCHARSET (sym);
2680 adjust_candidates (MPlist *plist, MCharset *charset)
2684 /* plist ::= MTEXT ... | PLIST ... */
2685 plist = mplist_copy (plist);
2686 if (MPLIST_MTEXT_P (plist))
2689 while (! MPLIST_TAIL_P (pl))
2691 /* pl ::= MTEXT ... */
2692 MText *mt = MPLIST_MTEXT (pl);
2696 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2698 c = mtext_ref_char (mt, i);
2699 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2703 mt = mtext_dup (mt);
2704 mplist_set (pl, Mtext, mt);
2705 M17N_OBJECT_UNREF (mt);
2708 mtext_del (mt, i, i + 1);
2711 if (mtext_len (mt) > 0)
2712 pl = MPLIST_NEXT (pl);
2716 M17N_OBJECT_UNREF (mt);
2720 else /* MPLIST_PLIST_P (plist) */
2723 while (! MPLIST_TAIL_P (pl))
2725 /* pl ::= (MTEXT ...) ... */
2726 MPlist *p = MPLIST_PLIST (pl);
2728 /* p ::= MTEXT ... */
2732 while (! MPLIST_TAIL_P (p0))
2734 MText *mt = MPLIST_MTEXT (p0);
2737 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2739 c = mtext_ref_char (mt, i);
2740 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2745 p0 = MPLIST_NEXT (p0);
2752 p = mplist_copy (p);
2753 mplist_set (pl, Mplist, p);
2754 M17N_OBJECT_UNREF (p);
2758 p0 = MPLIST_NEXT (p0);
2761 M17N_OBJECT_UNREF (mt);
2764 if (! MPLIST_TAIL_P (p))
2765 pl = MPLIST_NEXT (pl);
2769 M17N_OBJECT_UNREF (p);
2773 if (MPLIST_TAIL_P (plist))
2775 M17N_OBJECT_UNREF (plist);
2782 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2784 MCharset *charset = get_select_charset (ic_info);
2789 plist = resolve_variable (ic_info, Mcandidates_group_size);
2790 column = MPLIST_INTEGER (plist);
2792 plist = MPLIST_PLIST (args);
2794 plist = adjust_candidates (plist, charset);
2796 if (plist && column > 0)
2798 if (MPLIST_MTEXT_P (plist))
2800 MText *mt = MPLIST_MTEXT (plist);
2801 MPlist *next = MPLIST_NEXT (plist);
2803 if (MPLIST_TAIL_P (next))
2804 M17N_OBJECT_REF (mt);
2807 mt = mtext_dup (mt);
2808 while (! MPLIST_TAIL_P (next))
2810 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2811 next = MPLIST_NEXT (next);
2815 M17N_OBJECT_UNREF (plist);
2817 len = mtext_nchars (mt);
2819 mplist_add (plist, Mtext, mt);
2822 for (i = 0; i < len; i += column)
2824 int to = (i + column < len ? i + column : len);
2825 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2827 mplist_add (plist, Mtext, sub);
2828 M17N_OBJECT_UNREF (sub);
2831 M17N_OBJECT_UNREF (mt);
2833 else if (! MPLIST_TAIL_P (plist))
2835 MPlist *tail = plist;
2836 MPlist *new = mplist ();
2837 MPlist *this = mplist ();
2840 MPLIST_DO (tail, tail)
2842 MPlist *p = MPLIST_PLIST (tail);
2846 MText *mt = MPLIST_MTEXT (p);
2848 if (count == column)
2850 mplist_add (new, Mplist, this);
2851 M17N_OBJECT_UNREF (this);
2855 mplist_add (this, Mtext, mt);
2859 mplist_add (new, Mplist, this);
2860 M17N_OBJECT_UNREF (this);
2861 mplist_set (plist, Mnil, NULL);
2862 MPLIST_DO (tail, new)
2864 MPlist *elt = MPLIST_PLIST (tail);
2866 mplist_add (plist, Mplist, elt);
2868 M17N_OBJECT_UNREF (new);
2877 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2879 MPlist *action = NULL;
2883 if (MPLIST_SYMBOL_P (action_list))
2885 MSymbol var = MPLIST_SYMBOL (action_list);
2888 MPLIST_DO (p, ic_info->vars)
2889 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2891 if (MPLIST_TAIL_P (p))
2893 action = MPLIST_NEXT (MPLIST_PLIST (p));
2894 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2897 if (MPLIST_PLIST_P (action_list))
2899 action = MPLIST_PLIST (action_list);
2900 if (MPLIST_SYMBOL_P (action))
2902 name = MPLIST_SYMBOL (action);
2903 args = MPLIST_NEXT (action);
2905 && MPLIST_PLIST_P (args))
2906 mplist_set (action, Msymbol, M_candidates);
2908 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2911 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2912 mplist_push (action, Msymbol, M_candidates);
2913 mplist_set (action_list, Mplist, action);
2914 M17N_OBJECT_UNREF (action);
2917 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2920 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2921 mplist_push (action, Msymbol, Minsert);
2922 mplist_set (action_list, Mplist, action);
2923 M17N_OBJECT_UNREF (action);
2928 /* Perform list of actions in ACTION_LIST for the current input
2929 context IC. If unhandle action was not performed, return 0.
2930 Otherwise, return -1. */
2933 take_action_list (MInputContext *ic, MPlist *action_list)
2935 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2936 MPlist *candidate_list = ic->candidate_list;
2937 int candidate_index = ic->candidate_index;
2938 int candidate_show = ic->candidate_show;
2939 MTextProperty *prop;
2941 MPLIST_DO (action_list, action_list)
2943 MPlist *action = regularize_action (action_list, ic_info);
2949 name = MPLIST_SYMBOL (action);
2950 args = MPLIST_NEXT (action);
2952 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2953 if (name == Minsert)
2955 if (MPLIST_SYMBOL_P (args))
2957 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2958 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2961 if (MPLIST_MTEXT_P (args))
2962 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2963 else /* MPLIST_INTEGER_P (args)) */
2964 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2966 else if (name == M_candidates)
2968 MPlist *plist = get_candidate_list (ic_info, args);
2971 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2973 if (MPLIST_MTEXT_P (plist))
2975 preedit_insert (ic, ic->cursor_pos, NULL,
2976 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2979 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2983 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2985 preedit_insert (ic, ic->cursor_pos, mt, 0);
2986 len = mtext_nchars (mt);
2988 plist = mplist_copy (plist);
2989 mtext_put_prop (ic->preedit,
2990 ic->cursor_pos - len, ic->cursor_pos,
2991 Mcandidate_list, plist);
2992 M17N_OBJECT_UNREF (plist);
2993 mtext_put_prop (ic->preedit,
2994 ic->cursor_pos - len, ic->cursor_pos,
2995 Mcandidate_index, (void *) 0);
2997 else if (name == Mselect)
3000 int code, idx, gindex;
3001 int pos = ic->cursor_pos;
3003 int idx_decided = 0;
3006 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3009 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3010 group = find_candidates_group (mtext_property_value (prop), idx,
3011 &start, &end, &gindex);
3012 if (MPLIST_SYMBOL_P (args))
3014 code = marker_code (MPLIST_SYMBOL (args), 0);
3017 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3018 if (! MPLIST_INTEGER_P (args))
3020 idx = start + MPLIST_INTEGER (args);
3021 if (idx < start || idx >= end)
3029 if (code != '[' && code != ']')
3034 ? new_index (NULL, ic->candidate_index - start,
3035 end - start - 1, MPLIST_SYMBOL (args),
3037 : MPLIST_INTEGER (args)));
3040 find_candidates_group (mtext_property_value (prop), -1,
3045 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3050 int ingroup_index = idx - start;
3053 group = mtext_property_value (prop);
3054 len = mplist_length (group);
3067 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3068 idx += (MPLIST_MTEXT_P (group)
3069 ? mtext_nchars (MPLIST_MTEXT (group))
3070 : mplist_length (MPLIST_PLIST (group)));
3071 len = (MPLIST_MTEXT_P (group)
3072 ? mtext_nchars (MPLIST_MTEXT (group))
3073 : mplist_length (MPLIST_PLIST (group)));
3074 if (ingroup_index >= len)
3075 ingroup_index = len - 1;
3076 idx += ingroup_index;
3078 update_candidate (ic, prop, idx);
3079 MDEBUG_PRINT1 ("(%d)", idx);
3081 else if (name == Mshow)
3082 ic->candidate_show = 1;
3083 else if (name == Mhide)
3084 ic->candidate_show = 0;
3085 else if (name == Mdelete)
3087 int len = mtext_nchars (ic->preedit);
3091 if (MPLIST_SYMBOL_P (args)
3092 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3094 to = ic->cursor_pos + pos;
3097 delete_surrounding_text (ic, to);
3102 delete_surrounding_text (ic, to - len);
3108 to = (MPLIST_SYMBOL_P (args)
3109 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3111 : MPLIST_INTEGER (args));
3117 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3118 if (to < ic->cursor_pos)
3119 preedit_delete (ic, to, ic->cursor_pos);
3120 else if (to > ic->cursor_pos)
3121 preedit_delete (ic, ic->cursor_pos, to);
3123 else if (name == Mmove)
3125 int len = mtext_nchars (ic->preedit);
3127 = (MPLIST_SYMBOL_P (args)
3128 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3130 : MPLIST_INTEGER (args));
3136 if (pos != ic->cursor_pos)
3138 ic->cursor_pos = pos;
3139 ic->preedit_changed = 1;
3141 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3143 else if (name == Mmark)
3145 int code = marker_code (MPLIST_SYMBOL (args), 0);
3149 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3150 (void *) ic->cursor_pos);
3151 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3154 else if (name == Mpushback)
3156 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3160 if (MPLIST_SYMBOL_P (args))
3162 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3163 if (MPLIST_INTEGER_P (args))
3164 num = MPLIST_INTEGER (args);
3169 num = MPLIST_INTEGER (args);
3172 ic_info->key_head -= num;
3174 ic_info->key_head = 0;
3176 ic_info->key_head = - num;
3177 if (ic_info->key_head > ic_info->used)
3178 ic_info->key_head = ic_info->used;
3180 else if (MPLIST_MTEXT_P (args))
3182 MText *mt = MPLIST_MTEXT (args);
3183 int i, len = mtext_nchars (mt);
3186 ic_info->key_head--;
3187 for (i = 0; i < len; i++)
3189 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3190 if (ic_info->key_head + i < ic_info->used)
3191 ic_info->keys[ic_info->key_head + i] = key;
3193 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3198 MPlist *plist = MPLIST_PLIST (args), *pl;
3202 ic_info->key_head--;
3204 MPLIST_DO (pl, plist)
3206 key = MPLIST_SYMBOL (pl);
3207 if (ic_info->key_head < ic_info->used)
3208 ic_info->keys[ic_info->key_head + i] = key;
3210 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3215 else if (name == Mpop)
3217 if (ic_info->key_head < ic_info->used)
3218 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3220 else if (name == Mcall)
3222 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3223 MIMExternalFunc func = NULL;
3224 MSymbol module, func_name;
3225 MPlist *func_args, *val;
3228 module = MPLIST_SYMBOL (args);
3229 args = MPLIST_NEXT (args);
3230 func_name = MPLIST_SYMBOL (args);
3232 if (im_info->externals)
3234 MIMExternalModule *external
3235 = (MIMExternalModule *) mplist_get (im_info->externals,
3238 func = ((MIMExternalFunc)
3239 mplist_get_func (external->func_list, func_name));
3243 func_args = mplist ();
3244 mplist_add (func_args, Mt, ic);
3245 MPLIST_DO (args, MPLIST_NEXT (args))
3249 if (MPLIST_KEY (args) == Msymbol
3250 && MPLIST_KEY (args) != Mnil
3251 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3253 code = new_index (ic, ic->cursor_pos,
3254 mtext_nchars (ic->preedit),
3255 MPLIST_SYMBOL (args), ic->preedit);
3256 mplist_add (func_args, Minteger, (void *) code);
3259 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3261 val = (func) (func_args);
3262 M17N_OBJECT_UNREF (func_args);
3263 if (val && ! MPLIST_TAIL_P (val))
3264 ret = take_action_list (ic, val);
3265 M17N_OBJECT_UNREF (val);
3269 else if (name == Mshift)
3271 shift_state (ic, MPLIST_SYMBOL (args));
3273 else if (name == Mundo)
3275 int intarg = (MPLIST_TAIL_P (args)
3277 : integer_value (ic, args, 0));
3279 mtext_reset (ic->preedit);
3280 mtext_reset (ic_info->preedit_saved);
3281 mtext_reset (ic->produced);
3282 M17N_OBJECT_UNREF (ic_info->vars);
3283 ic_info->vars = mplist_copy (ic_info->vars_saved);
3284 ic->cursor_pos = ic_info->state_pos = 0;
3285 ic_info->state_key_head = ic_info->key_head
3286 = ic_info->commit_key_head = 0;
3288 shift_state (ic, Mnil);
3291 if (MPLIST_TAIL_P (args))
3296 ic_info->used += intarg;
3299 ic_info->used = intarg;
3302 else if (name == Mset || name == Madd || name == Msub
3303 || name == Mmul || name == Mdiv)
3305 MSymbol sym = MPLIST_SYMBOL (args);
3306 MPlist *value = resolve_variable (ic_info, sym);
3310 val1 = MPLIST_INTEGER (value);
3311 args = MPLIST_NEXT (args);
3312 val2 = resolve_expression (ic, args);
3314 val1 = val2, op = "=";
3315 else if (name == Madd)
3316 val1 += val2, op = "+=";
3317 else if (name == Msub)
3318 val1 -= val2, op = "-=";
3319 else if (name == Mmul)
3320 val1 *= val2, op = "*=";
3322 val1 /= val2, op = "/=";
3323 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3324 MSYMBOL_NAME (sym), op, val1, val1);
3325 mplist_set (value, Minteger, (void *) val1);
3327 else if (name == Mequal || name == Mless || name == Mgreater
3328 || name == Mless_equal || name == Mgreater_equal)
3331 MPlist *actions1, *actions2;
3334 val1 = resolve_expression (ic, args);
3335 args = MPLIST_NEXT (args);
3336 val2 = resolve_expression (ic, args);
3337 args = MPLIST_NEXT (args);
3338 actions1 = MPLIST_PLIST (args);
3339 args = MPLIST_NEXT (args);
3340 if (MPLIST_TAIL_P (args))
3343 actions2 = MPLIST_PLIST (args);
3344 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3345 if (name == Mequal ? val1 == val2
3346 : name == Mless ? val1 < val2
3347 : name == Mgreater ? val1 > val2
3348 : name == Mless_equal ? val1 <= val2
3351 MDEBUG_PRINT ("ok");
3352 ret = take_action_list (ic, actions1);
3356 MDEBUG_PRINT ("no");
3358 ret = take_action_list (ic, actions2);
3363 else if (name == Mcond)
3367 MPLIST_DO (args, args)
3372 if (! MPLIST_PLIST (args))
3374 cond = MPLIST_PLIST (args);
3375 if (resolve_expression (ic, cond) != 0)
3377 MDEBUG_PRINT1 ("(%dth)", idx);
3378 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3384 else if (name == Mcommit)
3386 preedit_commit (ic, 0);
3388 else if (name == Munhandle)
3390 preedit_commit (ic, 0);
3395 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3399 && (actions = mplist_get (im_info->macros, name)))
3401 if (take_action_list (ic, actions) < 0)
3407 if (ic->candidate_list)
3409 M17N_OBJECT_UNREF (ic->candidate_list);
3410 ic->candidate_list = NULL;
3412 if (ic->cursor_pos > 0
3413 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3416 ic->candidate_list = mtext_property_value (prop);
3417 M17N_OBJECT_REF (ic->candidate_list);
3419 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3421 ic->candidate_from = mtext_property_start (prop);
3422 ic->candidate_to = mtext_property_end (prop);
3425 if (candidate_list != ic->candidate_list)
3426 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3427 if (candidate_index != ic->candidate_index)
3428 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3429 if (candidate_show != ic->candidate_show)
3430 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3435 /* Handle the input key KEY in the current state and map specified in
3436 the input context IC. If KEY is handled correctly, return 0.
3437 Otherwise, return -1. */
3440 handle_key (MInputContext *ic)
3442 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3443 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3444 MIMMap *map = ic_info->map;
3445 MIMMap *submap = NULL;
3446 MSymbol key = ic_info->keys[ic_info->key_head];
3447 MSymbol alias = Mnil;
3450 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3451 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3455 submap = mplist_get (map->submaps, key);
3458 && (alias = msymbol_get (alias, M_key_alias))
3460 submap = mplist_get (map->submaps, alias);
3465 if (! alias || alias == key)
3466 MDEBUG_PRINT (" submap-found");
3468 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3469 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3470 ic->preedit_changed = 1;
3471 ic->cursor_pos = ic_info->state_pos;
3472 ic_info->key_head++;
3473 ic_info->map = map = submap;
3474 if (map->map_actions)
3476 MDEBUG_PRINT (" map-actions:");
3477 if (take_action_list (ic, map->map_actions) < 0)
3479 MDEBUG_PRINT ("\n");
3483 else if (map->submaps)
3485 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3487 MSymbol key = ic_info->keys[i];
3488 char *name = msymbol_name (key);
3490 if (! name[0] || ! name[1])
3491 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3495 /* If this is the terminal map or we have shifted to another
3496 state, perform branch actions (if any). */
3497 if (! map->submaps || map != ic_info->map)
3499 if (map->branch_actions)
3501 MDEBUG_PRINT (" branch-actions:");
3502 if (take_action_list (ic, map->branch_actions) < 0)
3504 MDEBUG_PRINT ("\n");
3508 /* If MAP is still not the root map, shift to the current
3510 if (ic_info->map != ic_info->state->map)
3511 shift_state (ic, ic_info->state->name);
3516 /* MAP can not handle KEY. */
3518 /* Perform branch actions if any. */
3519 if (map->branch_actions)
3521 MDEBUG_PRINT (" branch-actions:");
3522 if (take_action_list (ic, map->branch_actions) < 0)
3524 MDEBUG_PRINT ("\n");
3529 if (map == ic_info->map)
3531 /* The above branch actions didn't change the state. */
3533 /* If MAP is the root map of the initial state, and there
3534 still exist an unhandled key, it means that the current
3535 input method can not handle it. */
3536 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3537 && ic_info->key_head < ic_info->used)
3539 MDEBUG_PRINT (" unhandled\n");
3543 if (map != ic_info->state->map)
3545 /* MAP is not the root map. Shift to the root map of the
3547 shift_state (ic, ic_info->state->name);
3549 else if (! map->branch_actions)
3551 /* MAP is the root map without any default branch
3552 actions. Shift to the initial state. */
3553 shift_state (ic, Mnil);
3557 MDEBUG_PRINT ("\n");
3561 /* Initialize IC->ic_info. */
3564 init_ic_info (MInputContext *ic)
3566 MInputMethodInfo *im_info = ic->im->info;
3567 MInputContextInfo *ic_info = ic->info;
3570 MLIST_INIT1 (ic_info, keys, 8);;
3572 ic_info->markers = mplist ();
3574 ic_info->vars = mplist ();
3575 if (im_info->configured_vars)
3576 MPLIST_DO (plist, im_info->configured_vars)
3578 MPlist *pl = MPLIST_PLIST (plist);
3579 MSymbol name = MPLIST_SYMBOL (pl);
3581 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3582 if (MPLIST_KEY (pl) != Mt)
3584 MPlist *p = mplist ();
3586 mplist_push (ic_info->vars, Mplist, p);
3587 M17N_OBJECT_UNREF (p);
3588 mplist_add (p, Msymbol, name);
3589 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3592 ic_info->vars_saved = mplist_copy (ic_info->vars);
3594 if (im_info->externals)
3596 MPlist *func_args = mplist (), *plist;
3598 mplist_add (func_args, Mt, ic);
3599 MPLIST_DO (plist, im_info->externals)
3601 MIMExternalModule *external = MPLIST_VAL (plist);
3602 MIMExternalFunc func
3603 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3608 M17N_OBJECT_UNREF (func_args);
3611 ic_info->preedit_saved = mtext ();
3612 ic_info->tick = im_info->tick;
3615 /* Finalize IC->ic_info. */
3618 fini_ic_info (MInputContext *ic)
3620 MInputMethodInfo *im_info = ic->im->info;
3621 MInputContextInfo *ic_info = ic->info;
3623 if (im_info->externals)
3625 MPlist *func_args = mplist (), *plist;
3627 mplist_add (func_args, Mt, ic);
3628 MPLIST_DO (plist, im_info->externals)
3630 MIMExternalModule *external = MPLIST_VAL (plist);
3631 MIMExternalFunc func
3632 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3637 M17N_OBJECT_UNREF (func_args);
3640 MLIST_FREE1 (ic_info, keys);
3641 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3642 M17N_OBJECT_UNREF (ic_info->markers);
3643 M17N_OBJECT_UNREF (ic_info->vars);
3644 M17N_OBJECT_UNREF (ic_info->vars_saved);
3645 M17N_OBJECT_UNREF (ic_info->preceding_text);
3646 M17N_OBJECT_UNREF (ic_info->following_text);
3648 memset (ic_info, 0, sizeof (MInputContextInfo));
3652 re_init_ic (MInputContext *ic, int reload)
3654 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3655 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3656 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3658 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3659 preedit_changed = mtext_nchars (ic->preedit) > 0;
3660 cursor_pos_changed = ic->cursor_pos > 0;
3661 candidates_changed = 0;
3662 if (ic->candidate_list)
3664 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3665 M17N_OBJECT_UNREF (ic->candidate_list);
3666 ic->candidate_list = NULL;
3668 if (ic->candidate_show)
3670 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3671 ic->candidate_show = 0;
3673 if (ic->candidate_index > 0)
3675 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3676 ic->candidate_index = 0;
3677 ic->candidate_from = ic->candidate_to = 0;
3679 if (mtext_nchars (ic->produced) > 0)
3680 mtext_reset (ic->produced);
3681 if (mtext_nchars (ic->preedit) > 0)
3682 mtext_reset (ic->preedit);
3684 M17N_OBJECT_UNREF (ic->plist);
3685 ic->plist = mplist ();
3689 reload_im_info (im_info);
3690 if (! im_info->states)
3692 struct MIMState *state;
3694 M17N_OBJECT (state, free_state, MERROR_IM);
3695 state->name = msymbol ("init");
3696 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3697 MSTRUCT_CALLOC (state->map, MERROR_IM);
3698 im_info->states = mplist ();
3699 mplist_add (im_info->states, state->name, state);
3702 shift_state (ic, Mnil);
3704 ic->status_changed = status_changed;
3705 ic->preedit_changed = preedit_changed;
3706 ic->cursor_pos_changed = cursor_pos_changed;
3707 ic->candidates_changed = candidates_changed;
3711 reset_ic (MInputContext *ic, MSymbol ignore)
3713 MDEBUG_PRINT ("\n [IM] reset\n");
3718 open_im (MInputMethod *im)
3720 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3722 if (! im_info || ! im_info->states)
3723 MERROR (MERROR_IM, -1);
3730 close_im (MInputMethod *im)
3736 create_ic (MInputContext *ic)
3738 MInputContextInfo *ic_info;
3740 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3743 shift_state (ic, Mnil);
3748 destroy_ic (MInputContext *ic)
3755 check_reload (MInputContext *ic, MSymbol key)
3757 MInputMethodInfo *im_info = ic->im->info;
3758 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3762 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3766 MPLIST_DO (plist, plist)
3768 MSymbol this_key, alias;
3770 if (MPLIST_MTEXT_P (plist))
3772 MText *mt = MPLIST_MTEXT (plist);
3773 int c = mtext_ref_char (mt, 0);
3777 this_key = one_char_symbol[c];
3781 MPlist *pl = MPLIST_PLIST (plist);
3783 this_key = MPLIST_SYMBOL (pl);
3787 && (alias = msymbol_get (alias, M_key_alias))
3788 && alias != this_key);
3792 if (MPLIST_TAIL_P (plist))
3795 MDEBUG_PRINT ("\n [IM] reload");
3801 /** Handle the input key KEY in the current state and map of IC->info.
3802 If KEY is handled but no text is produced, return 0, otherwise
3808 filter (MInputContext *ic, MSymbol key, void *arg)
3810 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3811 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3814 if (check_reload (ic, key))
3817 if (! ic_info->state)
3819 ic_info->key_unhandled = 1;
3822 mtext_reset (ic->produced);
3823 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3824 M17N_OBJECT_UNREF (ic_info->preceding_text);
3825 M17N_OBJECT_UNREF (ic_info->following_text);
3826 ic_info->preceding_text = ic_info->following_text = NULL;
3827 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3828 ic_info->key_unhandled = 0;
3831 if (handle_key (ic) < 0)
3833 /* KEY was not handled. Delete it from the current key sequence. */
3834 if (ic_info->used > 0)
3836 memmove (ic_info->keys, ic_info->keys + 1,
3837 sizeof (int) * (ic_info->used - 1));
3839 if (ic_info->state_key_head > 0)
3840 ic_info->state_key_head--;
3841 if (ic_info->commit_key_head > 0)
3842 ic_info->commit_key_head--;
3844 /* This forces returning 1. */
3845 ic_info->key_unhandled = 1;
3851 reset_ic (ic, Mnil);
3852 ic_info->key_unhandled = 1;
3855 /* Break the loop if all keys were handled. */
3856 } while (ic_info->key_head < ic_info->used);
3858 /* If the current map is the root of the initial state, we should
3859 produce any preedit text in ic->produced. */
3860 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3861 preedit_commit (ic, 1);
3863 if (mtext_nchars (ic->produced) > 0)
3867 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3868 MSYMBOL_NAME (ic_info->state->name));
3869 for (i = 0; i < mtext_nchars (ic->produced); i++)
3870 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3874 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3875 Mlanguage, ic->im->language);
3877 if (ic_info->commit_key_head > 0)
3879 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3880 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3881 ic_info->used -= ic_info->commit_key_head;
3882 ic_info->key_head -= ic_info->commit_key_head;
3883 ic_info->state_key_head -= ic_info->commit_key_head;
3884 ic_info->commit_key_head = 0;
3886 if (ic_info->key_unhandled)
3889 ic_info->key_head = ic_info->state_key_head
3890 = ic_info->commit_key_head = 0;
3893 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3897 /** Return 1 if the last event or key was not handled, otherwise
3900 There is no need of looking up because ic->produced should already
3901 contain the produced text (if any).
3906 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3908 mtext_cat (mt, ic->produced);
3909 mtext_reset (ic->produced);
3910 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3914 /* Input method command handler. */
3916 /* List of all (global and local) commands.
3917 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3918 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3919 Global commands are stored as (t (t COMMAND ...)) */
3922 /* Input method variable handler. */
3925 /* Support functions for mdebug_dump_im. */
3928 dump_im_map (MPlist *map_list, int indent)
3931 MSymbol key = MPLIST_KEY (map_list);
3932 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3934 prefix = (char *) alloca (indent + 1);
3935 memset (prefix, 32, indent);
3936 prefix[indent] = '\0';
3938 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3939 if (map->map_actions)
3940 mdebug_dump_plist (map->map_actions, indent + 2);
3943 MPLIST_DO (map_list, map->submaps)
3945 fprintf (stderr, "\n%s ", prefix);
3946 dump_im_map (map_list, indent + 2);
3949 if (map->branch_actions)
3951 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3952 mdebug_dump_plist (map->branch_actions, indent + 4);
3953 fprintf (stderr, ")");
3955 fprintf (stderr, ")");
3960 dump_im_state (MIMState *state, int indent)
3965 prefix = (char *) alloca (indent + 1);
3966 memset (prefix, 32, indent);
3967 prefix[indent] = '\0';
3969 fprintf (stderr, "(%s", msymbol_name (state->name));
3970 if (state->map->submaps)
3972 MPLIST_DO (map_list, state->map->submaps)
3974 fprintf (stderr, "\n%s ", prefix);
3975 dump_im_map (map_list, indent + 2);
3978 fprintf (stderr, ")");
3986 Minput_driver = msymbol ("input-driver");
3988 Minput_preedit_start = msymbol ("input-preedit-start");
3989 Minput_preedit_done = msymbol ("input-preedit-done");
3990 Minput_preedit_draw = msymbol ("input-preedit-draw");
3991 Minput_status_start = msymbol ("input-status-start");
3992 Minput_status_done = msymbol ("input-status-done");
3993 Minput_status_draw = msymbol ("input-status-draw");
3994 Minput_candidates_start = msymbol ("input-candidates-start");
3995 Minput_candidates_done = msymbol ("input-candidates-done");
3996 Minput_candidates_draw = msymbol ("input-candidates-draw");
3997 Minput_set_spot = msymbol ("input-set-spot");
3998 Minput_focus_move = msymbol ("input-focus-move");
3999 Minput_focus_in = msymbol ("input-focus-in");
4000 Minput_focus_out = msymbol ("input-focus-out");
4001 Minput_toggle = msymbol ("input-toggle");
4002 Minput_reset = msymbol ("input-reset");
4003 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4004 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4005 Mcustomized = msymbol ("customized");
4006 Mconfigured = msymbol ("configured");
4007 Minherited = msymbol ("inherited");
4009 minput_default_driver.open_im = open_im;
4010 minput_default_driver.close_im = close_im;
4011 minput_default_driver.create_ic = create_ic;
4012 minput_default_driver.destroy_ic = destroy_ic;
4013 minput_default_driver.filter = filter;
4014 minput_default_driver.lookup = lookup;
4015 minput_default_driver.callback_list = mplist ();
4016 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4017 M17N_FUNC (reset_ic));
4018 minput_driver = &minput_default_driver;
4020 fully_initialized = 0;
4027 if (fully_initialized)
4029 free_im_list (im_info_list);
4031 free_im_list (im_custom_list);
4033 free_im_list (im_config_list);
4034 M17N_OBJECT_UNREF (load_im_info_keys);
4037 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4038 M17N_OBJECT_UNREF (minput_driver->callback_list);
4043 minput__char_to_key (int c)
4045 if (c < 0 || c >= 0x100)
4048 return one_char_symbol[c];
4052 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4057 /*** @addtogroup m17nInputMethod */
4062 @name Variables: Predefined symbols for callback commands.
4064 These are the predefined symbols that are used as the @c COMMAND
4065 argument of callback functions of an input method driver (see
4066 #MInputDriver::callback_list).
4068 Most of them do not require extra argument nor return any value;
4069 exceptions are these:
4071 Minput_get_surrounding_text: When a callback function assigned for
4072 this command is called, the first element of #MInputContext::plist
4073 has key #Minteger and the value specifies which portion of the
4074 surrounding text should be retrieved. If the value is positive,
4075 it specifies the number of characters following the current cursor
4076 position. If the value is negative, the absolute value specifies
4077 the number of characters preceding the current cursor position.
4078 If the value is zero, it means that the caller just wants to know
4079 if the surrounding text is currently supported or not.
4081 If the surrounding text is currently supported, the callback
4082 function must set the key of this element to #Mtext and the value
4083 to the retrieved M-text. The length of the M-text may be shorter
4084 than the requested number of characters, if the available text is
4085 not that long. The length can be zero in the worst case. Or, the
4086 length may be longer if an application thinks it is more efficient
4087 to return that length.
4089 If the surrounding text is not currently supported, the callback
4090 function should return without changing the first element of
4091 #MInputContext::plist.
4093 Minput_delete_surrounding_text: When a callback function assigned
4094 for this command is called, the first element of
4095 #MInputContext::plist has key #Minteger and the value specifies
4096 which portion of the surrounding text should be deleted in the
4097 same way as the case of Minput_get_surrounding_text. The callback
4098 function must delete the specified text. It should not alter
4099 #MInputContext::plist. */
4101 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4103 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4104 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4106 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4108 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4109 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4110 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4111 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4112 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4113 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4114 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4116 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4117 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4118 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4119 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4120 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4122 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4123 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4125 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4126 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4127 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4128 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4129 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4130 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4134 MSymbol Minput_preedit_start;
4135 MSymbol Minput_preedit_done;
4136 MSymbol Minput_preedit_draw;
4137 MSymbol Minput_status_start;
4138 MSymbol Minput_status_done;
4139 MSymbol Minput_status_draw;
4140 MSymbol Minput_candidates_start;
4141 MSymbol Minput_candidates_done;
4142 MSymbol Minput_candidates_draw;
4143 MSymbol Minput_set_spot;
4144 MSymbol Minput_toggle;
4145 MSymbol Minput_reset;
4146 MSymbol Minput_get_surrounding_text;
4147 MSymbol Minput_delete_surrounding_text;
4153 @name Variables: Predefined symbols for special input events.
4155 These are the predefined symbols that are used as the @c KEY
4156 argument of minput_filter (). */
4158 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4160 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4165 MSymbol Minput_focus_out;
4166 MSymbol Minput_focus_in;
4167 MSymbol Minput_focus_move;
4173 @name Variables: Predefined symbols used in input method information.
4175 These are the predefined symbols describing status of input method
4176 command and variable, and are used in a return value of
4177 minput_get_command () and minput_get_variable (). */
4179 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4181 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4182 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4186 MSymbol Mcustomized;
4187 MSymbol Mconfigured;
4193 @brief The default driver for internal input methods.
4195 The variable #minput_default_driver is the default driver for
4196 internal input methods.
4198 The member MInputDriver::open_im () searches the m17n database for
4199 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4200 $NAME\> and loads it.
4202 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4203 programmers responsibility to set it to a plist of proper callback
4204 functions. Otherwise, no feedback information (e.g. preedit text)
4205 can be shown to users.
4207 The macro M17N_INIT () sets the variable #minput_driver to the
4208 pointer to this driver so that all internal input methods use it.
4210 Therefore, unless @c minput_driver is set differently, the driver
4211 dependent arguments $ARG of the functions whose name begins with
4212 "minput_" are all ignored. */
4214 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4216 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4218 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4219 \< #Minput_method, $LANGUAGE, $NAME\>
4220 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4222 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4223 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4224 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4225 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4227 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4228 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4230 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4231 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4233 MInputDriver minput_default_driver;
4237 @brief The driver for internal input methods.
4239 The variable #minput_driver is a pointer to the input method
4240 driver that is used by internal input methods. The macro
4241 M17N_INIT () initializes it to a pointer to #minput_default_driver
4242 if <m17n<EM></EM>.h> is included. */
4244 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4246 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4247 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4248 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4249 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4251 MInputDriver *minput_driver;
4253 MSymbol Minput_driver;
4268 @brief Open an input method.
4270 The minput_open_im () function opens an input method whose
4271 language and name match $LANGUAGE and $NAME, and returns a pointer
4272 to the input method object newly allocated.
4274 This function at first decides a driver for the input method as
4277 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4278 #minput_driver is used.
4280 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4281 driver pointed to by the property value is used to open the input
4282 method. If $NAME has no such a property, @c NULL is returned.
4284 Then, the member MInputDriver::open_im () of the driver is
4287 $ARG is set in the member @c arg of the structure MInputMethod so
4288 that the driver can refer to it. */
4290 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4292 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4293 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4295 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4297 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4298 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4300 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4301 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4302 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4304 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4306 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4308 @latexonly \IPAlabel{minput_open} @endlatexonly
4313 minput_open_im (MSymbol language, MSymbol name, void *arg)
4316 MInputDriver *driver;
4320 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4321 msymbol_name (language), msymbol_name (name));
4323 driver = minput_driver;
4326 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4328 MERROR (MERROR_IM, NULL);
4331 MSTRUCT_CALLOC (im, MERROR_IM);
4332 im->language = language;
4335 im->driver = *driver;
4336 if ((*im->driver.open_im) (im) < 0)
4338 MDEBUG_PRINT (" failed\n");
4342 MDEBUG_PRINT (" ok\n");
4349 @brief Close an input method.
4351 The minput_close_im () function closes the input method $IM, which
4352 must have been created by minput_open_im (). */
4355 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4357 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4358 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4361 minput_close_im (MInputMethod *im)
4363 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4364 msymbol_name (im->name), msymbol_name (im->language));
4365 (*im->driver.close_im) (im);
4367 MDEBUG_PRINT (" done\n");
4373 @brief Create an input context.
4375 The minput_create_ic () function creates an input context object
4376 associated with input method $IM, and calls callback functions
4377 corresponding to #Minput_preedit_start, #Minput_status_start, and
4378 #Minput_status_draw in this order.
4381 If an input context is successfully created, minput_create_ic ()
4382 returns a pointer to it. Otherwise it returns @c NULL. */
4385 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4387 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4388 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4389 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4390 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4393 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4394 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4398 minput_create_ic (MInputMethod *im, void *arg)
4402 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4403 msymbol_name (im->name), msymbol_name (im->language));
4404 MSTRUCT_CALLOC (ic, MERROR_IM);
4407 ic->preedit = mtext ();
4408 ic->candidate_list = NULL;
4409 ic->produced = mtext ();
4410 ic->spot.x = ic->spot.y = 0;
4412 ic->plist = mplist ();
4413 if ((*im->driver.create_ic) (ic) < 0)
4415 MDEBUG_PRINT (" failed\n");
4416 M17N_OBJECT_UNREF (ic->preedit);
4417 M17N_OBJECT_UNREF (ic->produced);
4418 M17N_OBJECT_UNREF (ic->plist);
4423 if (im->driver.callback_list)
4425 minput_callback (ic, Minput_preedit_start);
4426 minput_callback (ic, Minput_status_start);
4427 minput_callback (ic, Minput_status_draw);
4430 MDEBUG_PRINT (" ok\n");
4437 @brief Destroy an input context.
4439 The minput_destroy_ic () function destroys the input context $IC,
4440 which must have been created by minput_create_ic (). It calls
4441 callback functions corresponding to #Minput_preedit_done,
4442 #Minput_status_done, and #Minput_candidates_done in this order. */
4445 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4447 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4448 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4449 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4450 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4451 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4455 minput_destroy_ic (MInputContext *ic)
4457 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4458 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4459 if (ic->im->driver.callback_list)
4461 minput_callback (ic, Minput_preedit_done);
4462 minput_callback (ic, Minput_status_done);
4463 minput_callback (ic, Minput_candidates_done);
4465 (*ic->im->driver.destroy_ic) (ic);
4466 M17N_OBJECT_UNREF (ic->preedit);
4467 M17N_OBJECT_UNREF (ic->produced);
4468 M17N_OBJECT_UNREF (ic->plist);
4469 MDEBUG_PRINT (" done\n");
4476 @brief Filter an input key.
4478 The minput_filter () function filters input key $KEY according to
4479 input context $IC, and calls callback functions corresponding to
4480 #Minput_preedit_draw, #Minput_status_draw, and
4481 #Minput_candidates_draw if the preedit text, the status, and the
4482 current candidate are changed respectively.
4484 To make the input method commit the current preedit text (if any)
4485 and shift to the initial state, call this function with #Mnil as
4488 To inform the input method about the focus-out event, call this
4489 function with #Minput_focus_out as $KEY.
4491 To inform the input method about the focus-in event, call this
4492 function with #Minput_focus_in as $KEY.
4494 To inform the input method about the focus-move event (i.e. input
4495 spot change within the same input context), call this function
4496 with #Minput_focus_move as $KEY.
4499 If $KEY is filtered out, this function returns 1. In that case,
4500 the caller should discard the key. Otherwise, it returns 0, and
4501 the caller should handle the key, for instance, by calling the
4502 function minput_lookup () with the same key. */
4505 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4507 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4508 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4509 #Minput_preedit_draw, #Minput_status_draw,
4510 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4513 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4514 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4515 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4516 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4518 @latexonly \IPAlabel{minput_filter} @endlatexonly
4522 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4529 if (ic->im->driver.callback_list
4530 && mtext_nchars (ic->preedit) > 0)
4531 minput_callback (ic, Minput_preedit_draw);
4533 ret = (*ic->im->driver.filter) (ic, key, arg);
4535 if (ic->im->driver.callback_list)
4537 if (ic->preedit_changed)
4538 minput_callback (ic, Minput_preedit_draw);
4539 if (ic->status_changed)
4540 minput_callback (ic, Minput_status_draw);
4541 if (ic->candidates_changed)
4542 minput_callback (ic, Minput_candidates_draw);
4551 @brief Look up a text produced in the input context.
4553 The minput_lookup () function looks up a text in the input context
4554 $IC. $KEY must be identical to the one that was used in the previous call of
4557 If a text was produced by the input method, it is concatenated
4560 This function calls #MInputDriver::lookup .
4563 If $KEY was correctly handled by the input method, this function
4564 returns 0. Otherwise, it returns -1, even though some text
4565 might be produced in $MT. */
4568 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4570 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4571 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4573 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4576 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4579 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4580 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4581 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4583 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4586 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4588 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4593 @brief Set the spot of the input context.
4595 The minput_set_spot () function sets the spot of input context $IC
4596 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4597 The semantics of these values depends on the input method driver.
4599 For instance, a driver designed to work in a CUI environment may
4600 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4601 $DESCENT . A driver designed to work in a window system may
4602 interpret $X and $Y as the pixel offsets relative to the origin of the
4603 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4604 descent pixels of the line at ($X . $Y ).
4606 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4608 $MT and $POS are the M-text and the character position at the spot.
4609 $MT may be @c NULL, in which case, the input method cannot get
4610 information about the text around the spot. */
4613 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4615 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4616 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4617 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4619 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4620 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4621 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4622 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4623 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4624 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4626 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4628 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4629 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4633 minput_set_spot (MInputContext *ic, int x, int y,
4634 int ascent, int descent, int fontsize,
4639 ic->spot.ascent = ascent;
4640 ic->spot.descent = descent;
4641 ic->spot.fontsize = fontsize;
4644 if (ic->im->driver.callback_list)
4645 minput_callback (ic, Minput_set_spot);
4650 @brief Toggle input method.
4652 The minput_toggle () function toggles the input method associated
4653 with input context $IC. */
4655 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4657 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4658 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4662 minput_toggle (MInputContext *ic)
4664 if (ic->im->driver.callback_list)
4665 minput_callback (ic, Minput_toggle);
4666 ic->active = ! ic->active;
4672 @brief Reset an input context.
4674 The minput_reset_ic () function resets input context $IC by
4675 calling a callback function corresponding to #Minput_reset. It
4676 resets the status of $IC to its initial one. As the
4677 current preedit text is deleted without commitment, if necessary,
4678 call minput_filter () with the arg @r key #Mnil to force the input
4679 method to commit the preedit in advance. */
4682 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4684 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4685 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4686 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4687 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4688 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4689 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4692 minput_reset_ic (MInputContext *ic)
4694 if (ic->im->driver.callback_list)
4695 minput_callback (ic, Minput_reset);
4701 @brief Get title and icon filename of an input method.
4703 The minput_get_title_icon () function returns a plist containing a
4704 title and icon filename (if any) of an input method specified by
4705 $LANGUAGE and $NAME.
4707 The first element of the plist has key #Mtext and the value is an
4708 M-text of the title for identifying the input method. The second
4709 element (if any) has key #Mtext and the value is an M-text of the
4710 icon image (absolute) filename for the same purpose.
4713 If there exists a specified input method and it defines an title,
4714 a plist is returned. Otherwise, NULL is returned. The caller
4715 must free the plist by m17n_object_unref (). */
4717 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4719 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4720 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4723 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4724 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4725 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4728 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4729 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4730 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4733 minput_get_title_icon (MSymbol language, MSymbol name)
4735 MInputMethodInfo *im_info;
4742 im_info = get_im_info (language, name, Mnil, Mtitle);
4743 if (! im_info || !im_info->title)
4745 mt = mtext_get_prop (im_info->title, 0, Mtext);
4747 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4750 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4753 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4754 (char *) MSYMBOL_NAME (name));
4755 file = mdatabase__find_file (buf);
4756 if (! file && language == Mt)
4758 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4759 file = mdatabase__find_file (buf);
4764 mplist_add (plist, Mtext, im_info->title);
4767 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4769 mplist_add (plist, Mtext, mt);
4770 M17N_OBJECT_UNREF (mt);
4778 @brief Get description text of an input method.
4780 The minput_get_description () function returns an M-text that
4781 describes the input method specified by $LANGUAGE and $NAME.
4784 If the specified input method has a description text, a pointer to
4785 #MText is returned. The caller has to free it by m17n_object_unref ().
4786 If the input method does not have a description text, @c NULL is
4789 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4791 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4792 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4795 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4796 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4797 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4798 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4801 minput_get_description (MSymbol language, MSymbol name)
4803 MInputMethodInfo *im_info;
4811 extra = language, language = Mt;
4813 im_info = get_im_info (language, name, extra, Mdescription);
4814 if (! im_info || ! im_info->description)
4816 M17N_OBJECT_REF (im_info->description);
4817 return im_info->description;
4823 @brief Get information about input method command(s).
4825 The minput_get_command () function returns information about
4826 the command $COMMAND of the input method specified by $LANGUAGE and
4827 $NAME. An input method command is a pseudo key event to which one
4828 or more actual input key sequences are assigned.
4830 There are two kinds of commands, global and local. A global
4831 command has a global definition, and the description and the key
4832 assignment may be inherited by a local command. Each input method
4833 defines a local command which has a local key assignment. It may
4834 also declare a local command that inherits the definition of a
4835 global command of the same name.
4837 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4838 information about a global command. Otherwise information about a
4839 local command is returned.
4841 If $COMMAND is #Mnil, information about all commands is returned.
4843 The return value is a @e well-formed plist (@ref m17nPlist) of this
4846 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4848 @c NAME is a symbol representing the command name.
4850 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4851 command has no description.
4853 @c STATUS is a symbol representing how the key assignment is decided.
4854 The value is #Mnil (the default key assignment), #Mcustomized (the
4855 key assignment is customized by per-user customization file), or
4856 #Mconfigured (the key assignment is set by the call of
4857 minput_config_command ()). For a local command only, it may also
4858 be #Minherited (the key assignment is inherited from the
4859 corresponding global command).
4861 @c KEYSEQ is a plist of one or more symbols representing a key
4862 sequence assigned to the command. If there's no KEYSEQ, the
4863 command is currently disabled (i.e. no key sequence can trigger
4864 actions of the command).
4866 If $COMMAND is not #Mnil, the first element of the returned plist
4867 contains the information about $COMMAND.
4871 If the requested information was found, a pointer to a non-empty
4872 plist is returned. As the plist is kept in the library, the
4873 caller must not modify nor free it.
4875 Otherwise (the specified input method or the specified command
4876 does not exist), @c NULL is returned. */
4878 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4880 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4881 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4882 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4883 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4885 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4886 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4887 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4888 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4889 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4891 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4892 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4895 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4897 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4900 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4902 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4904 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4907 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4908 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4909 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4910 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4911 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4912 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4915 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4916 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4917 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4918 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4920 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4921 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4925 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4926 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4929 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4934 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4936 /* Return a description of the command COMMAND of the input method
4937 specified by LANGUAGE and NAME. */
4938 MPlist *cmd = minput_get_command (langauge, name, command);
4943 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4944 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4945 return (mplist_key (plist) == Mtext
4946 ? (MText *) mplist_value (plist)
4952 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4954 MInputMethodInfo *im_info;
4958 im_info = get_im_info (language, name, Mnil, Mcommand);
4960 || ! im_info->configured_cmds
4961 || MPLIST_TAIL_P (im_info->configured_cmds))
4963 if (command == Mnil)
4964 return im_info->configured_cmds;
4965 return mplist__assq (im_info->configured_cmds, command);
4971 @brief Configure the key sequence of an input method command.
4973 The minput_config_command () function assigns a list of key
4974 sequences $KEYSEQLIST to the command $COMMAND of the input method
4975 specified by $LANGUAGE and $NAME.
4977 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4978 sequences, and each key sequence must be a plist of symbols.
4980 If $KEYSEQLIST is an empty plist, any configuration and
4981 customization of the command are cancelled, and default key
4982 sequences become effective.
4984 If $KEYSEQLIST is NULL, the configuration of the command is
4985 canceled, and the original key sequences (what saved in per-user
4986 customization file, or the default one) become effective.
4988 In the latter two cases, $COMMAND can be #Mnil to make all the
4989 commands of the input method the target of the operation.
4991 If $NAME is #Mnil, this function configures the key assignment of a
4992 global command, not that of a specific input method.
4994 The configuration takes effect for input methods opened or
4995 re-opened later in the current session. In order to make the
4996 configuration take effect for the future session, it must be saved
4997 in a per-user customization file by the function
4998 minput_save_config ().
5001 If the operation was successful, this function returns 0,
5002 otherwise returns -1. The operation fails in these cases:
5004 <li>$KEYSEQLIST is not in a valid form.
5005 <li>$COMMAND is not available for the input method.
5006 <li>$LANGUAGE and $NAME do not specify an existing input method.
5010 minput_get_commands (), minput_save_config ().
5013 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5015 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5016 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5017 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5019 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5020 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5022 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5023 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5025 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5026 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5027 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5029 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5030 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5032 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5033 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5035 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5036 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5037 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5038 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5042 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5044 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5045 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5046 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5050 minput_get_commands (), minput_save_config ().
5054 /* Add "C-x u" to the "start" command of Unicode input method. */
5056 MSymbol start_command = msymbol ("start");
5057 MSymbol unicode = msymbol ("unicode");
5058 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5060 /* At first get the current key-sequence assignment. */
5061 cmd = minput_get_command (Mt, unicode, start_command);
5064 /* The input method does not have the command "start". Here
5065 should come some error handling code. */
5067 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5068 Extract the part (KEY-SEQUENCE ...). */
5069 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5070 /* Copy it because we should not modify it directly. */
5071 key_seq_list = mplist_copy (plist);
5073 key_seq = mplist ();
5074 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5075 mplist_add (key_seq, Msymbol, msymbol ("u"));
5076 mplist_add (key_seq_list, Mplist, key_seq);
5077 m17n_object_unref (key_seq);
5079 minput_config_command (Mt, unicode, start_command, key_seq_list);
5080 m17n_object_unref (key_seq_list);
5085 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5088 MInputMethodInfo *im_info, *config;
5093 im_info = get_im_info (language, name, Mnil, Mcommand);
5095 MERROR (MERROR_IM, -1);
5096 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5098 || ! mplist__assq (im_info->configured_cmds, command)))
5099 MERROR (MERROR_IM, -1);
5100 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5102 MPLIST_DO (plist, keyseqlist)
5103 if (! check_command_keyseq (plist))
5104 MERROR (MERROR_IM, -1);
5107 config = get_config_info (im_info);
5110 if (! im_config_list)
5111 im_config_list = mplist ();
5112 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5113 config->cmds = mplist ();
5114 config->vars = mplist ();
5117 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5118 /* Nothing to do. */
5121 if (command == Mnil)
5125 /* Cancal the configuration. */
5126 if (MPLIST_TAIL_P (config->cmds))
5128 mplist_set (config->cmds, Mnil, NULL);
5132 /* Cancal the customization. */
5133 MInputMethodInfo *custom = get_custom_info (im_info);
5135 if (MPLIST_TAIL_P (config->cmds)
5136 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5137 /* Nothing to do. */
5139 mplist_set (config->cmds, Mnil, NULL);
5140 MPLIST_DO (plist, custom->cmds)
5142 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5144 mplist_add (plist, Msymbol, command);
5145 mplist_push (config->cmds, Mplist, plist);
5146 M17N_OBJECT_UNREF (plist);
5152 plist = mplist__assq (config->cmds, command);
5155 /* Cancel the configuration. */
5158 mplist__pop_unref (plist);
5160 else if (MPLIST_TAIL_P (keyseqlist))
5162 /* Cancel the customization. */
5163 MInputMethodInfo *custom = get_custom_info (im_info);
5164 int no_custom = (! custom || ! custom->cmds
5165 || ! mplist__assq (custom->cmds, command));
5171 mplist_add (config->cmds, Mplist, plist);
5172 M17N_OBJECT_UNREF (plist);
5173 plist = mplist_add (plist, Msymbol, command);
5178 mplist__pop_unref (plist);
5181 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5182 plist = MPLIST_NEXT (plist);
5183 mplist_set (plist, Mnil, NULL);
5193 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5194 if (! MPLIST_TAIL_P (plist))
5195 mplist_set (plist, Mnil, NULL);
5200 mplist_add (config->cmds, Mplist, plist);
5201 M17N_OBJECT_UNREF (plist);
5202 plist = mplist_add (plist, Msymbol, command);
5203 plist = MPLIST_NEXT (plist);
5205 MPLIST_DO (keyseqlist, keyseqlist)
5207 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5208 plist = mplist_add (plist, Mplist, pl);
5209 M17N_OBJECT_UNREF (pl);
5213 config_all_commands (im_info);
5214 im_info->tick = time (NULL);
5221 @brief Get information about input method variable(s).
5223 The minput_get_variable () function returns information about
5224 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5225 An input method variable controls behavior of an input method.
5227 There are two kinds of variables, global and local. A global
5228 variable has a global definition, and the description and the value
5229 may be inherited by a local variable. Each input method defines a
5230 local variable which has local value. It may also declare a
5231 local variable that inherits definition of a global variable of
5234 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5235 variable is returned. Otherwise information about a local variable
5238 If $VARIABLE is #Mnil, information about all variables is
5241 The return value is a @e well-formed plist (@ref m17nPlist) of this
5244 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5246 @c NAME is a symbol representing the variable name.
5248 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5249 variable has no description.
5251 @c STATUS is a symbol representing how the value is decided. The
5252 value is #Mnil (the default value), #Mcustomized (the value is
5253 customized by per-user customization file), or #Mconfigured (the
5254 value is set by the call of minput_config_variable ()). For a
5255 local variable only, it may also be #Minherited (the value is
5256 inherited from the corresponding global variable).
5258 @c VALUE is the initial value of the variable. If the key of this
5259 element is #Mt, the variable has no initial value. Otherwise, the
5260 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5263 @c VALID-VALUEs (if any) specify which values the variable can have.
5264 They have the same type (i.e. having the same key) as @c VALUE except
5265 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5266 may be a plist of two integers specifying the range of possible
5269 If there no @c VALID-VALUE, the variable can have any value as long
5270 as the type is the same as @c VALUE.
5272 If $VARIABLE is not #Mnil, the first element of the returned plist
5273 contains the information about $VARIABLE.
5277 If the requested information was found, a pointer to a non-empty
5278 plist is returned. As the plist is kept in the library, the
5279 caller must not modify nor free it.
5281 Otherwise (the specified input method or the specified variable
5282 does not exist), @c NULL is returned. */
5284 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5286 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5287 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5288 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5290 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5291 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5292 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5293 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5296 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5297 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5299 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5301 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5303 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5306 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5308 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5311 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5312 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5313 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5314 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5315 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5316 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5318 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5319 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5320 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5322 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5323 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5324 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5325 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5327 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5330 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5331 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5335 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5336 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5339 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5343 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5345 MInputMethodInfo *im_info;
5349 im_info = get_im_info (language, name, Mnil, Mvariable);
5350 if (! im_info || ! im_info->configured_vars)
5352 if (variable == Mnil)
5353 return im_info->configured_vars;
5354 return mplist__assq (im_info->configured_vars, variable);
5360 @brief Configure the value of an input method variable.
5362 The minput_config_variable () function assigns $VALUE to the
5363 variable $VARIABLE of the input method specified by $LANGUAGE and
5366 If $VALUE is a non-empty plist, it must be a plist of one element
5367 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5368 the corresponding type. That value is assigned to the variable.
5370 If $VALUE is an empty plist, any configuration and customization
5371 of the variable are canceled, and the default value is assigned to
5374 If $VALUE is NULL, the configuration of the variable is canceled,
5375 and the original value (what saved in per-user customization file,
5376 or the default value) is assigned to the variable.
5378 In the latter two cases, $VARIABLE can be #Mnil to make all the
5379 variables of the input method the target of the operation.
5381 If $NAME is #Mnil, this function configures the value of global
5382 variable, not that of a specific input method.
5384 The configuration takes effect for input methods opened or
5385 re-opened later in the current session. To make the configuration
5386 take effect for the future session, it must be saved in a per-user
5387 customization file by the function minput_save_config ().
5391 If the operation was successful, this function returns 0,
5392 otherwise returns -1. The operation fails in these cases:
5394 <li>$VALUE is not in a valid form, the type does not match the
5395 definition, or the value is our of range.
5396 <li>$VARIABLE is not available for the input method.
5397 <li>$LANGUAGE and $NAME do not specify an existing input method.
5401 minput_get_variable (), minput_save_config (). */
5403 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5405 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5406 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5408 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5409 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5410 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5412 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5413 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5415 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5416 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5418 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5419 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5421 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5422 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5424 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5425 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5426 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5427 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5431 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5433 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5434 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5435 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5439 minput_get_commands (), minput_save_config ().
5442 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5445 MInputMethodInfo *im_info, *config;
5450 im_info = get_im_info (language, name, Mnil, Mvariable);
5452 MERROR (MERROR_IM, -1);
5453 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5455 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5456 MERROR (MERROR_IM, -1);
5458 if (value && ! MPLIST_TAIL_P (value))
5460 plist = MPLIST_PLIST (plist);
5461 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5462 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5463 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5464 if (MPLIST_KEY (plist) != Mt
5465 && ! check_variable_value (value, plist))
5466 MERROR (MERROR_IM, -1);
5469 config = get_config_info (im_info);
5472 if (! im_config_list)
5473 im_config_list = mplist ();
5474 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5475 config->cmds = mplist ();
5476 config->vars = mplist ();
5479 if (! value && MPLIST_TAIL_P (config->vars))
5480 /* Nothing to do. */
5483 if (variable == Mnil)
5487 /* Cancel the configuration. */
5488 if (MPLIST_TAIL_P (config->vars))
5490 mplist_set (config->vars, Mnil, NULL);
5494 /* Cancel the customization. */
5495 MInputMethodInfo *custom = get_custom_info (im_info);
5497 if (MPLIST_TAIL_P (config->vars)
5498 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5499 /* Nothing to do. */
5501 mplist_set (config->vars, Mnil, NULL);
5502 MPLIST_DO (plist, custom->vars)
5504 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5506 mplist_add (plist, Msymbol, variable);
5507 mplist_push (config->vars, Mplist, plist);
5508 M17N_OBJECT_UNREF (plist);
5514 plist = mplist__assq (config->vars, variable);
5517 /* Cancel the configuration. */
5520 mplist__pop_unref (plist);
5522 else if (MPLIST_TAIL_P (value))
5524 /* Cancel the customization. */
5525 MInputMethodInfo *custom = get_custom_info (im_info);
5526 int no_custom = (! custom || ! custom->vars
5527 || ! mplist__assq (custom->vars, variable));
5533 mplist_add (config->vars, Mplist, plist);
5534 M17N_OBJECT_UNREF (plist);
5535 plist = mplist_add (plist, Msymbol, variable);
5540 mplist__pop_unref (plist);
5543 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5544 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5545 mplist_set (plist, Mnil ,NULL);
5553 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5554 if (! MPLIST_TAIL_P (plist))
5555 mplist_set (plist, Mnil, NULL);
5560 mplist_add (config->vars, Mplist, plist);
5561 M17N_OBJECT_UNREF (plist);
5562 plist = mplist_add (plist, Msymbol, variable);
5563 plist = MPLIST_NEXT (plist);
5565 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5568 config_all_variables (im_info);
5569 im_info->tick = time (NULL);
5576 @brief Get the name of per-user customization file.
5578 The minput_config_file () function returns the absolute path name
5579 of per-user customization file into which minput_save_config ()
5580 save configurations. It is usually @c "config.mic" under the
5581 directory @c ".m17n.d" of user's home directory. It is not assured
5582 that the file of the returned name exists nor is
5583 readable/writable. If minput_save_config () fails and returns -1,
5584 an application program might check the file, make it
5585 writable (if possible), and try minput_save_config () again.
5589 This function returns a string. As the string is kept in the
5590 library, the caller must not modify nor free it.
5593 minput_save_config ()
5596 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5598 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5599 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5600 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5601 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5602 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5603 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5604 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5609 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5610 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5613 minput_save_config ()
5617 minput_config_file ()
5621 return mdatabase__file (im_custom_mdb);
5627 @brief Save configurations in per-user customization file.
5629 The minput_save_config () function saves the configurations done
5630 so far in the current session into the per-user customization
5635 If the operation was successful, 1 is returned. If the per-user
5636 customization file is currently locked, 0 is returned. In that
5637 case, the caller may wait for a while and try again. If the
5638 configuration file is not writable, -1 is returned. In that case,
5639 the caller may check the name of the file by calling
5640 minput_config_file (), make it writable if possible, and try
5644 minput_config_file () */
5646 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5648 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5649 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5653 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5654 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5655 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5656 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5660 minput_config_file () */
5663 minput_save_config (void)
5665 MPlist *data, *tail, *plist, *p, *elt;
5669 ret = mdatabase__lock (im_custom_mdb);
5672 if (! im_config_list)
5674 update_custom_info ();
5675 if (! im_custom_list)
5676 im_custom_list = mplist ();
5678 /* At first, reflect configuration in customization. */
5679 MPLIST_DO (plist, im_config_list)
5681 MPlist *pl = MPLIST_PLIST (plist);
5682 MSymbol language, name, extra, command, variable;
5683 MInputMethodInfo *custom, *config;
5685 language = MPLIST_SYMBOL (pl);
5686 pl = MPLIST_NEXT (pl);
5687 name = MPLIST_SYMBOL (pl);
5688 pl = MPLIST_NEXT (pl);
5689 extra = MPLIST_SYMBOL (pl);
5690 pl = MPLIST_NEXT (pl);
5691 config = MPLIST_VAL (pl);
5692 custom = get_custom_info (config);
5694 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5696 MPLIST_DO (pl, config->cmds)
5698 elt = MPLIST_PLIST (pl);
5699 command = MPLIST_SYMBOL (elt);
5701 p = mplist__assq (custom->cmds, command);
5703 custom->cmds = mplist (), p = NULL;
5704 elt = MPLIST_NEXT (elt);
5707 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5708 mplist_set (p, Mnil, NULL);
5713 mplist_add (custom->cmds, Mplist, p);
5714 M17N_OBJECT_UNREF (p);
5715 mplist_add (p, Msymbol, command);
5716 p = mplist_add (p, Msymbol, Mnil);
5717 p = MPLIST_NEXT (p);
5719 mplist__conc (p, elt);
5722 MPLIST_DO (pl, config->vars)
5724 elt = MPLIST_PLIST (pl);
5725 variable = MPLIST_SYMBOL (elt);
5727 p = mplist__assq (custom->vars, variable);
5729 custom->vars = mplist (), p = NULL;
5730 elt = MPLIST_NEXT (elt);
5733 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5734 mplist_set (p, Mnil, NULL);
5739 mplist_add (custom->vars, Mplist, p);
5740 M17N_OBJECT_UNREF (p);
5741 mplist_add (p, Msymbol, variable);
5742 p = mplist_add (p, Msymbol, Mnil);
5743 p = MPLIST_NEXT (p);
5745 mplist__conc (p, elt);
5748 free_im_list (im_config_list);
5749 im_config_list = NULL;
5751 /* Next, reflect customization to the actual plist to be written. */
5752 data = tail = mplist ();
5753 MPLIST_DO (plist, im_custom_list)
5755 MPlist *pl = MPLIST_PLIST (plist);
5756 MSymbol language, name, extra;
5757 MInputMethodInfo *custom, *im_info;
5759 language = MPLIST_SYMBOL (pl);
5760 pl = MPLIST_NEXT (pl);
5761 name = MPLIST_SYMBOL (pl);
5762 pl = MPLIST_NEXT (pl);
5763 extra = MPLIST_SYMBOL (pl);
5764 pl = MPLIST_NEXT (pl);
5765 custom = MPLIST_VAL (pl);
5766 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5767 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5769 im_info = lookup_im_info (im_info_list, language, name, extra);
5773 config_all_commands (im_info);
5775 config_all_variables (im_info);
5779 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5781 MPLIST_DO (p, custom->cmds)
5782 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5784 if (! MPLIST_TAIL_P (p))
5788 mplist_add (elt, Mplist, pl);
5789 M17N_OBJECT_UNREF (pl);
5790 pl = mplist_add (pl, Msymbol, Mcommand);
5791 MPLIST_DO (p, custom->cmds)
5792 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5793 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5796 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5798 MPLIST_DO (p, custom->vars)
5799 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5801 if (! MPLIST_TAIL_P (p))
5806 mplist_add (elt, Mplist, pl);
5807 M17N_OBJECT_UNREF (pl);
5808 pl = mplist_add (pl, Msymbol, Mvariable);
5809 MPLIST_DO (p, custom->vars)
5810 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5811 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5817 mplist_push (elt, Mplist, pl);
5818 M17N_OBJECT_UNREF (pl);
5819 pl = mplist_add (pl, Msymbol, Minput_method);
5820 pl = mplist_add (pl, Msymbol, language);
5821 pl = mplist_add (pl, Msymbol, name);
5823 pl = mplist_add (pl, Msymbol, extra);
5824 tail = mplist_add (tail, Mplist, elt);
5825 M17N_OBJECT_UNREF (elt);
5829 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5830 ret = mdatabase__save (im_custom_mdb, data);
5831 mdatabase__unlock (im_custom_mdb);
5832 M17N_OBJECT_UNREF (data);
5833 return (ret < 0 ? -1 : 1);
5840 @name Obsolete functions
5843 @name Obsolete ¤Ê´Ø¿ô
5849 @brief Get a list of variables of an input method (obsolete).
5851 This function is obsolete. Use minput_get_variable () instead.
5853 The minput_get_variables () function returns a plist (#MPlist) of
5854 variables used to control the behavior of the input method
5855 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5856 (@ref m17nPlist) of the following format:
5859 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5860 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5864 @c VARNAME is a symbol representing the variable name.
5866 @c DOC-MTEXT is an M-text describing the variable.
5868 @c DEFAULT-VALUE is the default value of the variable. It is a
5869 symbol, integer, or M-text.
5871 @c VALUEs (if any) specifies the possible values of the variable.
5872 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5873 @c TO), where @c FROM and @c TO specifies a range of possible
5876 For instance, suppose an input method has the variables:
5878 @li name:intvar, description:"value is an integer",
5879 initial value:0, value-range:0..3,10,20
5881 @li name:symvar, description:"value is a symbol",
5882 initial value:nil, value-range:a, b, c, nil
5884 @li name:txtvar, description:"value is an M-text",
5885 initial value:empty text, no value-range (i.e. any text)
5887 Then, the returned plist is as follows.
5890 (intvar ("value is an integer" 0 (0 3) 10 20)
5891 symvar ("value is a symbol" nil a b c nil)
5892 txtvar ("value is an M-text" ""))
5896 If the input method uses any variables, a pointer to #MPlist is
5897 returned. As the plist is kept in the library, the caller must not
5898 modify nor free it. If the input method does not use any
5899 variable, @c NULL is returned. */
5901 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5903 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5904 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5905 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5909 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5910 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5914 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5916 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5918 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5921 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5922 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5923 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5925 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5927 @li name:intvar, ÀâÌÀ:"value is an integer",
5928 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5930 @li name:symvar, ÀâÌÀ:"value is a symbol",
5931 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5933 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5934 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5936 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5939 (intvar ("value is an integer" 0 (0 3) 10 20)
5940 symvar ("value is a symbol" nil a b c nil)
5941 txtvar ("value is an M-text" ""))
5945 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5946 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5947 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5950 minput_get_variables (MSymbol language, MSymbol name)
5952 MInputMethodInfo *im_info;
5957 im_info = get_im_info (language, name, Mnil, Mvariable);
5958 if (! im_info || ! im_info->configured_vars)
5961 M17N_OBJECT_UNREF (im_info->bc_vars);
5962 im_info->bc_vars = mplist ();
5963 MPLIST_DO (vars, im_info->configured_vars)
5965 MPlist *plist = MPLIST_PLIST (vars);
5966 MPlist *elt = mplist ();
5968 mplist_push (im_info->bc_vars, Mplist, elt);
5969 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5970 elt = MPLIST_NEXT (elt);
5971 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5972 M17N_OBJECT_UNREF (elt);
5974 return im_info->bc_vars;
5980 @brief Set the initial value of an input method variable.
5982 The minput_set_variable () function sets the initial value of
5983 input method variable $VARIABLE to $VALUE for the input method
5984 specified by $LANGUAGE and $NAME.
5986 By default, the initial value is 0.
5988 This setting gets effective in a newly opened input method.
5991 If the operation was successful, 0 is returned. Otherwise -1 is
5992 returned, and #merror_code is set to #MERROR_IM. */
5994 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5996 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5997 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5998 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6000 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6002 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6005 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6006 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6009 minput_set_variable (MSymbol language, MSymbol name,
6010 MSymbol variable, void *value)
6013 MInputMethodInfo *im_info;
6018 if (variable == Mnil)
6019 MERROR (MERROR_IM, -1);
6020 plist = minput_get_variable (language, name, variable);
6021 plist = MPLIST_PLIST (plist);
6022 plist = MPLIST_NEXT (plist);
6024 mplist_add (pl, MPLIST_KEY (plist), value);
6025 ret = minput_config_variable (language, name, variable, pl);
6026 M17N_OBJECT_UNREF (pl);
6029 im_info = get_im_info (language, name, Mnil, Mvariable);
6038 @brief Get information about input method commands.
6040 The minput_get_commands () function returns information about
6041 input method commands of the input method specified by $LANGUAGE
6042 and $NAME. An input method command is a pseudo key event to which
6043 one or more actual input key sequences are assigned.
6045 There are two kinds of commands, global and local. Global
6046 commands are used by multiple input methods for the same purpose,
6047 and have global key assignments. Local commands are used only by
6048 a specific input method, and have only local key assignments.
6050 Each input method may locally change key assignments for global
6051 commands. The global key assignment for a global command is
6052 effective only when the current input method does not have local
6053 key assignments for that command.
6055 If $NAME is #Mnil, information about global commands is returned.
6056 In this case $LANGUAGE is ignored.
6058 If $NAME is not #Mnil, information about those commands that have
6059 local key assignments in the input method specified by $LANGUAGE
6060 and $NAME is returned.
6063 If no input method commands are found, this function returns @c NULL.
6065 Otherwise, a pointer to a plist is returned. The key of each
6066 element in the plist is a symbol representing a command, and the
6067 value is a plist of the form COMMAND-INFO described below.
6069 The first element of COMMAND-INFO has the key #Mtext, and the
6070 value is an M-text describing the command.
6072 If there are no more elements, that means no key sequences are
6073 assigned to the command. Otherwise, each of the remaining
6074 elements has the key #Mplist, and the value is a plist whose keys are
6075 #Msymbol and values are symbols representing input keys, which are
6076 currently assigned to the command.
6078 As the returned plist is kept in the library, the caller must not
6079 modify nor free it. */
6081 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6083 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6084 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6085 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6086 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6088 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6089 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6090 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6091 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6093 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6094 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6095 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6098 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6099 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6101 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6102 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6106 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6108 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6109 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6110 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6112 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6113 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6114 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6117 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6118 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6119 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6120 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6121 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6123 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6124 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6127 minput_get_commands (MSymbol language, MSymbol name)
6129 MInputMethodInfo *im_info;
6134 im_info = get_im_info (language, name, Mnil, Mcommand);
6135 if (! im_info || ! im_info->configured_vars)
6137 M17N_OBJECT_UNREF (im_info->bc_cmds);
6138 im_info->bc_cmds = mplist ();
6139 MPLIST_DO (cmds, im_info->configured_cmds)
6141 MPlist *plist = MPLIST_PLIST (cmds);
6142 MPlist *elt = mplist ();
6144 mplist_push (im_info->bc_cmds, Mplist, elt);
6145 mplist_add (elt, MPLIST_SYMBOL (plist),
6146 mplist_copy (MPLIST_NEXT (plist)));
6147 M17N_OBJECT_UNREF (elt);
6149 return im_info->bc_cmds;
6155 @brief Assign a key sequence to an input method command (obsolete).
6157 This function is obsolete. Use minput_config_command () instead.
6159 The minput_assign_command_keys () function assigns input key
6160 sequence $KEYSEQ to input method command $COMMAND for the input
6161 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6162 key sequence is assigned globally no matter what $LANGUAGE is.
6163 Otherwise the key sequence is assigned locally.
6165 Each element of $KEYSEQ must have the key $Msymbol and the value
6166 must be a symbol representing an input key.
6168 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6169 globally or locally.
6171 This assignment gets effective in a newly opened input method.
6174 If the operation was successful, 0 is returned. Otherwise -1 is
6175 returned, and #merror_code is set to #MERROR_IM. */
6177 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6179 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6180 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6181 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6182 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6183 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6185 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6186 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6188 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6189 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6191 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6195 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6196 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6199 minput_assign_command_keys (MSymbol language, MSymbol name,
6200 MSymbol command, MPlist *keyseq)
6206 if (command == Mnil)
6207 MERROR (MERROR_IM, -1);
6212 if (! check_command_keyseq (keyseq))
6213 MERROR (MERROR_IM, -1);
6215 mplist_add (plist, Mplist, keyseq);
6220 ret = minput_config_command (language, name, command, keyseq);
6221 M17N_OBJECT_UNREF (keyseq);
6228 @brief Call a callback function
6230 The minput_callback () functions calls a callback function
6231 $COMMAND assigned for the input context $IC. The caller must set
6232 specific elements in $IC->plist if the callback function requires.
6235 If there exists a specified callback function, 0 is returned.
6236 Otherwise -1 is returned. By side effects, $IC->plist may be
6240 minput_callback (MInputContext *ic, MSymbol command)
6242 MInputCallbackFunc func;
6244 if (! ic->im->driver.callback_list)
6246 func = ((MInputCallbackFunc)
6247 mplist_get_func (ic->im->driver.callback_list, command));
6250 (func) (ic, command);
6257 /*** @addtogroup m17nDebug */
6263 @brief Dump an input method.
6265 The mdebug_dump_im () function prints the input method $IM in a
6266 human readable way to the stderr. $INDENT specifies how many
6267 columns to indent the lines but the first one.
6270 This function returns $IM. */
6272 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6274 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6275 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6278 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6281 mdebug_dump_im (MInputMethod *im, int indent)
6283 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6286 prefix = (char *) alloca (indent + 1);
6287 memset (prefix, 32, indent);
6288 prefix[indent] = '\0';
6290 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6291 msymbol_name (im->name));
6292 mdebug_dump_mtext (im_info->title, 0, 0);
6293 if (im->name != Mnil)
6297 MPLIST_DO (state, im_info->states)
6299 fprintf (stderr, "\n%s ", prefix);
6300 dump_im_state (MPLIST_VAL (state), indent + 2);
6303 fprintf (stderr, ")");