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));
3116 pos = to - ic->cursor_pos;
3118 MDEBUG_PRINT1 ("(%d)", pos);
3119 if (to < ic->cursor_pos)
3120 preedit_delete (ic, to, ic->cursor_pos);
3121 else if (to > ic->cursor_pos)
3122 preedit_delete (ic, ic->cursor_pos, to);
3124 else if (name == Mmove)
3126 int len = mtext_nchars (ic->preedit);
3128 = (MPLIST_SYMBOL_P (args)
3129 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3131 : MPLIST_INTEGER (args));
3137 if (pos != ic->cursor_pos)
3139 ic->cursor_pos = pos;
3140 ic->preedit_changed = 1;
3142 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3144 else if (name == Mmark)
3146 int code = marker_code (MPLIST_SYMBOL (args), 0);
3150 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3151 (void *) ic->cursor_pos);
3152 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3155 else if (name == Mpushback)
3157 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3161 if (MPLIST_SYMBOL_P (args))
3163 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3164 if (MPLIST_INTEGER_P (args))
3165 num = MPLIST_INTEGER (args);
3170 num = MPLIST_INTEGER (args);
3173 ic_info->key_head -= num;
3175 ic_info->key_head = 0;
3177 ic_info->key_head = - num;
3178 if (ic_info->key_head > ic_info->used)
3179 ic_info->key_head = ic_info->used;
3181 else if (MPLIST_MTEXT_P (args))
3183 MText *mt = MPLIST_MTEXT (args);
3184 int i, len = mtext_nchars (mt);
3187 ic_info->key_head--;
3188 for (i = 0; i < len; i++)
3190 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3191 if (ic_info->key_head + i < ic_info->used)
3192 ic_info->keys[ic_info->key_head + i] = key;
3194 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3199 MPlist *plist = MPLIST_PLIST (args), *pl;
3203 ic_info->key_head--;
3205 MPLIST_DO (pl, plist)
3207 key = MPLIST_SYMBOL (pl);
3208 if (ic_info->key_head < ic_info->used)
3209 ic_info->keys[ic_info->key_head + i] = key;
3211 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3216 else if (name == Mpop)
3218 if (ic_info->key_head < ic_info->used)
3219 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3221 else if (name == Mcall)
3223 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3224 MIMExternalFunc func = NULL;
3225 MSymbol module, func_name;
3226 MPlist *func_args, *val;
3229 module = MPLIST_SYMBOL (args);
3230 args = MPLIST_NEXT (args);
3231 func_name = MPLIST_SYMBOL (args);
3233 if (im_info->externals)
3235 MIMExternalModule *external
3236 = (MIMExternalModule *) mplist_get (im_info->externals,
3239 func = ((MIMExternalFunc)
3240 mplist_get_func (external->func_list, func_name));
3244 func_args = mplist ();
3245 mplist_add (func_args, Mt, ic);
3246 MPLIST_DO (args, MPLIST_NEXT (args))
3250 if (MPLIST_KEY (args) == Msymbol
3251 && MPLIST_KEY (args) != Mnil
3252 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3254 code = new_index (ic, ic->cursor_pos,
3255 mtext_nchars (ic->preedit),
3256 MPLIST_SYMBOL (args), ic->preedit);
3257 mplist_add (func_args, Minteger, (void *) code);
3260 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3262 val = (func) (func_args);
3263 M17N_OBJECT_UNREF (func_args);
3264 if (val && ! MPLIST_TAIL_P (val))
3265 ret = take_action_list (ic, val);
3266 M17N_OBJECT_UNREF (val);
3270 else if (name == Mshift)
3272 shift_state (ic, MPLIST_SYMBOL (args));
3274 else if (name == Mundo)
3276 int intarg = (MPLIST_TAIL_P (args)
3278 : integer_value (ic, args, 0));
3280 mtext_reset (ic->preedit);
3281 mtext_reset (ic_info->preedit_saved);
3282 mtext_reset (ic->produced);
3283 M17N_OBJECT_UNREF (ic_info->vars);
3284 ic_info->vars = mplist_copy (ic_info->vars_saved);
3285 ic->cursor_pos = ic_info->state_pos = 0;
3286 ic_info->state_key_head = ic_info->key_head
3287 = ic_info->commit_key_head = 0;
3289 shift_state (ic, Mnil);
3292 if (MPLIST_TAIL_P (args))
3297 ic_info->used += intarg;
3300 ic_info->used = intarg;
3303 else if (name == Mset || name == Madd || name == Msub
3304 || name == Mmul || name == Mdiv)
3306 MSymbol sym = MPLIST_SYMBOL (args);
3307 MPlist *value = resolve_variable (ic_info, sym);
3311 val1 = MPLIST_INTEGER (value);
3312 args = MPLIST_NEXT (args);
3313 val2 = resolve_expression (ic, args);
3315 val1 = val2, op = "=";
3316 else if (name == Madd)
3317 val1 += val2, op = "+=";
3318 else if (name == Msub)
3319 val1 -= val2, op = "-=";
3320 else if (name == Mmul)
3321 val1 *= val2, op = "*=";
3323 val1 /= val2, op = "/=";
3324 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3325 MSYMBOL_NAME (sym), op, val1, val1);
3326 mplist_set (value, Minteger, (void *) val1);
3328 else if (name == Mequal || name == Mless || name == Mgreater
3329 || name == Mless_equal || name == Mgreater_equal)
3332 MPlist *actions1, *actions2;
3335 val1 = resolve_expression (ic, args);
3336 args = MPLIST_NEXT (args);
3337 val2 = resolve_expression (ic, args);
3338 args = MPLIST_NEXT (args);
3339 actions1 = MPLIST_PLIST (args);
3340 args = MPLIST_NEXT (args);
3341 if (MPLIST_TAIL_P (args))
3344 actions2 = MPLIST_PLIST (args);
3345 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3346 if (name == Mequal ? val1 == val2
3347 : name == Mless ? val1 < val2
3348 : name == Mgreater ? val1 > val2
3349 : name == Mless_equal ? val1 <= val2
3352 MDEBUG_PRINT ("ok");
3353 ret = take_action_list (ic, actions1);
3357 MDEBUG_PRINT ("no");
3359 ret = take_action_list (ic, actions2);
3364 else if (name == Mcond)
3368 MPLIST_DO (args, args)
3373 if (! MPLIST_PLIST (args))
3375 cond = MPLIST_PLIST (args);
3376 if (resolve_expression (ic, cond) != 0)
3378 MDEBUG_PRINT1 ("(%dth)", idx);
3379 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3385 else if (name == Mcommit)
3387 preedit_commit (ic, 0);
3389 else if (name == Munhandle)
3391 preedit_commit (ic, 0);
3396 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3400 && (actions = mplist_get (im_info->macros, name)))
3402 if (take_action_list (ic, actions) < 0)
3408 if (ic->candidate_list)
3410 M17N_OBJECT_UNREF (ic->candidate_list);
3411 ic->candidate_list = NULL;
3413 if (ic->cursor_pos > 0
3414 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3417 ic->candidate_list = mtext_property_value (prop);
3418 M17N_OBJECT_REF (ic->candidate_list);
3420 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3422 ic->candidate_from = mtext_property_start (prop);
3423 ic->candidate_to = mtext_property_end (prop);
3426 if (candidate_list != ic->candidate_list)
3427 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3428 if (candidate_index != ic->candidate_index)
3429 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3430 if (candidate_show != ic->candidate_show)
3431 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3436 /* Handle the input key KEY in the current state and map specified in
3437 the input context IC. If KEY is handled correctly, return 0.
3438 Otherwise, return -1. */
3441 handle_key (MInputContext *ic)
3443 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3444 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3445 MIMMap *map = ic_info->map;
3446 MIMMap *submap = NULL;
3447 MSymbol key = ic_info->keys[ic_info->key_head];
3448 MSymbol alias = Mnil;
3451 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3452 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3456 submap = mplist_get (map->submaps, key);
3459 && (alias = msymbol_get (alias, M_key_alias))
3461 submap = mplist_get (map->submaps, alias);
3466 if (! alias || alias == key)
3467 MDEBUG_PRINT (" submap-found");
3469 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3470 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3471 ic->preedit_changed = 1;
3472 ic->cursor_pos = ic_info->state_pos;
3473 ic_info->key_head++;
3474 ic_info->map = map = submap;
3475 if (map->map_actions)
3477 MDEBUG_PRINT (" map-actions:");
3478 if (take_action_list (ic, map->map_actions) < 0)
3480 MDEBUG_PRINT ("\n");
3484 else if (map->submaps)
3486 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3488 MSymbol key = ic_info->keys[i];
3489 char *name = msymbol_name (key);
3491 if (! name[0] || ! name[1])
3492 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3496 /* If this is the terminal map or we have shifted to another
3497 state, perform branch actions (if any). */
3498 if (! map->submaps || map != ic_info->map)
3500 if (map->branch_actions)
3502 MDEBUG_PRINT (" branch-actions:");
3503 if (take_action_list (ic, map->branch_actions) < 0)
3505 MDEBUG_PRINT ("\n");
3509 /* If MAP is still not the root map, shift to the current
3511 if (ic_info->map != ic_info->state->map)
3512 shift_state (ic, ic_info->state->name);
3517 /* MAP can not handle KEY. */
3519 /* Perform branch actions if any. */
3520 if (map->branch_actions)
3522 MDEBUG_PRINT (" branch-actions:");
3523 if (take_action_list (ic, map->branch_actions) < 0)
3525 MDEBUG_PRINT ("\n");
3530 if (map == ic_info->map)
3532 /* The above branch actions didn't change the state. */
3534 /* If MAP is the root map of the initial state, and there
3535 still exist an unhandled key, it means that the current
3536 input method can not handle it. */
3537 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3538 && ic_info->key_head < ic_info->used)
3540 MDEBUG_PRINT (" unhandled\n");
3544 if (map != ic_info->state->map)
3546 /* MAP is not the root map. Shift to the root map of the
3548 shift_state (ic, ic_info->state->name);
3550 else if (! map->branch_actions)
3552 /* MAP is the root map without any default branch
3553 actions. Shift to the initial state. */
3554 shift_state (ic, Mnil);
3558 MDEBUG_PRINT ("\n");
3562 /* Initialize IC->ic_info. */
3565 init_ic_info (MInputContext *ic)
3567 MInputMethodInfo *im_info = ic->im->info;
3568 MInputContextInfo *ic_info = ic->info;
3571 MLIST_INIT1 (ic_info, keys, 8);;
3573 ic_info->markers = mplist ();
3575 ic_info->vars = mplist ();
3576 if (im_info->configured_vars)
3577 MPLIST_DO (plist, im_info->configured_vars)
3579 MPlist *pl = MPLIST_PLIST (plist);
3580 MSymbol name = MPLIST_SYMBOL (pl);
3582 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3583 if (MPLIST_KEY (pl) != Mt)
3585 MPlist *p = mplist ();
3587 mplist_push (ic_info->vars, Mplist, p);
3588 M17N_OBJECT_UNREF (p);
3589 mplist_add (p, Msymbol, name);
3590 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3593 ic_info->vars_saved = mplist_copy (ic_info->vars);
3595 if (im_info->externals)
3597 MPlist *func_args = mplist (), *plist;
3599 mplist_add (func_args, Mt, ic);
3600 MPLIST_DO (plist, im_info->externals)
3602 MIMExternalModule *external = MPLIST_VAL (plist);
3603 MIMExternalFunc func
3604 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3609 M17N_OBJECT_UNREF (func_args);
3612 ic_info->preedit_saved = mtext ();
3613 ic_info->tick = im_info->tick;
3616 /* Finalize IC->ic_info. */
3619 fini_ic_info (MInputContext *ic)
3621 MInputMethodInfo *im_info = ic->im->info;
3622 MInputContextInfo *ic_info = ic->info;
3624 if (im_info->externals)
3626 MPlist *func_args = mplist (), *plist;
3628 mplist_add (func_args, Mt, ic);
3629 MPLIST_DO (plist, im_info->externals)
3631 MIMExternalModule *external = MPLIST_VAL (plist);
3632 MIMExternalFunc func
3633 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3638 M17N_OBJECT_UNREF (func_args);
3641 MLIST_FREE1 (ic_info, keys);
3642 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3643 M17N_OBJECT_UNREF (ic_info->markers);
3644 M17N_OBJECT_UNREF (ic_info->vars);
3645 M17N_OBJECT_UNREF (ic_info->vars_saved);
3646 M17N_OBJECT_UNREF (ic_info->preceding_text);
3647 M17N_OBJECT_UNREF (ic_info->following_text);
3649 memset (ic_info, 0, sizeof (MInputContextInfo));
3653 re_init_ic (MInputContext *ic, int reload)
3655 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3656 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3657 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3659 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3660 preedit_changed = mtext_nchars (ic->preedit) > 0;
3661 cursor_pos_changed = ic->cursor_pos > 0;
3662 candidates_changed = 0;
3663 if (ic->candidate_list)
3665 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3666 M17N_OBJECT_UNREF (ic->candidate_list);
3667 ic->candidate_list = NULL;
3669 if (ic->candidate_show)
3671 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3672 ic->candidate_show = 0;
3674 if (ic->candidate_index > 0)
3676 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3677 ic->candidate_index = 0;
3678 ic->candidate_from = ic->candidate_to = 0;
3680 if (mtext_nchars (ic->produced) > 0)
3681 mtext_reset (ic->produced);
3682 if (mtext_nchars (ic->preedit) > 0)
3683 mtext_reset (ic->preedit);
3685 M17N_OBJECT_UNREF (ic->plist);
3686 ic->plist = mplist ();
3690 reload_im_info (im_info);
3691 if (! im_info->states)
3693 struct MIMState *state;
3695 M17N_OBJECT (state, free_state, MERROR_IM);
3696 state->name = msymbol ("init");
3697 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3698 MSTRUCT_CALLOC (state->map, MERROR_IM);
3699 im_info->states = mplist ();
3700 mplist_add (im_info->states, state->name, state);
3703 shift_state (ic, Mnil);
3705 ic->status_changed = status_changed;
3706 ic->preedit_changed = preedit_changed;
3707 ic->cursor_pos_changed = cursor_pos_changed;
3708 ic->candidates_changed = candidates_changed;
3712 reset_ic (MInputContext *ic, MSymbol ignore)
3714 MDEBUG_PRINT ("\n [IM] reset\n");
3719 open_im (MInputMethod *im)
3721 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3723 if (! im_info || ! im_info->states)
3724 MERROR (MERROR_IM, -1);
3731 close_im (MInputMethod *im)
3737 create_ic (MInputContext *ic)
3739 MInputContextInfo *ic_info;
3741 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3744 shift_state (ic, Mnil);
3749 destroy_ic (MInputContext *ic)
3756 check_reload (MInputContext *ic, MSymbol key)
3758 MInputMethodInfo *im_info = ic->im->info;
3759 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3763 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3767 MPLIST_DO (plist, plist)
3769 MSymbol this_key, alias;
3771 if (MPLIST_MTEXT_P (plist))
3773 MText *mt = MPLIST_MTEXT (plist);
3774 int c = mtext_ref_char (mt, 0);
3778 this_key = one_char_symbol[c];
3782 MPlist *pl = MPLIST_PLIST (plist);
3784 this_key = MPLIST_SYMBOL (pl);
3788 && (alias = msymbol_get (alias, M_key_alias))
3789 && alias != this_key);
3793 if (MPLIST_TAIL_P (plist))
3796 MDEBUG_PRINT ("\n [IM] reload");
3802 /** Handle the input key KEY in the current state and map of IC->info.
3803 If KEY is handled but no text is produced, return 0, otherwise
3809 filter (MInputContext *ic, MSymbol key, void *arg)
3811 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3812 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3815 if (check_reload (ic, key))
3818 if (! ic_info->state)
3820 ic_info->key_unhandled = 1;
3823 mtext_reset (ic->produced);
3824 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3825 M17N_OBJECT_UNREF (ic_info->preceding_text);
3826 M17N_OBJECT_UNREF (ic_info->following_text);
3827 ic_info->preceding_text = ic_info->following_text = NULL;
3828 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3829 ic_info->key_unhandled = 0;
3832 if (handle_key (ic) < 0)
3834 /* KEY was not handled. Delete it from the current key sequence. */
3835 if (ic_info->used > 0)
3837 memmove (ic_info->keys, ic_info->keys + 1,
3838 sizeof (int) * (ic_info->used - 1));
3840 if (ic_info->state_key_head > 0)
3841 ic_info->state_key_head--;
3842 if (ic_info->commit_key_head > 0)
3843 ic_info->commit_key_head--;
3845 /* This forces returning 1. */
3846 ic_info->key_unhandled = 1;
3852 reset_ic (ic, Mnil);
3853 ic_info->key_unhandled = 1;
3856 /* Break the loop if all keys were handled. */
3857 } while (ic_info->key_head < ic_info->used);
3859 /* If the current map is the root of the initial state, we should
3860 produce any preedit text in ic->produced. */
3861 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3862 preedit_commit (ic, 1);
3864 if (mtext_nchars (ic->produced) > 0)
3868 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3869 MSYMBOL_NAME (ic_info->state->name));
3870 for (i = 0; i < mtext_nchars (ic->produced); i++)
3871 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3875 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3876 Mlanguage, ic->im->language);
3878 if (ic_info->commit_key_head > 0)
3880 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3881 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3882 ic_info->used -= ic_info->commit_key_head;
3883 ic_info->key_head -= ic_info->commit_key_head;
3884 ic_info->state_key_head -= ic_info->commit_key_head;
3885 ic_info->commit_key_head = 0;
3887 if (ic_info->key_unhandled)
3890 ic_info->key_head = ic_info->state_key_head
3891 = ic_info->commit_key_head = 0;
3894 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3898 /** Return 1 if the last event or key was not handled, otherwise
3901 There is no need of looking up because ic->produced should already
3902 contain the produced text (if any).
3907 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3909 mtext_cat (mt, ic->produced);
3910 mtext_reset (ic->produced);
3911 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3915 /* Input method command handler. */
3917 /* List of all (global and local) commands.
3918 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3919 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3920 Global commands are stored as (t (t COMMAND ...)) */
3923 /* Input method variable handler. */
3926 /* Support functions for mdebug_dump_im. */
3929 dump_im_map (MPlist *map_list, int indent)
3932 MSymbol key = MPLIST_KEY (map_list);
3933 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3935 prefix = (char *) alloca (indent + 1);
3936 memset (prefix, 32, indent);
3937 prefix[indent] = '\0';
3939 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3940 if (map->map_actions)
3941 mdebug_dump_plist (map->map_actions, indent + 2);
3944 MPLIST_DO (map_list, map->submaps)
3946 fprintf (stderr, "\n%s ", prefix);
3947 dump_im_map (map_list, indent + 2);
3950 if (map->branch_actions)
3952 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3953 mdebug_dump_plist (map->branch_actions, indent + 4);
3954 fprintf (stderr, ")");
3956 fprintf (stderr, ")");
3961 dump_im_state (MIMState *state, int indent)
3966 prefix = (char *) alloca (indent + 1);
3967 memset (prefix, 32, indent);
3968 prefix[indent] = '\0';
3970 fprintf (stderr, "(%s", msymbol_name (state->name));
3971 if (state->map->submaps)
3973 MPLIST_DO (map_list, state->map->submaps)
3975 fprintf (stderr, "\n%s ", prefix);
3976 dump_im_map (map_list, indent + 2);
3979 fprintf (stderr, ")");
3987 Minput_driver = msymbol ("input-driver");
3989 Minput_preedit_start = msymbol ("input-preedit-start");
3990 Minput_preedit_done = msymbol ("input-preedit-done");
3991 Minput_preedit_draw = msymbol ("input-preedit-draw");
3992 Minput_status_start = msymbol ("input-status-start");
3993 Minput_status_done = msymbol ("input-status-done");
3994 Minput_status_draw = msymbol ("input-status-draw");
3995 Minput_candidates_start = msymbol ("input-candidates-start");
3996 Minput_candidates_done = msymbol ("input-candidates-done");
3997 Minput_candidates_draw = msymbol ("input-candidates-draw");
3998 Minput_set_spot = msymbol ("input-set-spot");
3999 Minput_focus_move = msymbol ("input-focus-move");
4000 Minput_focus_in = msymbol ("input-focus-in");
4001 Minput_focus_out = msymbol ("input-focus-out");
4002 Minput_toggle = msymbol ("input-toggle");
4003 Minput_reset = msymbol ("input-reset");
4004 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4005 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4006 Mcustomized = msymbol ("customized");
4007 Mconfigured = msymbol ("configured");
4008 Minherited = msymbol ("inherited");
4010 minput_default_driver.open_im = open_im;
4011 minput_default_driver.close_im = close_im;
4012 minput_default_driver.create_ic = create_ic;
4013 minput_default_driver.destroy_ic = destroy_ic;
4014 minput_default_driver.filter = filter;
4015 minput_default_driver.lookup = lookup;
4016 minput_default_driver.callback_list = mplist ();
4017 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4018 M17N_FUNC (reset_ic));
4019 minput_driver = &minput_default_driver;
4021 fully_initialized = 0;
4028 if (fully_initialized)
4030 free_im_list (im_info_list);
4032 free_im_list (im_custom_list);
4034 free_im_list (im_config_list);
4035 M17N_OBJECT_UNREF (load_im_info_keys);
4038 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4039 M17N_OBJECT_UNREF (minput_driver->callback_list);
4044 minput__char_to_key (int c)
4046 if (c < 0 || c >= 0x100)
4049 return one_char_symbol[c];
4053 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4058 /*** @addtogroup m17nInputMethod */
4063 @name Variables: Predefined symbols for callback commands.
4065 These are the predefined symbols that are used as the @c COMMAND
4066 argument of callback functions of an input method driver (see
4067 #MInputDriver::callback_list).
4069 Most of them do not require extra argument nor return any value;
4070 exceptions are these:
4072 Minput_get_surrounding_text: When a callback function assigned for
4073 this command is called, the first element of #MInputContext::plist
4074 has key #Minteger and the value specifies which portion of the
4075 surrounding text should be retrieved. If the value is positive,
4076 it specifies the number of characters following the current cursor
4077 position. If the value is negative, the absolute value specifies
4078 the number of characters preceding the current cursor position.
4079 If the value is zero, it means that the caller just wants to know
4080 if the surrounding text is currently supported or not.
4082 If the surrounding text is currently supported, the callback
4083 function must set the key of this element to #Mtext and the value
4084 to the retrieved M-text. The length of the M-text may be shorter
4085 than the requested number of characters, if the available text is
4086 not that long. The length can be zero in the worst case. Or, the
4087 length may be longer if an application thinks it is more efficient
4088 to return that length.
4090 If the surrounding text is not currently supported, the callback
4091 function should return without changing the first element of
4092 #MInputContext::plist.
4094 Minput_delete_surrounding_text: When a callback function assigned
4095 for this command is called, the first element of
4096 #MInputContext::plist has key #Minteger and the value specifies
4097 which portion of the surrounding text should be deleted in the
4098 same way as the case of Minput_get_surrounding_text. The callback
4099 function must delete the specified text. It should not alter
4100 #MInputContext::plist. */
4102 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4104 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4105 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4107 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4109 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4110 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4111 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4112 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4113 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4114 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4115 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4117 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4118 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4119 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4120 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4121 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4123 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4124 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4126 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4127 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4128 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4129 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4130 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4131 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4135 MSymbol Minput_preedit_start;
4136 MSymbol Minput_preedit_done;
4137 MSymbol Minput_preedit_draw;
4138 MSymbol Minput_status_start;
4139 MSymbol Minput_status_done;
4140 MSymbol Minput_status_draw;
4141 MSymbol Minput_candidates_start;
4142 MSymbol Minput_candidates_done;
4143 MSymbol Minput_candidates_draw;
4144 MSymbol Minput_set_spot;
4145 MSymbol Minput_toggle;
4146 MSymbol Minput_reset;
4147 MSymbol Minput_get_surrounding_text;
4148 MSymbol Minput_delete_surrounding_text;
4154 @name Variables: Predefined symbols for special input events.
4156 These are the predefined symbols that are used as the @c KEY
4157 argument of minput_filter (). */
4159 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4161 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4166 MSymbol Minput_focus_out;
4167 MSymbol Minput_focus_in;
4168 MSymbol Minput_focus_move;
4174 @name Variables: Predefined symbols used in input method information.
4176 These are the predefined symbols describing status of input method
4177 command and variable, and are used in a return value of
4178 minput_get_command () and minput_get_variable (). */
4180 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4182 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4183 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4187 MSymbol Mcustomized;
4188 MSymbol Mconfigured;
4194 @brief The default driver for internal input methods.
4196 The variable #minput_default_driver is the default driver for
4197 internal input methods.
4199 The member MInputDriver::open_im () searches the m17n database for
4200 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4201 $NAME\> and loads it.
4203 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4204 programmers responsibility to set it to a plist of proper callback
4205 functions. Otherwise, no feedback information (e.g. preedit text)
4206 can be shown to users.
4208 The macro M17N_INIT () sets the variable #minput_driver to the
4209 pointer to this driver so that all internal input methods use it.
4211 Therefore, unless @c minput_driver is set differently, the driver
4212 dependent arguments $ARG of the functions whose name begins with
4213 "minput_" are all ignored. */
4215 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4217 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4219 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4220 \< #Minput_method, $LANGUAGE, $NAME\>
4221 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4223 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4224 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4225 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4226 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4228 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4229 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4231 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4232 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4234 MInputDriver minput_default_driver;
4238 @brief The driver for internal input methods.
4240 The variable #minput_driver is a pointer to the input method
4241 driver that is used by internal input methods. The macro
4242 M17N_INIT () initializes it to a pointer to #minput_default_driver
4243 if <m17n<EM></EM>.h> is included. */
4245 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4247 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4248 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4249 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4250 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4252 MInputDriver *minput_driver;
4254 MSymbol Minput_driver;
4269 @brief Open an input method.
4271 The minput_open_im () function opens an input method whose
4272 language and name match $LANGUAGE and $NAME, and returns a pointer
4273 to the input method object newly allocated.
4275 This function at first decides a driver for the input method as
4278 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4279 #minput_driver is used.
4281 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4282 driver pointed to by the property value is used to open the input
4283 method. If $NAME has no such a property, @c NULL is returned.
4285 Then, the member MInputDriver::open_im () of the driver is
4288 $ARG is set in the member @c arg of the structure MInputMethod so
4289 that the driver can refer to it. */
4291 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4293 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4294 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4296 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4298 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4299 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4301 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4302 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4303 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4305 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4307 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4309 @latexonly \IPAlabel{minput_open} @endlatexonly
4314 minput_open_im (MSymbol language, MSymbol name, void *arg)
4317 MInputDriver *driver;
4321 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4322 msymbol_name (language), msymbol_name (name));
4326 MERROR (MERROR_IM, NULL);
4327 driver = minput_driver;
4331 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4333 MERROR (MERROR_IM, NULL);
4336 MSTRUCT_CALLOC (im, MERROR_IM);
4337 im->language = language;
4340 im->driver = *driver;
4341 if ((*im->driver.open_im) (im) < 0)
4343 MDEBUG_PRINT (" failed\n");
4347 MDEBUG_PRINT (" ok\n");
4354 @brief Close an input method.
4356 The minput_close_im () function closes the input method $IM, which
4357 must have been created by minput_open_im (). */
4360 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4362 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4363 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4366 minput_close_im (MInputMethod *im)
4368 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4369 msymbol_name (im->name), msymbol_name (im->language));
4370 (*im->driver.close_im) (im);
4372 MDEBUG_PRINT (" done\n");
4378 @brief Create an input context.
4380 The minput_create_ic () function creates an input context object
4381 associated with input method $IM, and calls callback functions
4382 corresponding to #Minput_preedit_start, #Minput_status_start, and
4383 #Minput_status_draw in this order.
4386 If an input context is successfully created, minput_create_ic ()
4387 returns a pointer to it. Otherwise it returns @c NULL. */
4390 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4392 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4393 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4394 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4395 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4398 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4399 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4403 minput_create_ic (MInputMethod *im, void *arg)
4407 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4408 msymbol_name (im->name), msymbol_name (im->language));
4409 MSTRUCT_CALLOC (ic, MERROR_IM);
4412 ic->preedit = mtext ();
4413 ic->candidate_list = NULL;
4414 ic->produced = mtext ();
4415 ic->spot.x = ic->spot.y = 0;
4417 ic->plist = mplist ();
4418 if ((*im->driver.create_ic) (ic) < 0)
4420 MDEBUG_PRINT (" failed\n");
4421 M17N_OBJECT_UNREF (ic->preedit);
4422 M17N_OBJECT_UNREF (ic->produced);
4423 M17N_OBJECT_UNREF (ic->plist);
4428 if (im->driver.callback_list)
4430 minput_callback (ic, Minput_preedit_start);
4431 minput_callback (ic, Minput_status_start);
4432 minput_callback (ic, Minput_status_draw);
4435 MDEBUG_PRINT (" ok\n");
4442 @brief Destroy an input context.
4444 The minput_destroy_ic () function destroys the input context $IC,
4445 which must have been created by minput_create_ic (). It calls
4446 callback functions corresponding to #Minput_preedit_done,
4447 #Minput_status_done, and #Minput_candidates_done in this order. */
4450 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4452 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4453 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4454 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4455 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4456 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4460 minput_destroy_ic (MInputContext *ic)
4462 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4463 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4464 if (ic->im->driver.callback_list)
4466 minput_callback (ic, Minput_preedit_done);
4467 minput_callback (ic, Minput_status_done);
4468 minput_callback (ic, Minput_candidates_done);
4470 (*ic->im->driver.destroy_ic) (ic);
4471 M17N_OBJECT_UNREF (ic->preedit);
4472 M17N_OBJECT_UNREF (ic->produced);
4473 M17N_OBJECT_UNREF (ic->plist);
4474 MDEBUG_PRINT (" done\n");
4481 @brief Filter an input key.
4483 The minput_filter () function filters input key $KEY according to
4484 input context $IC, and calls callback functions corresponding to
4485 #Minput_preedit_draw, #Minput_status_draw, and
4486 #Minput_candidates_draw if the preedit text, the status, and the
4487 current candidate are changed respectively.
4489 To make the input method commit the current preedit text (if any)
4490 and shift to the initial state, call this function with #Mnil as
4493 To inform the input method about the focus-out event, call this
4494 function with #Minput_focus_out as $KEY.
4496 To inform the input method about the focus-in event, call this
4497 function with #Minput_focus_in as $KEY.
4499 To inform the input method about the focus-move event (i.e. input
4500 spot change within the same input context), call this function
4501 with #Minput_focus_move as $KEY.
4504 If $KEY is filtered out, this function returns 1. In that case,
4505 the caller should discard the key. Otherwise, it returns 0, and
4506 the caller should handle the key, for instance, by calling the
4507 function minput_lookup () with the same key. */
4510 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4512 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4513 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4514 #Minput_preedit_draw, #Minput_status_draw,
4515 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4518 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4519 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4520 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4521 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4523 @latexonly \IPAlabel{minput_filter} @endlatexonly
4527 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4534 if (ic->im->driver.callback_list
4535 && mtext_nchars (ic->preedit) > 0)
4536 minput_callback (ic, Minput_preedit_draw);
4538 ret = (*ic->im->driver.filter) (ic, key, arg);
4540 if (ic->im->driver.callback_list)
4542 if (ic->preedit_changed)
4543 minput_callback (ic, Minput_preedit_draw);
4544 if (ic->status_changed)
4545 minput_callback (ic, Minput_status_draw);
4546 if (ic->candidates_changed)
4547 minput_callback (ic, Minput_candidates_draw);
4556 @brief Look up a text produced in the input context.
4558 The minput_lookup () function looks up a text in the input context
4559 $IC. $KEY must be identical to the one that was used in the previous call of
4562 If a text was produced by the input method, it is concatenated
4565 This function calls #MInputDriver::lookup .
4568 If $KEY was correctly handled by the input method, this function
4569 returns 0. Otherwise, it returns -1, even though some text
4570 might be produced in $MT. */
4573 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4575 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4576 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4578 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4581 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4584 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4585 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4586 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4588 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4591 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4593 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4598 @brief Set the spot of the input context.
4600 The minput_set_spot () function sets the spot of input context $IC
4601 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4602 The semantics of these values depends on the input method driver.
4604 For instance, a driver designed to work in a CUI environment may
4605 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4606 $DESCENT . A driver designed to work in a window system may
4607 interpret $X and $Y as the pixel offsets relative to the origin of the
4608 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4609 descent pixels of the line at ($X . $Y ).
4611 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4613 $MT and $POS are the M-text and the character position at the spot.
4614 $MT may be @c NULL, in which case, the input method cannot get
4615 information about the text around the spot. */
4618 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4620 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4621 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4622 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4624 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4625 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4626 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4627 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4628 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4629 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4631 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4633 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4634 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4638 minput_set_spot (MInputContext *ic, int x, int y,
4639 int ascent, int descent, int fontsize,
4644 ic->spot.ascent = ascent;
4645 ic->spot.descent = descent;
4646 ic->spot.fontsize = fontsize;
4649 if (ic->im->driver.callback_list)
4650 minput_callback (ic, Minput_set_spot);
4655 @brief Toggle input method.
4657 The minput_toggle () function toggles the input method associated
4658 with input context $IC. */
4660 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4662 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4663 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4667 minput_toggle (MInputContext *ic)
4669 if (ic->im->driver.callback_list)
4670 minput_callback (ic, Minput_toggle);
4671 ic->active = ! ic->active;
4677 @brief Reset an input context.
4679 The minput_reset_ic () function resets input context $IC by
4680 calling a callback function corresponding to #Minput_reset. It
4681 resets the status of $IC to its initial one. As the
4682 current preedit text is deleted without commitment, if necessary,
4683 call minput_filter () with the arg @r key #Mnil to force the input
4684 method to commit the preedit in advance. */
4687 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4689 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4690 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4691 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4692 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4693 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4694 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4697 minput_reset_ic (MInputContext *ic)
4699 if (ic->im->driver.callback_list)
4700 minput_callback (ic, Minput_reset);
4706 @brief Get title and icon filename of an input method.
4708 The minput_get_title_icon () function returns a plist containing a
4709 title and icon filename (if any) of an input method specified by
4710 $LANGUAGE and $NAME.
4712 The first element of the plist has key #Mtext and the value is an
4713 M-text of the title for identifying the input method. The second
4714 element (if any) has key #Mtext and the value is an M-text of the
4715 icon image (absolute) filename for the same purpose.
4718 If there exists a specified input method and it defines an title,
4719 a plist is returned. Otherwise, NULL is returned. The caller
4720 must free the plist by m17n_object_unref (). */
4722 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4724 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4725 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4728 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4729 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4730 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4733 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4734 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4735 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4738 minput_get_title_icon (MSymbol language, MSymbol name)
4740 MInputMethodInfo *im_info;
4747 im_info = get_im_info (language, name, Mnil, Mtitle);
4748 if (! im_info || !im_info->title)
4750 mt = mtext_get_prop (im_info->title, 0, Mtext);
4752 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4755 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4758 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4759 (char *) MSYMBOL_NAME (name));
4760 file = mdatabase__find_file (buf);
4761 if (! file && language == Mt)
4763 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4764 file = mdatabase__find_file (buf);
4769 mplist_add (plist, Mtext, im_info->title);
4772 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4774 mplist_add (plist, Mtext, mt);
4775 M17N_OBJECT_UNREF (mt);
4783 @brief Get description text of an input method.
4785 The minput_get_description () function returns an M-text that
4786 describes the input method specified by $LANGUAGE and $NAME.
4789 If the specified input method has a description text, a pointer to
4790 #MText is returned. The caller has to free it by m17n_object_unref ().
4791 If the input method does not have a description text, @c NULL is
4794 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4796 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4797 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4800 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4801 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4802 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4803 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4806 minput_get_description (MSymbol language, MSymbol name)
4808 MInputMethodInfo *im_info;
4816 extra = language, language = Mt;
4818 im_info = get_im_info (language, name, extra, Mdescription);
4819 if (! im_info || ! im_info->description)
4821 M17N_OBJECT_REF (im_info->description);
4822 return im_info->description;
4828 @brief Get information about input method command(s).
4830 The minput_get_command () function returns information about
4831 the command $COMMAND of the input method specified by $LANGUAGE and
4832 $NAME. An input method command is a pseudo key event to which one
4833 or more actual input key sequences are assigned.
4835 There are two kinds of commands, global and local. A global
4836 command has a global definition, and the description and the key
4837 assignment may be inherited by a local command. Each input method
4838 defines a local command which has a local key assignment. It may
4839 also declare a local command that inherits the definition of a
4840 global command of the same name.
4842 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4843 information about a global command. Otherwise information about a
4844 local command is returned.
4846 If $COMMAND is #Mnil, information about all commands is returned.
4848 The return value is a @e well-formed plist (@ref m17nPlist) of this
4851 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4853 @c NAME is a symbol representing the command name.
4855 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4856 command has no description.
4858 @c STATUS is a symbol representing how the key assignment is decided.
4859 The value is #Mnil (the default key assignment), #Mcustomized (the
4860 key assignment is customized by per-user customization file), or
4861 #Mconfigured (the key assignment is set by the call of
4862 minput_config_command ()). For a local command only, it may also
4863 be #Minherited (the key assignment is inherited from the
4864 corresponding global command).
4866 @c KEYSEQ is a plist of one or more symbols representing a key
4867 sequence assigned to the command. If there's no KEYSEQ, the
4868 command is currently disabled (i.e. no key sequence can trigger
4869 actions of the command).
4871 If $COMMAND is not #Mnil, the first element of the returned plist
4872 contains the information about $COMMAND.
4876 If the requested information was found, a pointer to a non-empty
4877 plist is returned. As the plist is kept in the library, the
4878 caller must not modify nor free it.
4880 Otherwise (the specified input method or the specified command
4881 does not exist), @c NULL is returned. */
4883 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4885 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4886 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4887 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4888 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4890 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4891 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4892 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4893 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4894 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4896 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4897 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4900 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4902 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4905 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4907 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4909 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4912 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4913 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4914 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4915 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4916 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4917 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4920 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4921 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4922 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4923 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4925 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4926 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4930 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4931 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4934 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4939 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4941 /* Return a description of the command COMMAND of the input method
4942 specified by LANGUAGE and NAME. */
4943 MPlist *cmd = minput_get_command (langauge, name, command);
4948 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4949 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4950 return (mplist_key (plist) == Mtext
4951 ? (MText *) mplist_value (plist)
4957 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4959 MInputMethodInfo *im_info;
4963 im_info = get_im_info (language, name, Mnil, Mcommand);
4965 || ! im_info->configured_cmds
4966 || MPLIST_TAIL_P (im_info->configured_cmds))
4968 if (command == Mnil)
4969 return im_info->configured_cmds;
4970 return mplist__assq (im_info->configured_cmds, command);
4976 @brief Configure the key sequence of an input method command.
4978 The minput_config_command () function assigns a list of key
4979 sequences $KEYSEQLIST to the command $COMMAND of the input method
4980 specified by $LANGUAGE and $NAME.
4982 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4983 sequences, and each key sequence must be a plist of symbols.
4985 If $KEYSEQLIST is an empty plist, any configuration and
4986 customization of the command are cancelled, and default key
4987 sequences become effective.
4989 If $KEYSEQLIST is NULL, the configuration of the command is
4990 canceled, and the original key sequences (what saved in per-user
4991 customization file, or the default one) become effective.
4993 In the latter two cases, $COMMAND can be #Mnil to make all the
4994 commands of the input method the target of the operation.
4996 If $NAME is #Mnil, this function configures the key assignment of a
4997 global command, not that of a specific input method.
4999 The configuration takes effect for input methods opened or
5000 re-opened later in the current session. In order to make the
5001 configuration take effect for the future session, it must be saved
5002 in a per-user customization file by the function
5003 minput_save_config ().
5006 If the operation was successful, this function returns 0,
5007 otherwise returns -1. The operation fails in these cases:
5009 <li>$KEYSEQLIST is not in a valid form.
5010 <li>$COMMAND is not available for the input method.
5011 <li>$LANGUAGE and $NAME do not specify an existing input method.
5015 minput_get_commands (), minput_save_config ().
5018 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5020 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5021 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5022 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5024 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5025 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5027 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5028 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5030 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5031 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5032 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5034 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5035 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5037 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5038 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5040 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5041 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5042 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5043 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5047 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5049 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5050 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5051 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5055 minput_get_commands (), minput_save_config ().
5059 /* Add "C-x u" to the "start" command of Unicode input method. */
5061 MSymbol start_command = msymbol ("start");
5062 MSymbol unicode = msymbol ("unicode");
5063 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5065 /* At first get the current key-sequence assignment. */
5066 cmd = minput_get_command (Mt, unicode, start_command);
5069 /* The input method does not have the command "start". Here
5070 should come some error handling code. */
5072 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5073 Extract the part (KEY-SEQUENCE ...). */
5074 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5075 /* Copy it because we should not modify it directly. */
5076 key_seq_list = mplist_copy (plist);
5078 key_seq = mplist ();
5079 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5080 mplist_add (key_seq, Msymbol, msymbol ("u"));
5081 mplist_add (key_seq_list, Mplist, key_seq);
5082 m17n_object_unref (key_seq);
5084 minput_config_command (Mt, unicode, start_command, key_seq_list);
5085 m17n_object_unref (key_seq_list);
5090 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5093 MInputMethodInfo *im_info, *config;
5098 im_info = get_im_info (language, name, Mnil, Mcommand);
5100 MERROR (MERROR_IM, -1);
5101 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5103 || ! mplist__assq (im_info->configured_cmds, command)))
5104 MERROR (MERROR_IM, -1);
5105 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5107 MPLIST_DO (plist, keyseqlist)
5108 if (! check_command_keyseq (plist))
5109 MERROR (MERROR_IM, -1);
5112 config = get_config_info (im_info);
5115 if (! im_config_list)
5116 im_config_list = mplist ();
5117 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5118 config->cmds = mplist ();
5119 config->vars = mplist ();
5122 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5123 /* Nothing to do. */
5126 if (command == Mnil)
5130 /* Cancal the configuration. */
5131 if (MPLIST_TAIL_P (config->cmds))
5133 mplist_set (config->cmds, Mnil, NULL);
5137 /* Cancal the customization. */
5138 MInputMethodInfo *custom = get_custom_info (im_info);
5140 if (MPLIST_TAIL_P (config->cmds)
5141 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5142 /* Nothing to do. */
5144 mplist_set (config->cmds, Mnil, NULL);
5145 MPLIST_DO (plist, custom->cmds)
5147 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5149 mplist_add (plist, Msymbol, command);
5150 mplist_push (config->cmds, Mplist, plist);
5151 M17N_OBJECT_UNREF (plist);
5157 plist = mplist__assq (config->cmds, command);
5160 /* Cancel the configuration. */
5163 mplist__pop_unref (plist);
5165 else if (MPLIST_TAIL_P (keyseqlist))
5167 /* Cancel the customization. */
5168 MInputMethodInfo *custom = get_custom_info (im_info);
5169 int no_custom = (! custom || ! custom->cmds
5170 || ! mplist__assq (custom->cmds, command));
5176 mplist_add (config->cmds, Mplist, plist);
5177 M17N_OBJECT_UNREF (plist);
5178 plist = mplist_add (plist, Msymbol, command);
5183 mplist__pop_unref (plist);
5186 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5187 plist = MPLIST_NEXT (plist);
5188 mplist_set (plist, Mnil, NULL);
5198 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5199 if (! MPLIST_TAIL_P (plist))
5200 mplist_set (plist, Mnil, NULL);
5205 mplist_add (config->cmds, Mplist, plist);
5206 M17N_OBJECT_UNREF (plist);
5207 plist = mplist_add (plist, Msymbol, command);
5208 plist = MPLIST_NEXT (plist);
5210 MPLIST_DO (keyseqlist, keyseqlist)
5212 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5213 plist = mplist_add (plist, Mplist, pl);
5214 M17N_OBJECT_UNREF (pl);
5218 config_all_commands (im_info);
5219 im_info->tick = time (NULL);
5226 @brief Get information about input method variable(s).
5228 The minput_get_variable () function returns information about
5229 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5230 An input method variable controls behavior of an input method.
5232 There are two kinds of variables, global and local. A global
5233 variable has a global definition, and the description and the value
5234 may be inherited by a local variable. Each input method defines a
5235 local variable which has local value. It may also declare a
5236 local variable that inherits definition of a global variable of
5239 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5240 variable is returned. Otherwise information about a local variable
5243 If $VARIABLE is #Mnil, information about all variables is
5246 The return value is a @e well-formed plist (@ref m17nPlist) of this
5249 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5251 @c NAME is a symbol representing the variable name.
5253 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5254 variable has no description.
5256 @c STATUS is a symbol representing how the value is decided. The
5257 value is #Mnil (the default value), #Mcustomized (the value is
5258 customized by per-user customization file), or #Mconfigured (the
5259 value is set by the call of minput_config_variable ()). For a
5260 local variable only, it may also be #Minherited (the value is
5261 inherited from the corresponding global variable).
5263 @c VALUE is the initial value of the variable. If the key of this
5264 element is #Mt, the variable has no initial value. Otherwise, the
5265 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5268 @c VALID-VALUEs (if any) specify which values the variable can have.
5269 They have the same type (i.e. having the same key) as @c VALUE except
5270 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5271 may be a plist of two integers specifying the range of possible
5274 If there no @c VALID-VALUE, the variable can have any value as long
5275 as the type is the same as @c VALUE.
5277 If $VARIABLE is not #Mnil, the first element of the returned plist
5278 contains the information about $VARIABLE.
5282 If the requested information was found, a pointer to a non-empty
5283 plist is returned. As the plist is kept in the library, the
5284 caller must not modify nor free it.
5286 Otherwise (the specified input method or the specified variable
5287 does not exist), @c NULL is returned. */
5289 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5291 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5292 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5293 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5295 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5296 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5297 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5298 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5301 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5302 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5304 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5306 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5308 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5311 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5313 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5316 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5317 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5318 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5319 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5320 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5321 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5323 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5324 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5325 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5327 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5328 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5329 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5330 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5332 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5335 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5336 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5340 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5341 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5344 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5348 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5350 MInputMethodInfo *im_info;
5354 im_info = get_im_info (language, name, Mnil, Mvariable);
5355 if (! im_info || ! im_info->configured_vars)
5357 if (variable == Mnil)
5358 return im_info->configured_vars;
5359 return mplist__assq (im_info->configured_vars, variable);
5365 @brief Configure the value of an input method variable.
5367 The minput_config_variable () function assigns $VALUE to the
5368 variable $VARIABLE of the input method specified by $LANGUAGE and
5371 If $VALUE is a non-empty plist, it must be a plist of one element
5372 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5373 the corresponding type. That value is assigned to the variable.
5375 If $VALUE is an empty plist, any configuration and customization
5376 of the variable are canceled, and the default value is assigned to
5379 If $VALUE is NULL, the configuration of the variable is canceled,
5380 and the original value (what saved in per-user customization file,
5381 or the default value) is assigned to the variable.
5383 In the latter two cases, $VARIABLE can be #Mnil to make all the
5384 variables of the input method the target of the operation.
5386 If $NAME is #Mnil, this function configures the value of global
5387 variable, not that of a specific input method.
5389 The configuration takes effect for input methods opened or
5390 re-opened later in the current session. To make the configuration
5391 take effect for the future session, it must be saved in a per-user
5392 customization file by the function minput_save_config ().
5396 If the operation was successful, this function returns 0,
5397 otherwise returns -1. The operation fails in these cases:
5399 <li>$VALUE is not in a valid form, the type does not match the
5400 definition, or the value is our of range.
5401 <li>$VARIABLE is not available for the input method.
5402 <li>$LANGUAGE and $NAME do not specify an existing input method.
5406 minput_get_variable (), minput_save_config (). */
5408 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5410 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5411 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5413 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5414 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5415 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5417 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5418 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5420 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5421 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5423 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5424 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5426 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5427 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5429 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5430 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5431 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5432 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5436 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5438 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5439 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5440 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5444 minput_get_commands (), minput_save_config ().
5447 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5450 MInputMethodInfo *im_info, *config;
5455 im_info = get_im_info (language, name, Mnil, Mvariable);
5457 MERROR (MERROR_IM, -1);
5458 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5460 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5461 MERROR (MERROR_IM, -1);
5463 if (value && ! MPLIST_TAIL_P (value))
5465 plist = MPLIST_PLIST (plist);
5466 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5467 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5468 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5469 if (MPLIST_KEY (plist) != Mt
5470 && ! check_variable_value (value, plist))
5471 MERROR (MERROR_IM, -1);
5474 config = get_config_info (im_info);
5477 if (! im_config_list)
5478 im_config_list = mplist ();
5479 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5480 config->cmds = mplist ();
5481 config->vars = mplist ();
5484 if (! value && MPLIST_TAIL_P (config->vars))
5485 /* Nothing to do. */
5488 if (variable == Mnil)
5492 /* Cancel the configuration. */
5493 if (MPLIST_TAIL_P (config->vars))
5495 mplist_set (config->vars, Mnil, NULL);
5499 /* Cancel the customization. */
5500 MInputMethodInfo *custom = get_custom_info (im_info);
5502 if (MPLIST_TAIL_P (config->vars)
5503 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5504 /* Nothing to do. */
5506 mplist_set (config->vars, Mnil, NULL);
5507 MPLIST_DO (plist, custom->vars)
5509 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5511 mplist_add (plist, Msymbol, variable);
5512 mplist_push (config->vars, Mplist, plist);
5513 M17N_OBJECT_UNREF (plist);
5519 plist = mplist__assq (config->vars, variable);
5522 /* Cancel the configuration. */
5525 mplist__pop_unref (plist);
5527 else if (MPLIST_TAIL_P (value))
5529 /* Cancel the customization. */
5530 MInputMethodInfo *custom = get_custom_info (im_info);
5531 int no_custom = (! custom || ! custom->vars
5532 || ! mplist__assq (custom->vars, variable));
5538 mplist_add (config->vars, Mplist, plist);
5539 M17N_OBJECT_UNREF (plist);
5540 plist = mplist_add (plist, Msymbol, variable);
5545 mplist__pop_unref (plist);
5548 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5549 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5550 mplist_set (plist, Mnil ,NULL);
5558 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5559 if (! MPLIST_TAIL_P (plist))
5560 mplist_set (plist, Mnil, NULL);
5565 mplist_add (config->vars, Mplist, plist);
5566 M17N_OBJECT_UNREF (plist);
5567 plist = mplist_add (plist, Msymbol, variable);
5568 plist = MPLIST_NEXT (plist);
5570 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5573 config_all_variables (im_info);
5574 im_info->tick = time (NULL);
5581 @brief Get the name of per-user customization file.
5583 The minput_config_file () function returns the absolute path name
5584 of per-user customization file into which minput_save_config ()
5585 save configurations. It is usually @c config.mic under the
5586 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5587 directory). It is not assured that the file of the returned name
5588 exists nor is readable/writable. If minput_save_config () fails
5589 and returns -1, an application program might check the file, make
5590 it writable (if possible), and try minput_save_config () again.
5594 This function returns a string. As the string is kept in the
5595 library, the caller must not modify nor free it.
5598 minput_save_config ()
5601 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5603 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5604 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5605 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5606 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5607 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5608 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5609 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5614 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5615 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5618 minput_save_config ()
5622 minput_config_file ()
5626 return mdatabase__file (im_custom_mdb);
5632 @brief Save configurations in per-user customization file.
5634 The minput_save_config () function saves the configurations done
5635 so far in the current session into the per-user customization
5640 If the operation was successful, 1 is returned. If the per-user
5641 customization file is currently locked, 0 is returned. In that
5642 case, the caller may wait for a while and try again. If the
5643 configuration file is not writable, -1 is returned. In that case,
5644 the caller may check the name of the file by calling
5645 minput_config_file (), make it writable if possible, and try
5649 minput_config_file () */
5651 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5653 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5654 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5658 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5659 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5660 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5661 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5665 minput_config_file () */
5668 minput_save_config (void)
5670 MPlist *data, *tail, *plist, *p, *elt;
5674 ret = mdatabase__lock (im_custom_mdb);
5677 if (! im_config_list)
5679 update_custom_info ();
5680 if (! im_custom_list)
5681 im_custom_list = mplist ();
5683 /* At first, reflect configuration in customization. */
5684 MPLIST_DO (plist, im_config_list)
5686 MPlist *pl = MPLIST_PLIST (plist);
5687 MSymbol language, name, extra, command, variable;
5688 MInputMethodInfo *custom, *config;
5690 language = MPLIST_SYMBOL (pl);
5691 pl = MPLIST_NEXT (pl);
5692 name = MPLIST_SYMBOL (pl);
5693 pl = MPLIST_NEXT (pl);
5694 extra = MPLIST_SYMBOL (pl);
5695 pl = MPLIST_NEXT (pl);
5696 config = MPLIST_VAL (pl);
5697 custom = get_custom_info (config);
5699 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5701 MPLIST_DO (pl, config->cmds)
5703 elt = MPLIST_PLIST (pl);
5704 command = MPLIST_SYMBOL (elt);
5706 p = mplist__assq (custom->cmds, command);
5708 custom->cmds = mplist (), p = NULL;
5709 elt = MPLIST_NEXT (elt);
5712 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5713 mplist_set (p, Mnil, NULL);
5718 mplist_add (custom->cmds, Mplist, p);
5719 M17N_OBJECT_UNREF (p);
5720 mplist_add (p, Msymbol, command);
5721 p = mplist_add (p, Msymbol, Mnil);
5722 p = MPLIST_NEXT (p);
5724 mplist__conc (p, elt);
5727 MPLIST_DO (pl, config->vars)
5729 elt = MPLIST_PLIST (pl);
5730 variable = MPLIST_SYMBOL (elt);
5732 p = mplist__assq (custom->vars, variable);
5734 custom->vars = mplist (), p = NULL;
5735 elt = MPLIST_NEXT (elt);
5738 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5739 mplist_set (p, Mnil, NULL);
5744 mplist_add (custom->vars, Mplist, p);
5745 M17N_OBJECT_UNREF (p);
5746 mplist_add (p, Msymbol, variable);
5747 p = mplist_add (p, Msymbol, Mnil);
5748 p = MPLIST_NEXT (p);
5750 mplist__conc (p, elt);
5753 free_im_list (im_config_list);
5754 im_config_list = NULL;
5756 /* Next, reflect customization to the actual plist to be written. */
5757 data = tail = mplist ();
5758 MPLIST_DO (plist, im_custom_list)
5760 MPlist *pl = MPLIST_PLIST (plist);
5761 MSymbol language, name, extra;
5762 MInputMethodInfo *custom, *im_info;
5764 language = MPLIST_SYMBOL (pl);
5765 pl = MPLIST_NEXT (pl);
5766 name = MPLIST_SYMBOL (pl);
5767 pl = MPLIST_NEXT (pl);
5768 extra = MPLIST_SYMBOL (pl);
5769 pl = MPLIST_NEXT (pl);
5770 custom = MPLIST_VAL (pl);
5771 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5772 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5774 im_info = lookup_im_info (im_info_list, language, name, extra);
5778 config_all_commands (im_info);
5780 config_all_variables (im_info);
5784 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5786 MPLIST_DO (p, custom->cmds)
5787 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5789 if (! MPLIST_TAIL_P (p))
5793 mplist_add (elt, Mplist, pl);
5794 M17N_OBJECT_UNREF (pl);
5795 pl = mplist_add (pl, Msymbol, Mcommand);
5796 MPLIST_DO (p, custom->cmds)
5797 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5798 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5801 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5803 MPLIST_DO (p, custom->vars)
5804 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5806 if (! MPLIST_TAIL_P (p))
5811 mplist_add (elt, Mplist, pl);
5812 M17N_OBJECT_UNREF (pl);
5813 pl = mplist_add (pl, Msymbol, Mvariable);
5814 MPLIST_DO (p, custom->vars)
5815 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5816 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5822 mplist_push (elt, Mplist, pl);
5823 M17N_OBJECT_UNREF (pl);
5824 pl = mplist_add (pl, Msymbol, Minput_method);
5825 pl = mplist_add (pl, Msymbol, language);
5826 pl = mplist_add (pl, Msymbol, name);
5828 pl = mplist_add (pl, Msymbol, extra);
5829 tail = mplist_add (tail, Mplist, elt);
5830 M17N_OBJECT_UNREF (elt);
5834 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5835 ret = mdatabase__save (im_custom_mdb, data);
5836 mdatabase__unlock (im_custom_mdb);
5837 M17N_OBJECT_UNREF (data);
5838 return (ret < 0 ? -1 : 1);
5845 @name Obsolete functions
5848 @name Obsolete ¤Ê´Ø¿ô
5854 @brief Get a list of variables of an input method (obsolete).
5856 This function is obsolete. Use minput_get_variable () instead.
5858 The minput_get_variables () function returns a plist (#MPlist) of
5859 variables used to control the behavior of the input method
5860 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5861 (@ref m17nPlist) of the following format:
5864 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5865 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5869 @c VARNAME is a symbol representing the variable name.
5871 @c DOC-MTEXT is an M-text describing the variable.
5873 @c DEFAULT-VALUE is the default value of the variable. It is a
5874 symbol, integer, or M-text.
5876 @c VALUEs (if any) specifies the possible values of the variable.
5877 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5878 @c TO), where @c FROM and @c TO specifies a range of possible
5881 For instance, suppose an input method has the variables:
5883 @li name:intvar, description:"value is an integer",
5884 initial value:0, value-range:0..3,10,20
5886 @li name:symvar, description:"value is a symbol",
5887 initial value:nil, value-range:a, b, c, nil
5889 @li name:txtvar, description:"value is an M-text",
5890 initial value:empty text, no value-range (i.e. any text)
5892 Then, the returned plist is as follows.
5895 (intvar ("value is an integer" 0 (0 3) 10 20)
5896 symvar ("value is a symbol" nil a b c nil)
5897 txtvar ("value is an M-text" ""))
5901 If the input method uses any variables, a pointer to #MPlist is
5902 returned. As the plist is kept in the library, the caller must not
5903 modify nor free it. If the input method does not use any
5904 variable, @c NULL is returned. */
5906 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5908 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5909 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5910 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5914 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5915 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5919 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5921 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5923 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5926 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5927 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5928 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5930 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5932 @li name:intvar, ÀâÌÀ:"value is an integer",
5933 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5935 @li name:symvar, ÀâÌÀ:"value is a symbol",
5936 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5938 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5939 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5941 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5944 (intvar ("value is an integer" 0 (0 3) 10 20)
5945 symvar ("value is a symbol" nil a b c nil)
5946 txtvar ("value is an M-text" ""))
5950 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5951 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5952 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5955 minput_get_variables (MSymbol language, MSymbol name)
5957 MInputMethodInfo *im_info;
5962 im_info = get_im_info (language, name, Mnil, Mvariable);
5963 if (! im_info || ! im_info->configured_vars)
5966 M17N_OBJECT_UNREF (im_info->bc_vars);
5967 im_info->bc_vars = mplist ();
5968 MPLIST_DO (vars, im_info->configured_vars)
5970 MPlist *plist = MPLIST_PLIST (vars);
5971 MPlist *elt = mplist ();
5973 mplist_push (im_info->bc_vars, Mplist, elt);
5974 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5975 elt = MPLIST_NEXT (elt);
5976 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5977 M17N_OBJECT_UNREF (elt);
5979 return im_info->bc_vars;
5985 @brief Set the initial value of an input method variable.
5987 The minput_set_variable () function sets the initial value of
5988 input method variable $VARIABLE to $VALUE for the input method
5989 specified by $LANGUAGE and $NAME.
5991 By default, the initial value is 0.
5993 This setting gets effective in a newly opened input method.
5996 If the operation was successful, 0 is returned. Otherwise -1 is
5997 returned, and #merror_code is set to #MERROR_IM. */
5999 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6001 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6002 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6003 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6005 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6007 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6010 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6011 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6014 minput_set_variable (MSymbol language, MSymbol name,
6015 MSymbol variable, void *value)
6018 MInputMethodInfo *im_info;
6023 if (variable == Mnil)
6024 MERROR (MERROR_IM, -1);
6025 plist = minput_get_variable (language, name, variable);
6026 plist = MPLIST_PLIST (plist);
6027 plist = MPLIST_NEXT (plist);
6029 mplist_add (pl, MPLIST_KEY (plist), value);
6030 ret = minput_config_variable (language, name, variable, pl);
6031 M17N_OBJECT_UNREF (pl);
6034 im_info = get_im_info (language, name, Mnil, Mvariable);
6043 @brief Get information about input method commands.
6045 The minput_get_commands () function returns information about
6046 input method commands of the input method specified by $LANGUAGE
6047 and $NAME. An input method command is a pseudo key event to which
6048 one or more actual input key sequences are assigned.
6050 There are two kinds of commands, global and local. Global
6051 commands are used by multiple input methods for the same purpose,
6052 and have global key assignments. Local commands are used only by
6053 a specific input method, and have only local key assignments.
6055 Each input method may locally change key assignments for global
6056 commands. The global key assignment for a global command is
6057 effective only when the current input method does not have local
6058 key assignments for that command.
6060 If $NAME is #Mnil, information about global commands is returned.
6061 In this case $LANGUAGE is ignored.
6063 If $NAME is not #Mnil, information about those commands that have
6064 local key assignments in the input method specified by $LANGUAGE
6065 and $NAME is returned.
6068 If no input method commands are found, this function returns @c NULL.
6070 Otherwise, a pointer to a plist is returned. The key of each
6071 element in the plist is a symbol representing a command, and the
6072 value is a plist of the form COMMAND-INFO described below.
6074 The first element of COMMAND-INFO has the key #Mtext, and the
6075 value is an M-text describing the command.
6077 If there are no more elements, that means no key sequences are
6078 assigned to the command. Otherwise, each of the remaining
6079 elements has the key #Mplist, and the value is a plist whose keys are
6080 #Msymbol and values are symbols representing input keys, which are
6081 currently assigned to the command.
6083 As the returned plist is kept in the library, the caller must not
6084 modify nor free it. */
6086 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6088 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6089 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6090 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6091 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6093 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6094 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6095 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6096 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6098 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6099 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6100 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6103 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6104 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6106 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6107 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6111 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6113 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6114 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6115 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6117 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6118 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6119 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6122 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6123 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6124 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6125 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6126 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6128 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6129 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6132 minput_get_commands (MSymbol language, MSymbol name)
6134 MInputMethodInfo *im_info;
6139 im_info = get_im_info (language, name, Mnil, Mcommand);
6140 if (! im_info || ! im_info->configured_vars)
6142 M17N_OBJECT_UNREF (im_info->bc_cmds);
6143 im_info->bc_cmds = mplist ();
6144 MPLIST_DO (cmds, im_info->configured_cmds)
6146 MPlist *plist = MPLIST_PLIST (cmds);
6147 MPlist *elt = mplist ();
6149 mplist_push (im_info->bc_cmds, Mplist, elt);
6150 mplist_add (elt, MPLIST_SYMBOL (plist),
6151 mplist_copy (MPLIST_NEXT (plist)));
6152 M17N_OBJECT_UNREF (elt);
6154 return im_info->bc_cmds;
6160 @brief Assign a key sequence to an input method command (obsolete).
6162 This function is obsolete. Use minput_config_command () instead.
6164 The minput_assign_command_keys () function assigns input key
6165 sequence $KEYSEQ to input method command $COMMAND for the input
6166 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6167 key sequence is assigned globally no matter what $LANGUAGE is.
6168 Otherwise the key sequence is assigned locally.
6170 Each element of $KEYSEQ must have the key $Msymbol and the value
6171 must be a symbol representing an input key.
6173 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6174 globally or locally.
6176 This assignment gets effective in a newly opened input method.
6179 If the operation was successful, 0 is returned. Otherwise -1 is
6180 returned, and #merror_code is set to #MERROR_IM. */
6182 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6184 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6185 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6186 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6187 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6188 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6190 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6191 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6193 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6194 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6196 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6200 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6201 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6204 minput_assign_command_keys (MSymbol language, MSymbol name,
6205 MSymbol command, MPlist *keyseq)
6211 if (command == Mnil)
6212 MERROR (MERROR_IM, -1);
6217 if (! check_command_keyseq (keyseq))
6218 MERROR (MERROR_IM, -1);
6220 mplist_add (plist, Mplist, keyseq);
6225 ret = minput_config_command (language, name, command, keyseq);
6226 M17N_OBJECT_UNREF (keyseq);
6233 @brief Call a callback function
6235 The minput_callback () functions calls a callback function
6236 $COMMAND assigned for the input context $IC. The caller must set
6237 specific elements in $IC->plist if the callback function requires.
6240 If there exists a specified callback function, 0 is returned.
6241 Otherwise -1 is returned. By side effects, $IC->plist may be
6245 minput_callback (MInputContext *ic, MSymbol command)
6247 MInputCallbackFunc func;
6249 if (! ic->im->driver.callback_list)
6251 func = ((MInputCallbackFunc)
6252 mplist_get_func (ic->im->driver.callback_list, command));
6255 (func) (ic, command);
6262 /*** @addtogroup m17nDebug */
6268 @brief Dump an input method.
6270 The mdebug_dump_im () function prints the input method $IM in a
6271 human readable way to the stderr. $INDENT specifies how many
6272 columns to indent the lines but the first one.
6275 This function returns $IM. */
6277 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6279 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6280 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6283 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6286 mdebug_dump_im (MInputMethod *im, int indent)
6288 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6291 prefix = (char *) alloca (indent + 1);
6292 memset (prefix, 32, indent);
6293 prefix[indent] = '\0';
6295 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6296 msymbol_name (im->name));
6297 mdebug_dump_mtext (im_info->title, 0, 0);
6298 if (im->name != Mnil)
6302 MPLIST_DO (state, im_info->states)
6304 fprintf (stderr, "\n%s ", prefix);
6305 dump_im_state (MPLIST_VAL (state), indent + 2);
6308 fprintf (stderr, ")");