1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mpop = msymbol ("pop");
406 Mundo = msymbol ("undo");
407 Mcall = msymbol ("call");
408 Mshift = msymbol ("shift");
409 Mselect = msymbol ("select");
410 Mshow = msymbol ("show");
411 Mhide = msymbol ("hide");
412 Mcommit = msymbol ("commit");
413 Munhandle = msymbol ("unhandle");
414 Mset = msymbol ("set");
415 Madd = msymbol ("add");
416 Msub = msymbol ("sub");
417 Mmul = msymbol ("mul");
418 Mdiv = msymbol ("div");
419 Mequal = msymbol ("=");
420 Mless = msymbol ("<");
421 Mgreater = msymbol (">");
422 Mless_equal = msymbol ("<=");
423 Mgreater_equal = msymbol (">=");
424 Mcond = msymbol ("cond");
425 Mplus = msymbol ("+");
426 Mminus = msymbol ("-");
427 Mstar = msymbol ("*");
428 Mslash = msymbol ("/");
429 Mand = msymbol ("&");
431 Mnot = msymbol ("!");
433 Mat_reload = msymbol ("@reload");
435 Mcandidates_group_size = msymbol ("candidates-group-size");
436 Mcandidates_charset = msymbol ("candidates-charset");
438 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
439 Mcandidate_index = msymbol (" candidate-index");
441 Minit = msymbol ("init");
442 Mfini = msymbol ("fini");
444 Mdescription = msymbol ("description");
445 Mcommand = msymbol ("command");
446 Mvariable = msymbol ("variable");
447 Mglobal = msymbol ("global");
448 Mconfig = msymbol ("config");
449 M_gettext = msymbol ("_");
451 load_im_info_keys = mplist ();
452 mplist_add (load_im_info_keys, Mstate, Mnil);
453 mplist_push (load_im_info_keys, Mmap, Mnil);
455 im_info_list = mplist ();
456 im_config_list = im_custom_list = NULL;
457 im_custom_mdb = NULL;
458 update_custom_info ();
460 update_global_info ();
462 fully_initialized = 1;
465 #define MINPUT__INIT() \
467 if (! fully_initialized) \
468 fully_initialize (); \
473 marker_code (MSymbol sym, int surrounding)
479 name = MSYMBOL_NAME (sym);
480 return (name[0] != '@' ? -1
481 : (((name[1] >= '0' && name[1] <= '9')
482 || name[1] == '<' || name[1] == '>' || name[1] == '='
483 || name[1] == '[' || name[1] == ']'
485 && name[2] == '\0') ? name[1]
486 : (name[1] != '+' && name[1] != '-') ? -1
487 : (name[2] == '\0' || surrounding) ? name[1]
493 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
495 MPlist *plist = mplist__assq (ic_info->vars, var);
499 plist = MPLIST_PLIST (plist);
500 return MPLIST_NEXT (plist);
504 mplist_push (ic_info->vars, Mplist, plist);
505 M17N_OBJECT_UNREF (plist);
506 plist = mplist_add (plist, Msymbol, var);
507 plist = mplist_add (plist, Minteger, (void *) 0);
512 get_surrounding_text (MInputContext *ic, int len)
516 mplist_push (ic->plist, Minteger, (void *) len);
517 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
518 && MPLIST_MTEXT_P (ic->plist))
519 mt = MPLIST_MTEXT (ic->plist);
520 mplist_pop (ic->plist);
525 delete_surrounding_text (MInputContext *ic, int pos)
527 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
529 mplist_push (ic->plist, Minteger, (void *) pos);
530 minput_callback (ic, Minput_delete_surrounding_text);
531 mplist_pop (ic->plist);
534 M17N_OBJECT_UNREF (ic_info->preceding_text);
535 ic_info->preceding_text = NULL;
539 M17N_OBJECT_UNREF (ic_info->following_text);
540 ic_info->following_text = NULL;
545 get_preceding_char (MInputContext *ic, int pos)
547 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
551 if (pos && ic_info->preceding_text)
553 len = mtext_nchars (ic_info->preceding_text);
555 return mtext_ref_char (ic_info->preceding_text, len - pos);
557 mt = get_surrounding_text (ic, - pos);
560 len = mtext_nchars (mt);
561 if (ic_info->preceding_text)
563 if (mtext_nchars (ic_info->preceding_text) < len)
565 M17N_OBJECT_UNREF (ic_info->preceding_text);
566 ic_info->preceding_text = mt;
569 M17N_OBJECT_UNREF (mt);
572 ic_info->preceding_text = mt;
575 return mtext_ref_char (ic_info->preceding_text, len - pos);
579 get_following_char (MInputContext *ic, int pos)
581 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
585 if (ic_info->following_text)
587 len = mtext_nchars (ic_info->following_text);
589 return mtext_ref_char (ic_info->following_text, pos);
591 mt = get_surrounding_text (ic, pos + 1);
594 len = mtext_nchars (mt);
595 if (ic_info->following_text)
597 if (mtext_nchars (ic_info->following_text) < len)
599 M17N_OBJECT_UNREF (ic_info->following_text);
600 ic_info->following_text = mt;
603 M17N_OBJECT_UNREF (mt);
606 ic_info->following_text = mt;
609 return mtext_ref_char (ic_info->following_text, pos);
613 surrounding_pos (MSymbol sym)
619 name = MSYMBOL_NAME (sym);
621 && (name[1] == '-' || name[1] == '+')
622 && name[2] >= '1' && name[2] <= '9')
623 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
628 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
630 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
632 MText *preedit = ic->preedit;
633 int len = mtext_nchars (preedit);
637 if (MPLIST_INTEGER_P (arg))
638 return MPLIST_INTEGER (arg);
640 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
643 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
647 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
650 return ic_info->key_head;
651 if ((code == '-' || code == '+'))
653 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
657 pos = atoi (name + 1);
659 return get_preceding_char (ic, 0);
661 pos = ic->cursor_pos + pos;
663 pos = ic->cursor_pos + pos - 1;
666 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
667 return mtext_ref_char (ic->produced,
668 mtext_len (ic->produced) + pos);
669 return get_preceding_char (ic, - pos);
672 return get_following_char (ic, pos - len);
675 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
677 else if (code >= '0' && code <= '9')
679 else if (code == '=')
680 pos = ic->cursor_pos;
681 else if (code == '[')
682 pos = ic->cursor_pos - 1;
683 else if (code == ']')
684 pos = ic->cursor_pos + 1;
685 else if (code == '<')
687 else if (code == '>')
689 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
693 parse_expression (MPlist *plist)
697 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
699 if (! MPLIST_PLIST_P (plist))
701 plist = MPLIST_PLIST (plist);
702 op = MPLIST_SYMBOL (plist);
703 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
704 && op != Mand && op != Mor && op != Mnot
705 && op != Mless && op != Mgreater && op != Mequal
706 && op != Mless_equal && op != Mgreater_equal)
707 MERROR (MERROR_IM, -1);
708 MPLIST_DO (plist, MPLIST_NEXT (plist))
709 if (parse_expression (plist) < 0)
715 resolve_expression (MInputContext *ic, MPlist *plist)
720 if (MPLIST_INTEGER_P (plist))
721 return MPLIST_INTEGER (plist);
722 if (MPLIST_SYMBOL_P (plist))
723 return integer_value (ic, plist, NULL, 1);
724 if (! MPLIST_PLIST_P (plist))
726 plist = MPLIST_PLIST (plist);
727 if (! MPLIST_SYMBOL_P (plist))
729 op = MPLIST_SYMBOL (plist);
730 plist = MPLIST_NEXT (plist);
731 val = resolve_expression (ic, plist);
733 MPLIST_DO (plist, MPLIST_NEXT (plist))
734 val += resolve_expression (ic, plist);
735 else if (op == Mminus)
736 MPLIST_DO (plist, MPLIST_NEXT (plist))
737 val -= resolve_expression (ic, plist);
738 else if (op == Mstar)
739 MPLIST_DO (plist, MPLIST_NEXT (plist))
740 val *= resolve_expression (ic, plist);
741 else if (op == Mslash)
742 MPLIST_DO (plist, MPLIST_NEXT (plist))
743 val /= resolve_expression (ic, plist);
745 MPLIST_DO (plist, MPLIST_NEXT (plist))
746 val &= resolve_expression (ic, plist);
748 MPLIST_DO (plist, MPLIST_NEXT (plist))
749 val |= resolve_expression (ic, plist);
752 else if (op == Mless)
753 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
754 else if (op == Mequal)
755 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
756 else if (op == Mgreater)
757 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
758 else if (op == Mless_equal)
759 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
760 else if (op == Mgreater_equal)
761 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
765 /* Parse PLIST as an action list. PLIST should have this form:
766 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
767 Return 0 if successfully parsed, otherwise return -1. */
770 parse_action_list (MPlist *plist, MPlist *macros)
772 MPLIST_DO (plist, plist)
774 if (MPLIST_MTEXT_P (plist))
776 /* This is a short form of (insert MTEXT). */
777 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
778 MERROR (MERROR_IM, -1); */
780 else if (MPLIST_PLIST_P (plist)
781 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
782 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
786 /* This is a short form of (insert (GROUPS *)). */
787 MPLIST_DO (pl, MPLIST_PLIST (plist))
789 if (MPLIST_PLIST_P (pl))
793 MPLIST_DO (elt, MPLIST_PLIST (pl))
794 if (! MPLIST_MTEXT_P (elt)
795 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
796 MERROR (MERROR_IM, -1);
800 if (! MPLIST_MTEXT_P (pl)
801 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
802 MERROR (MERROR_IM, -1);
806 else if (MPLIST_INTEGER_P (plist))
808 int c = MPLIST_INTEGER (plist);
810 if (c < 0 || c > MCHAR_MAX)
811 MERROR (MERROR_IM, -1);
813 else if (MPLIST_PLIST_P (plist)
814 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
816 MPlist *pl = MPLIST_PLIST (plist);
817 MSymbol action_name = MPLIST_SYMBOL (pl);
819 pl = MPLIST_NEXT (pl);
821 if (action_name == M_candidates)
823 /* This is an already regularised action. */
826 if (action_name == Minsert)
828 if (MPLIST_MTEXT_P (pl))
830 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
831 MERROR (MERROR_IM, -1);
833 else if (MPLIST_INTEGER_P (pl))
835 int c = MPLIST_INTEGER (pl);
837 if (c < 0 || c > MCHAR_MAX)
838 MERROR (MERROR_IM, -1);
840 else if (MPLIST_PLIST_P (pl))
842 MPLIST_DO (pl, MPLIST_PLIST (pl))
844 if (MPLIST_PLIST_P (pl))
848 MPLIST_DO (elt, MPLIST_PLIST (pl))
849 if (! MPLIST_MTEXT_P (elt)
850 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
851 MERROR (MERROR_IM, -1);
855 if (! MPLIST_MTEXT_P (pl)
856 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
857 MERROR (MERROR_IM, -1);
861 else if (! MPLIST_SYMBOL_P (pl))
862 MERROR (MERROR_IM, -1);
864 else if (action_name == Mselect
865 || action_name == Mdelete
866 || action_name == Mmove)
868 if (parse_expression (pl) < 0)
871 else if (action_name == Mmark
872 || action_name == Mcall
873 || action_name == Mshift)
875 if (! MPLIST_SYMBOL_P (pl))
876 MERROR (MERROR_IM, -1);
878 else if (action_name == Mundo)
880 if (! MPLIST_TAIL_P (pl))
882 if (! MPLIST_SYMBOL_P (pl)
883 && ! MPLIST_INTEGER_P (pl))
884 MERROR (MERROR_IM, -1);
887 else if (action_name == Mpushback)
889 if (MPLIST_MTEXT_P (pl))
891 MText *mt = MPLIST_MTEXT (pl);
893 if (mtext_nchars (mt) != mtext_nbytes (mt))
894 MERROR (MERROR_IM, -1);
896 else if (MPLIST_PLIST_P (pl))
900 MPLIST_DO (p, MPLIST_PLIST (pl))
901 if (! MPLIST_SYMBOL_P (p))
902 MERROR (MERROR_IM, -1);
904 else if (! MPLIST_INTEGER_P (pl))
905 MERROR (MERROR_IM, -1);
907 else if (action_name == Mset || action_name == Madd
908 || action_name == Msub || action_name == Mmul
909 || action_name == Mdiv)
911 if (! MPLIST_SYMBOL_P (pl))
912 MERROR (MERROR_IM, -1);
913 if (parse_expression (MPLIST_NEXT (pl)) < 0)
916 else if (action_name == Mequal || action_name == Mless
917 || action_name == Mgreater || action_name == Mless_equal
918 || action_name == Mgreater_equal)
920 if (parse_expression (pl) < 0
921 || parse_expression (MPLIST_NEXT (pl)) < 0)
923 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
924 if (! MPLIST_PLIST_P (pl))
925 MERROR (MERROR_IM, -1);
926 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
927 MERROR (MERROR_IM, -1);
928 pl = MPLIST_NEXT (pl);
929 if (MPLIST_PLIST_P (pl)
930 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
931 MERROR (MERROR_IM, -1);
933 else if (action_name == Mshow || action_name == Mhide
934 || action_name == Mcommit || action_name == Munhandle
935 || action_name == Mpop)
937 else if (action_name == Mcond)
940 if (! MPLIST_PLIST_P (pl))
941 MERROR (MERROR_IM, -1);
943 else if (! macros || ! mplist_get (macros, action_name))
944 MERROR (MERROR_IM, -1);
946 else if (! MPLIST_SYMBOL_P (plist))
947 MERROR (MERROR_IM, -1);
954 resolve_command (MPlist *cmds, MSymbol command)
958 if (! cmds || ! (plist = mplist__assq (cmds, command)))
960 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
961 plist = MPLIST_NEXT (plist);
962 plist = MPLIST_NEXT (plist);
963 plist = MPLIST_NEXT (plist);
967 /* Load a translation into MAP from PLIST.
969 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
972 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
973 MPlist *branch_actions, MPlist *macros)
978 if (MPLIST_MTEXT_P (keylist))
980 MText *mt = MPLIST_MTEXT (keylist);
982 len = mtext_nchars (mt);
983 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
985 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
986 for (i = 0; i < len; i++)
987 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
993 if (MFAILP (MPLIST_PLIST_P (keylist)))
995 elt = MPLIST_PLIST (keylist);
996 len = MPLIST_LENGTH (elt);
997 if (MFAILP (len > 0))
999 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1000 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1002 if (MPLIST_INTEGER_P (elt))
1004 int c = MPLIST_INTEGER (elt);
1006 if (MFAILP (c >= 0 && c < 0x100))
1008 keyseq[i] = one_char_symbol[c];
1012 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1014 keyseq[i] = MPLIST_SYMBOL (elt);
1019 for (i = 0; i < len; i++)
1021 MIMMap *deeper = NULL;
1024 deeper = mplist_get (map->submaps, keyseq[i]);
1026 map->submaps = mplist ();
1029 /* Fixme: It is better to make all deeper maps at once. */
1030 MSTRUCT_CALLOC (deeper, MERROR_IM);
1031 mplist_put (map->submaps, keyseq[i], deeper);
1036 /* We reach a terminal map. */
1037 if (map->map_actions
1038 || map->branch_actions)
1039 /* This map is already defined. We avoid overriding it. */
1042 if (! MPLIST_TAIL_P (map_actions))
1044 if (parse_action_list (map_actions, macros) < 0)
1045 MERROR (MERROR_IM, -1);
1046 map->map_actions = map_actions;
1050 map->branch_actions = branch_actions;
1051 M17N_OBJECT_REF (branch_actions);
1057 /* Load a branch from PLIST into MAP. PLIST has this form:
1058 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1061 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1064 MPlist *branch_actions;
1066 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1068 map_name = MPLIST_SYMBOL (plist);
1069 plist = MPLIST_NEXT (plist);
1070 if (MPLIST_TAIL_P (plist))
1071 branch_actions = NULL;
1072 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1075 branch_actions = plist;
1076 if (map_name == Mnil)
1078 map->branch_actions = branch_actions;
1080 M17N_OBJECT_REF (branch_actions);
1082 else if (map_name == Mt)
1084 map->map_actions = branch_actions;
1086 M17N_OBJECT_REF (branch_actions);
1088 else if (im_info->maps)
1090 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1091 if (! plist && im_info->configured_vars)
1093 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1095 if (p && MPLIST_PLIST_P (p))
1097 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1098 if (MPLIST_SYMBOL_P (p))
1099 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1104 MPLIST_DO (plist, plist)
1106 MPlist *keylist, *map_actions;
1108 if (! MPLIST_PLIST_P (plist))
1109 MERROR (MERROR_IM, -1);
1110 keylist = MPLIST_PLIST (plist);
1111 map_actions = MPLIST_NEXT (keylist);
1112 if (MPLIST_SYMBOL_P (keylist))
1114 MSymbol command = MPLIST_SYMBOL (keylist);
1117 if (MFAILP (command != Mat_reload))
1119 pl = resolve_command (im_info->configured_cmds, command);
1123 load_translation (map, pl, map_actions, branch_actions,
1127 load_translation (map, keylist, map_actions, branch_actions,
1136 /* Load a macro from PLIST into IM_INFO->macros.
1137 PLIST has this from:
1138 PLIST ::= ( MACRO-NAME ACTION * )
1139 IM_INFO->macros is a plist of macro names vs action list. */
1142 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1147 if (! MPLIST_SYMBOL_P (plist))
1148 MERROR (MERROR_IM, -1);
1149 name = MPLIST_SYMBOL (plist);
1150 plist = MPLIST_NEXT (plist);
1151 if (MPLIST_TAIL_P (plist)
1152 || parse_action_list (plist, im_info->macros) < 0)
1153 MERROR (MERROR_IM, -1);
1154 pl = mplist_get (im_info->macros, name);
1155 M17N_OBJECT_UNREF (pl);
1156 mplist_put (im_info->macros, name, plist);
1157 M17N_OBJECT_REF (plist);
1161 /* Load an external module from PLIST into IM_INFO->externals.
1162 PLIST has this form:
1163 PLIST ::= ( MODULE-NAME FUNCTION * )
1164 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1167 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1172 MIMExternalModule *external;
1176 if (MPLIST_MTEXT_P (plist))
1177 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1178 else if (MPLIST_SYMBOL_P (plist))
1179 module = MPLIST_SYMBOL (plist);
1180 module_file = alloca (strlen (MSYMBOL_NAME (module))
1181 + strlen (DLOPEN_SHLIB_EXT) + 1);
1182 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1184 handle = dlopen (module_file, RTLD_NOW);
1185 if (MFAILP (handle))
1187 fprintf (stderr, "%s\n", dlerror ());
1190 func_list = mplist ();
1191 MPLIST_DO (plist, MPLIST_NEXT (plist))
1193 if (! MPLIST_SYMBOL_P (plist))
1194 MERROR_GOTO (MERROR_IM, err_label);
1195 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1198 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1201 MSTRUCT_MALLOC (external, MERROR_IM);
1202 external->handle = handle;
1203 external->func_list = func_list;
1204 mplist_add (im_info->externals, module, external);
1209 M17N_OBJECT_UNREF (func_list);
1214 free_map (MIMMap *map, int top)
1219 M17N_OBJECT_UNREF (map->map_actions);
1222 MPLIST_DO (plist, map->submaps)
1223 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1224 M17N_OBJECT_UNREF (map->submaps);
1226 M17N_OBJECT_UNREF (map->branch_actions);
1231 free_state (void *object)
1233 MIMState *state = object;
1235 M17N_OBJECT_UNREF (state->title);
1237 free_map (state->map, 1);
1241 /** Load a state from PLIST into a newly allocated state object.
1242 PLIST has this form:
1243 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1244 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1245 Return the state object. */
1248 load_state (MInputMethodInfo *im_info, MPlist *plist)
1252 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1254 M17N_OBJECT (state, free_state, MERROR_IM);
1255 state->name = MPLIST_SYMBOL (plist);
1256 plist = MPLIST_NEXT (plist);
1257 if (MPLIST_MTEXT_P (plist))
1259 state->title = MPLIST_MTEXT (plist);
1260 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1261 Mlanguage, im_info->language);
1262 M17N_OBJECT_REF (state->title);
1263 plist = MPLIST_NEXT (plist);
1265 MSTRUCT_CALLOC (state->map, MERROR_IM);
1266 MPLIST_DO (plist, plist)
1268 if (MFAILP (MPLIST_PLIST_P (plist)))
1270 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1275 /* Return a newly created IM_INFO for an input method specified by
1276 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1278 static MInputMethodInfo *
1279 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1282 MInputMethodInfo *im_info;
1285 if (name == Mnil && extra == Mnil)
1286 language = Mt, extra = Mglobal;
1287 MSTRUCT_CALLOC (im_info, MERROR_IM);
1289 im_info->language = language;
1290 im_info->name = name;
1291 im_info->extra = extra;
1294 mplist_add (plist, Mplist, elt);
1295 M17N_OBJECT_UNREF (elt);
1296 elt = mplist_add (elt, Msymbol, language);
1297 elt = mplist_add (elt, Msymbol, name);
1298 elt = mplist_add (elt, Msymbol, extra);
1299 mplist_add (elt, Mt, im_info);
1305 fini_im_info (MInputMethodInfo *im_info)
1309 M17N_OBJECT_UNREF (im_info->cmds);
1310 M17N_OBJECT_UNREF (im_info->configured_cmds);
1311 M17N_OBJECT_UNREF (im_info->bc_cmds);
1312 M17N_OBJECT_UNREF (im_info->vars);
1313 M17N_OBJECT_UNREF (im_info->configured_vars);
1314 M17N_OBJECT_UNREF (im_info->bc_vars);
1315 M17N_OBJECT_UNREF (im_info->description);
1316 M17N_OBJECT_UNREF (im_info->title);
1317 if (im_info->states)
1319 MPLIST_DO (plist, im_info->states)
1321 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1323 M17N_OBJECT_UNREF (state);
1325 M17N_OBJECT_UNREF (im_info->states);
1328 if (im_info->macros)
1330 MPLIST_DO (plist, im_info->macros)
1331 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1332 M17N_OBJECT_UNREF (im_info->macros);
1335 if (im_info->externals)
1337 MPLIST_DO (plist, im_info->externals)
1339 MIMExternalModule *external = MPLIST_VAL (plist);
1341 dlclose (external->handle);
1342 M17N_OBJECT_UNREF (external->func_list);
1344 MPLIST_KEY (plist) = Mt;
1346 M17N_OBJECT_UNREF (im_info->externals);
1350 MPLIST_DO (plist, im_info->maps)
1352 MPlist *p = MPLIST_PLIST (plist);
1354 M17N_OBJECT_UNREF (p);
1356 M17N_OBJECT_UNREF (im_info->maps);
1363 free_im_info (MInputMethodInfo *im_info)
1365 fini_im_info (im_info);
1370 free_im_list (MPlist *plist)
1374 MPLIST_DO (pl, plist)
1376 MInputMethodInfo *im_info;
1378 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1379 im_info = MPLIST_VAL (elt);
1380 free_im_info (im_info);
1382 M17N_OBJECT_UNREF (plist);
1385 static MInputMethodInfo *
1386 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1388 if (name == Mnil && extra == Mnil)
1389 language = Mt, extra = Mglobal;
1390 while ((plist = mplist__assq (plist, language)))
1392 MPlist *elt = MPLIST_PLIST (plist);
1394 plist = MPLIST_NEXT (plist);
1395 elt = MPLIST_NEXT (elt);
1396 if (MPLIST_SYMBOL (elt) != name)
1398 elt = MPLIST_NEXT (elt);
1399 if (MPLIST_SYMBOL (elt) != extra)
1401 elt = MPLIST_NEXT (elt);
1402 return MPLIST_VAL (elt);
1407 static void load_im_info (MPlist *, MInputMethodInfo *);
1409 #define get_custom_info(im_info) \
1411 ? lookup_im_info (im_custom_list, (im_info)->language, \
1412 (im_info)->name, (im_info)->extra) \
1415 #define get_config_info(im_info) \
1417 ? lookup_im_info (im_config_list, (im_info)->language, \
1418 (im_info)->name, (im_info)->extra) \
1422 update_custom_info (void)
1428 if (mdatabase__check (im_custom_mdb) > 0)
1433 MDatabaseInfo *custom_dir_info;
1434 char custom_path[PATH_MAX + 1];
1436 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1437 if (! custom_dir_info->filename
1438 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1440 strcpy (custom_path, custom_dir_info->filename);
1441 strcat (custom_path, CUSTOM_FILE);
1442 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1448 free_im_list (im_custom_list);
1449 im_custom_list = NULL;
1451 plist = mdatabase_load (im_custom_mdb);
1454 im_custom_list = mplist ();
1456 MPLIST_DO (pl, plist)
1458 MSymbol language, name, extra;
1459 MInputMethodInfo *im_info;
1460 MPlist *im_data, *p;
1462 if (! MPLIST_PLIST_P (pl))
1464 p = MPLIST_PLIST (pl);
1465 im_data = MPLIST_NEXT (p);
1466 if (! MPLIST_PLIST_P (p))
1468 p = MPLIST_PLIST (p);
1469 if (! MPLIST_SYMBOL_P (p)
1470 || MPLIST_SYMBOL (p) != Minput_method)
1472 p = MPLIST_NEXT (p);
1473 if (! MPLIST_SYMBOL_P (p))
1475 language = MPLIST_SYMBOL (p);
1476 p = MPLIST_NEXT (p);
1477 if (! MPLIST_SYMBOL_P (p))
1479 name = MPLIST_SYMBOL (p);
1480 p = MPLIST_NEXT (p);
1481 if (MPLIST_TAIL_P (p))
1483 else if (MPLIST_SYMBOL_P (p))
1484 extra = MPLIST_SYMBOL (p);
1485 if (language == Mnil || (name == Mnil && extra == Mnil))
1487 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1488 load_im_info (im_data, im_info);
1490 M17N_OBJECT_UNREF (plist);
1495 update_global_info (void)
1501 int ret = mdatabase__check (global_info->mdb);
1505 fini_im_info (global_info);
1509 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1513 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1515 if (! global_info->mdb
1516 || ! (plist = mdatabase_load (global_info->mdb)))
1519 load_im_info (plist, global_info);
1520 M17N_OBJECT_UNREF (plist);
1525 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1526 and EXTRA. KEY, if not Mnil, tells which kind of information about
1527 the input method is necessary, and the returned IM_INFO may contain
1528 only that information. */
1530 static MInputMethodInfo *
1531 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1534 MInputMethodInfo *im_info;
1537 if (name == Mnil && extra == Mnil)
1538 language = Mt, extra = Mglobal;
1539 im_info = lookup_im_info (im_info_list, language, name, extra);
1542 if (key == Mnil ? im_info->states != NULL
1543 : key == Mcommand ? im_info->cmds != NULL
1544 : key == Mvariable ? im_info->vars != NULL
1545 : key == Mtitle ? im_info->title != NULL
1546 : key == Mdescription ? im_info->description != NULL
1548 /* IM_INFO already contains required information. */
1550 /* We have not yet loaded required information. */
1554 mdb = mdatabase_find (Minput_method, language, name, extra);
1557 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1562 plist = mdatabase_load (im_info->mdb);
1566 mplist_push (load_im_info_keys, key, Mt);
1567 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1568 mplist_pop (load_im_info_keys);
1572 MERROR (MERROR_IM, im_info);
1573 update_global_info ();
1574 load_im_info (plist, im_info);
1575 M17N_OBJECT_UNREF (plist);
1578 if (! im_info->cmds)
1579 im_info->cmds = mplist ();
1580 if (! im_info->vars)
1581 im_info->vars = mplist ();
1582 if (! im_info->states)
1583 im_info->states = mplist ();
1585 if (! im_info->title
1586 && (key == Mnil || key == Mtitle))
1587 im_info->title = (name == Mnil ? mtext ()
1588 : mtext_from_data (MSYMBOL_NAME (name),
1589 MSYMBOL_NAMELEN (name),
1590 MTEXT_FORMAT_US_ASCII));
1594 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1595 If updated, but got unloadable, return -1. Otherwise, update
1596 contents of IM_INFO from the new database, and return 1. */
1599 reload_im_info (MInputMethodInfo *im_info)
1604 update_custom_info ();
1605 update_global_info ();
1606 check = mdatabase__check (im_info->mdb);
1609 plist = mdatabase_load (im_info->mdb);
1612 fini_im_info (im_info);
1613 load_im_info (plist, im_info);
1614 M17N_OBJECT_UNREF (plist);
1615 if (! im_info->cmds)
1616 im_info->cmds = mplist ();
1617 if (! im_info->vars)
1618 im_info->vars = mplist ();
1619 if (! im_info->title)
1621 MSymbol name = im_info->name;
1623 im_info->title = (name == Mnil ? mtext ()
1624 : mtext_from_data (MSYMBOL_NAME (name),
1625 MSYMBOL_NAMELEN (name),
1626 MTEXT_FORMAT_US_ASCII));
1631 static MInputMethodInfo *
1632 get_im_info_by_tags (MPlist *plist)
1637 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1638 i++, plist = MPLIST_NEXT (plist))
1639 tag[i] = MPLIST_SYMBOL (plist);
1644 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1649 check_description (MPlist *plist)
1653 if (MPLIST_MTEXT_P (plist))
1655 if (MPLIST_PLIST_P (plist))
1657 MPlist *pl = MPLIST_PLIST (plist);
1659 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1661 pl =MPLIST_NEXT (pl);
1662 if (MFAILP (MPLIST_MTEXT_P (pl)))
1664 mt = MPLIST_MTEXT (pl);
1665 M17N_OBJECT_REF (mt);
1668 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1670 if (translated == (char *) MTEXT_DATA (mt))
1671 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1672 if (translated != (char *) MTEXT_DATA (mt))
1674 M17N_OBJECT_UNREF (mt);
1675 mt = mtext__from_data (translated, strlen (translated),
1676 MTEXT_FORMAT_UTF_8, 1);
1680 mplist_set (plist, Mtext, mt);
1681 M17N_OBJECT_UNREF (mt);
1684 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1690 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1694 check_command_keyseq (MPlist *keyseq)
1696 if (MPLIST_PLIST_P (keyseq))
1698 MPlist *p = MPLIST_PLIST (keyseq);
1701 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1705 if (MPLIST_MTEXT_P (keyseq))
1707 MText *mt = MPLIST_MTEXT (keyseq);
1710 for (i = 0; i < mtext_nchars (mt); i++)
1711 if (mtext_ref_char (mt, i) >= 256)
1718 /* Load command defitions from PLIST into IM_INFO->cmds.
1720 PLIST is well-formed and has this form;
1721 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1722 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1723 M-text or a plist of symbols.
1725 The returned list has the same form, but for each element...
1727 (1) If DESCRIPTION and the rest are omitted, the element is not
1728 stored in the returned list.
1730 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1731 description in global_info->cmds (if any). */
1734 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1738 im_info->cmds = tail = mplist ();
1740 MPLIST_DO (plist, MPLIST_NEXT (plist))
1742 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1745 if (MFAILP (MPLIST_PLIST_P (plist)))
1747 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1748 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1750 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1751 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1753 if (MFAILP (im_info != global_info))
1754 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1758 if (! check_description (p))
1759 mplist_set (p, Msymbol, Mnil);
1760 p = MPLIST_NEXT (p);
1761 while (! MPLIST_TAIL_P (p))
1763 if (MFAILP (check_command_keyseq (p)))
1764 mplist__pop_unref (p);
1766 p = MPLIST_NEXT (p);
1769 tail = mplist_add (tail, Mplist, pl);
1774 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1775 MPlist *config_cmds)
1777 MPlist *global = NULL, *custom = NULL, *config = NULL;
1778 MSymbol name = MPLIST_SYMBOL (plist);
1780 MPlist *description, *keyseq;
1782 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1783 global = MPLIST_NEXT (MPLIST_PLIST (global));
1785 plist = MPLIST_NEXT (plist);
1786 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1788 description = plist;
1789 plist = MPLIST_NEXT (plist);
1793 description = global;
1794 if (! MPLIST_TAIL_P (plist))
1795 plist = MPLIST_NEXT (plist);
1797 if (MPLIST_TAIL_P (plist) && global)
1799 keyseq = MPLIST_NEXT (global);
1800 status = Minherited;
1808 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1810 status = Mconfigured;
1811 config = MPLIST_NEXT (MPLIST_PLIST (config));
1812 if (! MPLIST_TAIL_P (config))
1815 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1817 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1819 if (MPLIST_TAIL_P (this_keyseq))
1820 mplist__pop_unref (custom);
1823 status = Mcustomized;
1824 keyseq = this_keyseq;
1829 mplist_add (plist, Msymbol, name);
1831 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1833 mplist_add (plist, Msymbol, Mnil);
1834 mplist_add (plist, Msymbol, status);
1835 mplist__conc (plist, keyseq);
1840 config_all_commands (MInputMethodInfo *im_info)
1842 MPlist *global_cmds, *custom_cmds, *config_cmds;
1843 MInputMethodInfo *temp;
1844 MPlist *tail, *plist;
1846 M17N_OBJECT_UNREF (im_info->configured_cmds);
1848 if (MPLIST_TAIL_P (im_info->cmds)
1852 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1853 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1854 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1856 im_info->configured_cmds = tail = mplist ();
1857 MPLIST_DO (plist, im_info->cmds)
1859 MPlist *pl = config_command (MPLIST_PLIST (plist),
1860 global_cmds, custom_cmds, config_cmds);
1863 tail = mplist_add (tail, Mplist, pl);
1864 M17N_OBJECT_UNREF (pl);
1869 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1870 valid, return 0 if not. */
1873 check_variable_value (MPlist *val, MPlist *global)
1875 MSymbol type = MPLIST_KEY (val);
1876 MPlist *valids = MPLIST_NEXT (val);
1878 if (type != Minteger && type != Mtext && type != Msymbol)
1882 if (MPLIST_KEY (global) != Mt
1883 && MPLIST_KEY (global) != MPLIST_KEY (val))
1885 if (MPLIST_TAIL_P (valids))
1886 valids = MPLIST_NEXT (global);
1888 if (MPLIST_TAIL_P (valids))
1891 if (type == Minteger)
1893 int n = MPLIST_INTEGER (val);
1895 MPLIST_DO (valids, valids)
1897 if (MPLIST_INTEGER_P (valids))
1899 if (n == MPLIST_INTEGER (valids))
1902 else if (MPLIST_PLIST_P (valids))
1904 MPlist *p = MPLIST_PLIST (valids);
1905 int min_bound, max_bound;
1907 if (! MPLIST_INTEGER_P (p))
1908 MERROR (MERROR_IM, 0);
1909 min_bound = MPLIST_INTEGER (p);
1910 p = MPLIST_NEXT (p);
1911 if (! MPLIST_INTEGER_P (p))
1912 MERROR (MERROR_IM, 0);
1913 max_bound = MPLIST_INTEGER (p);
1914 if (n >= min_bound && n <= max_bound)
1919 else if (type == Msymbol)
1921 MSymbol sym = MPLIST_SYMBOL (val);
1923 MPLIST_DO (valids, valids)
1925 if (! MPLIST_SYMBOL_P (valids))
1926 MERROR (MERROR_IM, 0);
1927 if (sym == MPLIST_SYMBOL (valids))
1933 MText *mt = MPLIST_MTEXT (val);
1935 MPLIST_DO (valids, valids)
1937 if (! MPLIST_MTEXT_P (valids))
1938 MERROR (MERROR_IM, 0);
1939 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1944 return (! MPLIST_TAIL_P (valids));
1947 /* Load variable defitions from PLIST into IM_INFO->vars.
1949 PLIST is well-formed and has this form;
1950 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1952 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1954 The returned list has the same form, but for each element...
1956 (1) If DESCRIPTION and the rest are omitted, the element is not
1957 stored in the returned list.
1959 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1960 description in global_info->vars (if any). */
1963 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1965 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1966 ? global_info->vars : NULL);
1969 im_info->vars = tail = mplist ();
1970 MPLIST_DO (plist, MPLIST_NEXT (plist))
1974 if (MFAILP (MPLIST_PLIST_P (plist)))
1976 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1977 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1979 if (im_info == global_info)
1981 /* Loading a global variable. */
1982 p = MPLIST_NEXT (pl);
1983 if (MPLIST_TAIL_P (p))
1984 mplist_add (p, Msymbol, Mnil);
1987 if (! check_description (p))
1988 mplist_set (p, Msymbol, Mnil);
1989 p = MPLIST_NEXT (p);
1990 if (MFAILP (! MPLIST_TAIL_P (p)
1991 && check_variable_value (p, NULL)))
1992 mplist_set (p, Mt, NULL);
1995 else if (im_info->mdb)
1997 /* Loading a local variable. */
1998 MSymbol name = MPLIST_SYMBOL (pl);
1999 MPlist *global = NULL;
2002 && (p = mplist__assq (global_vars, name)))
2004 /* P ::= ((NAME DESC ...) ...) */
2005 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2006 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2007 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2010 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2011 if (! MPLIST_TAIL_P (p))
2013 if (! check_description (p))
2014 mplist_set (p, Msymbol, Mnil);
2015 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2016 if (MFAILP (! MPLIST_TAIL_P (p)))
2017 mplist_set (p, Mt, NULL);
2020 MPlist *valid_values = MPLIST_NEXT (p);
2022 if (! MPLIST_TAIL_P (valid_values)
2023 ? MFAILP (check_variable_value (p, NULL))
2024 : global && MFAILP (check_variable_value (p, global)))
2025 mplist_set (p, Mt, NULL);
2031 /* Loading a variable customization. */
2032 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2033 if (MFAILP (! MPLIST_TAIL_P (p)))
2035 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2036 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2037 || MPLIST_MTEXT_P (p)))
2040 tail = mplist_add (tail, Mplist, pl);
2045 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2046 MPlist *config_vars)
2048 MPlist *global = NULL, *custom = NULL, *config = NULL;
2049 MSymbol name = MPLIST_SYMBOL (plist);
2051 MPlist *description = NULL, *value, *valids;
2055 global = mplist__assq (global_vars, name);
2057 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2060 plist = MPLIST_NEXT (plist);
2061 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2062 description = plist;
2064 description = global;
2066 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2068 if (MPLIST_TAIL_P (plist))
2070 /* Inherit from global (if any). */
2074 if (MPLIST_KEY (value) == Mt)
2076 valids = MPLIST_NEXT (global);
2077 status = Minherited;
2089 value = plist = MPLIST_NEXT (plist);
2090 valids = MPLIST_NEXT (value);
2091 if (MPLIST_KEY (value) == Mt)
2093 if (! MPLIST_TAIL_P (valids))
2096 valids = MPLIST_NEXT (global);
2100 if (config_vars && (config = mplist__assq (config_vars, name)))
2102 status = Mconfigured;
2103 config = MPLIST_NEXT (MPLIST_PLIST (config));
2104 if (! MPLIST_TAIL_P (config))
2107 if (MFAILP (check_variable_value (value, global ? global : plist)))
2111 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2113 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2115 if (MPLIST_TAIL_P (this_value))
2116 mplist__pop_unref (custom);
2120 if (MFAILP (check_variable_value (value, global ? global : plist)))
2122 status = Mcustomized;
2127 mplist_add (plist, Msymbol, name);
2129 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2131 mplist_add (plist, Msymbol, Mnil);
2132 mplist_add (plist, Msymbol, status);
2134 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2136 mplist_add (plist, Mt, NULL);
2137 if (valids && ! MPLIST_TAIL_P (valids))
2138 mplist__conc (plist, valids);
2142 /* Return a configured variable definition list based on
2143 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2144 get it from global_info->vars. */
2147 config_all_variables (MInputMethodInfo *im_info)
2149 MPlist *global_vars, *custom_vars, *config_vars;
2150 MInputMethodInfo *temp;
2151 MPlist *tail, *plist;
2153 M17N_OBJECT_UNREF (im_info->configured_vars);
2155 if (MPLIST_TAIL_P (im_info->vars)
2159 global_vars = im_info != global_info ? global_info->vars : NULL;
2160 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2161 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2163 im_info->configured_vars = tail = mplist ();
2164 MPLIST_DO (plist, im_info->vars)
2166 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2167 global_vars, custom_vars, config_vars);
2170 tail = mplist_add (tail, Mplist, pl);
2171 M17N_OBJECT_UNREF (pl);
2176 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2177 CONFIG contains configuration information of the input method. */
2180 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2184 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2186 load_commands (im_info, MPLIST_PLIST (pl));
2187 config_all_commands (im_info);
2188 pl = mplist_pop (pl);
2189 M17N_OBJECT_UNREF (pl);
2192 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2194 load_variables (im_info, MPLIST_PLIST (pl));
2195 config_all_variables (im_info);
2196 pl = mplist_pop (pl);
2197 M17N_OBJECT_UNREF (pl);
2200 MPLIST_DO (plist, plist)
2201 if (MPLIST_PLIST_P (plist))
2203 MPlist *elt = MPLIST_PLIST (plist);
2206 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2208 key = MPLIST_SYMBOL (elt);
2213 elt = MPLIST_NEXT (elt);
2214 if (MFAILP (MPLIST_MTEXT_P (elt)))
2216 im_info->title = MPLIST_MTEXT (elt);
2217 M17N_OBJECT_REF (im_info->title);
2219 else if (key == Mmap)
2221 pl = mplist__from_alist (MPLIST_NEXT (elt));
2224 if (! im_info->maps)
2228 mplist__conc (im_info->maps, pl);
2229 M17N_OBJECT_UNREF (pl);
2232 else if (key == Mmacro)
2234 if (! im_info->macros)
2235 im_info->macros = mplist ();
2236 MPLIST_DO (elt, MPLIST_NEXT (elt))
2238 if (MFAILP (MPLIST_PLIST_P (elt)))
2240 load_macros (im_info, MPLIST_PLIST (elt));
2243 else if (key == Mmodule)
2245 if (! im_info->externals)
2246 im_info->externals = mplist ();
2247 MPLIST_DO (elt, MPLIST_NEXT (elt))
2249 if (MFAILP (MPLIST_PLIST_P (elt)))
2251 load_external_module (im_info, MPLIST_PLIST (elt));
2254 else if (key == Mstate)
2256 MPLIST_DO (elt, MPLIST_NEXT (elt))
2260 if (MFAILP (MPLIST_PLIST_P (elt)))
2262 pl = MPLIST_PLIST (elt);
2263 if (! im_info->states)
2264 im_info->states = mplist ();
2265 state = load_state (im_info, MPLIST_PLIST (elt));
2268 mplist_put (im_info->states, state->name, state);
2271 else if (key == Minclude)
2273 /* elt ::= include (tag1 tag2 ...) key item ... */
2275 MInputMethodInfo *temp;
2277 elt = MPLIST_NEXT (elt);
2278 if (MFAILP (MPLIST_PLIST_P (elt)))
2280 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2283 elt = MPLIST_NEXT (elt);
2284 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2286 key = MPLIST_SYMBOL (elt);
2287 elt = MPLIST_NEXT (elt);
2290 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2292 if (! im_info->maps)
2293 im_info->maps = mplist ();
2294 MPLIST_DO (pl, temp->maps)
2296 p = MPLIST_VAL (pl);
2297 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2298 M17N_OBJECT_REF (p);
2301 else if (key == Mmacro)
2303 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2305 if (! im_info->macros)
2306 im_info->macros = mplist ();
2307 MPLIST_DO (pl, temp->macros)
2309 p = MPLIST_VAL (pl);
2310 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2311 M17N_OBJECT_REF (p);
2314 else if (key == Mstate)
2316 if (! temp->states || MPLIST_TAIL_P (temp->states))
2318 if (! im_info->states)
2319 im_info->states = mplist ();
2320 MPLIST_DO (pl, temp->states)
2322 MIMState *state = MPLIST_VAL (pl);
2324 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2325 M17N_OBJECT_REF (state);
2329 else if (key == Mdescription)
2331 if (im_info->description)
2333 elt = MPLIST_NEXT (elt);
2334 if (! check_description (elt))
2336 im_info->description = MPLIST_MTEXT (elt);
2337 M17N_OBJECT_REF (im_info->description);
2340 im_info->tick = time (NULL);
2345 static int take_action_list (MInputContext *ic, MPlist *action_list);
2346 static void preedit_commit (MInputContext *ic, int need_prefix);
2349 shift_state (MInputContext *ic, MSymbol state_name)
2351 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2352 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2353 MIMState *orig_state = ic_info->state, *state;
2355 /* Find a state to shift to. If not found, shift to the initial
2357 if (state_name == Mt)
2359 if (! ic_info->prev_state)
2361 state = ic_info->prev_state;
2363 else if (state_name == Mnil)
2365 state = (MIMState *) MPLIST_VAL (im_info->states);
2369 state = (MIMState *) mplist_get (im_info->states, state_name);
2371 state = (MIMState *) MPLIST_VAL (im_info->states);
2377 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2378 MSYMBOL_NAME (orig_state->name),
2379 MSYMBOL_NAME (state->name));
2381 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2384 /* Enter the new state. */
2385 ic_info->state = state;
2386 ic_info->map = state->map;
2387 ic_info->state_key_head = ic_info->key_head;
2388 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2390 /* We have shifted to the initial state. */
2391 preedit_commit (ic, 0);
2392 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2393 ic_info->state_pos = ic->cursor_pos;
2394 if (state != orig_state)
2396 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2398 /* Shifted to the initial state. */
2399 ic_info->prev_state = NULL;
2400 M17N_OBJECT_UNREF (ic_info->vars_saved);
2401 ic_info->vars_saved = mplist_copy (ic_info->vars);
2404 ic_info->prev_state = orig_state;
2407 ic->status = state->title;
2409 ic->status = im_info->title;
2410 ic->status_changed = 1;
2411 if (ic_info->map == ic_info->state->map
2412 && ic_info->map->map_actions)
2414 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2415 MSYMBOL_NAME (state->name));
2416 take_action_list (ic, ic_info->map->map_actions);
2421 /* Find a candidate group that contains a candidate number INDEX from
2422 PLIST. Set START_INDEX to the first candidate number of the group,
2423 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2424 candidate group number if they are non-NULL. If INDEX is -1, find
2425 the last candidate group. */
2428 find_candidates_group (MPlist *plist, int index,
2429 int *start_index, int *end_index, int *group_index)
2431 int i = 0, gidx = 0, len;
2433 MPLIST_DO (plist, plist)
2435 if (MPLIST_MTEXT_P (plist))
2436 len = mtext_nchars (MPLIST_MTEXT (plist));
2438 len = mplist_length (MPLIST_PLIST (plist));
2439 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2445 *end_index = i + len;
2447 *group_index = gidx;
2456 /* Adjust markers for the change of preedit text.
2457 If FROM == TO, the change is insertion of INS chars.
2458 If FROM < TO and INS == 0, the change is deletion of the range.
2459 If FROM < TO and INS > 0, the change is replacement. */
2462 adjust_markers (MInputContext *ic, int from, int to, int ins)
2464 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2469 MPLIST_DO (markers, ic_info->markers)
2470 if (MPLIST_INTEGER (markers) > from)
2471 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2472 if (ic->cursor_pos >= from)
2473 ic->cursor_pos += ins;
2477 MPLIST_DO (markers, ic_info->markers)
2479 if (MPLIST_INTEGER (markers) >= to)
2480 MPLIST_VAL (markers)
2481 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2482 else if (MPLIST_INTEGER (markers) > from)
2483 MPLIST_VAL (markers) = (void *) from;
2485 if (ic->cursor_pos >= to)
2486 ic->cursor_pos += ins - (to - from);
2487 else if (ic->cursor_pos > from)
2488 ic->cursor_pos = from;
2494 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2496 int nchars = mt ? mtext_nchars (mt) : 1;
2500 mtext_ins (ic->preedit, pos, mt);
2501 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2505 mtext_ins_char (ic->preedit, pos, c, 1);
2507 MDEBUG_PRINT1 ("('%c')", c);
2509 MDEBUG_PRINT1 ("(U+%04X)", c);
2511 adjust_markers (ic, pos, pos, nchars);
2512 ic->preedit_changed = 1;
2517 preedit_delete (MInputContext *ic, int from, int to)
2519 mtext_del (ic->preedit, from, to);
2520 adjust_markers (ic, from, to, 0);
2521 ic->preedit_changed = 1;
2525 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2529 mtext_del (ic->preedit, from, to);
2532 mtext_ins (ic->preedit, from, mt);
2533 ins = mtext_nchars (mt);
2537 mtext_ins_char (ic->preedit, from, c, 1);
2540 adjust_markers (ic, from, to, ins);
2541 ic->preedit_changed = 1;
2546 preedit_commit (MInputContext *ic, int need_prefix)
2548 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2549 int preedit_len = mtext_nchars (ic->preedit);
2551 if (preedit_len > 0)
2555 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2556 Mcandidate_list, NULL, 0);
2557 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2558 Mcandidate_index, NULL, 0);
2559 mtext_cat (ic->produced, ic->preedit);
2565 MDEBUG_PRINT1 ("\n [IM] [%s]",
2566 MSYMBOL_NAME (ic_info->state->name));
2567 MDEBUG_PRINT (" (commit");
2568 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2569 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2573 mtext_reset (ic->preedit);
2574 mtext_reset (ic_info->preedit_saved);
2575 MPLIST_DO (p, ic_info->markers)
2577 ic->cursor_pos = ic_info->state_pos = 0;
2578 ic->preedit_changed = 1;
2579 ic_info->commit_key_head = ic_info->key_head;
2581 if (ic->candidate_list)
2583 M17N_OBJECT_UNREF (ic->candidate_list);
2584 ic->candidate_list = NULL;
2585 ic->candidate_index = 0;
2586 ic->candidate_from = ic->candidate_to = 0;
2587 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2588 if (ic->candidate_show)
2590 ic->candidate_show = 0;
2591 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2597 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2599 int code = marker_code (sym, 0);
2601 if (mt && (code == '[' || code == ']'))
2605 if (code == '[' && current > 0)
2607 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2611 else if (code == ']' && current < mtext_nchars (mt))
2613 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2619 return (code == '<' ? 0
2620 : code == '>' ? limit
2621 : code == '-' ? current - 1
2622 : code == '+' ? current + 1
2623 : code == '=' ? current
2624 : code - '0' > limit ? limit
2628 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2632 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2634 int from = mtext_property_start (prop);
2635 int to = mtext_property_end (prop);
2637 MPlist *candidate_list = mtext_property_value (prop);
2638 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2640 int ingroup_index = idx - start;
2643 candidate_list = mplist_copy (candidate_list);
2644 if (MPLIST_MTEXT_P (group))
2646 mt = MPLIST_MTEXT (group);
2647 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2655 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2656 i++, plist = MPLIST_NEXT (plist));
2657 mt = MPLIST_MTEXT (plist);
2658 preedit_replace (ic, from, to, mt, 0);
2659 to = from + mtext_nchars (mt);
2661 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2662 M17N_OBJECT_UNREF (candidate_list);
2663 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2664 ic->cursor_pos = to;
2668 get_select_charset (MInputContextInfo * ic_info)
2670 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2673 if (! MPLIST_VAL (plist))
2675 sym = MPLIST_SYMBOL (plist);
2678 return MCHARSET (sym);
2682 adjust_candidates (MPlist *plist, MCharset *charset)
2686 /* plist ::= MTEXT ... | PLIST ... */
2687 plist = mplist_copy (plist);
2688 if (MPLIST_MTEXT_P (plist))
2691 while (! MPLIST_TAIL_P (pl))
2693 /* pl ::= MTEXT ... */
2694 MText *mt = MPLIST_MTEXT (pl);
2698 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2700 c = mtext_ref_char (mt, i);
2701 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2705 mt = mtext_dup (mt);
2706 mplist_set (pl, Mtext, mt);
2707 M17N_OBJECT_UNREF (mt);
2710 mtext_del (mt, i, i + 1);
2713 if (mtext_len (mt) > 0)
2714 pl = MPLIST_NEXT (pl);
2718 M17N_OBJECT_UNREF (mt);
2722 else /* MPLIST_PLIST_P (plist) */
2725 while (! MPLIST_TAIL_P (pl))
2727 /* pl ::= (MTEXT ...) ... */
2728 MPlist *p = MPLIST_PLIST (pl);
2730 /* p ::= MTEXT ... */
2734 while (! MPLIST_TAIL_P (p0))
2736 MText *mt = MPLIST_MTEXT (p0);
2739 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2741 c = mtext_ref_char (mt, i);
2742 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2747 p0 = MPLIST_NEXT (p0);
2754 p = mplist_copy (p);
2755 mplist_set (pl, Mplist, p);
2756 M17N_OBJECT_UNREF (p);
2760 p0 = MPLIST_NEXT (p0);
2763 M17N_OBJECT_UNREF (mt);
2766 if (! MPLIST_TAIL_P (p))
2767 pl = MPLIST_NEXT (pl);
2771 M17N_OBJECT_UNREF (p);
2775 if (MPLIST_TAIL_P (plist))
2777 M17N_OBJECT_UNREF (plist);
2784 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2786 MCharset *charset = get_select_charset (ic_info);
2791 plist = resolve_variable (ic_info, Mcandidates_group_size);
2792 column = MPLIST_INTEGER (plist);
2794 plist = MPLIST_PLIST (args);
2796 plist = adjust_candidates (plist, charset);
2798 if (plist && column > 0)
2800 if (MPLIST_MTEXT_P (plist))
2802 MText *mt = MPLIST_MTEXT (plist);
2803 MPlist *next = MPLIST_NEXT (plist);
2805 if (MPLIST_TAIL_P (next))
2806 M17N_OBJECT_REF (mt);
2809 mt = mtext_dup (mt);
2810 while (! MPLIST_TAIL_P (next))
2812 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2813 next = MPLIST_NEXT (next);
2817 M17N_OBJECT_UNREF (plist);
2819 len = mtext_nchars (mt);
2821 mplist_add (plist, Mtext, mt);
2824 for (i = 0; i < len; i += column)
2826 int to = (i + column < len ? i + column : len);
2827 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2829 mplist_add (plist, Mtext, sub);
2830 M17N_OBJECT_UNREF (sub);
2833 M17N_OBJECT_UNREF (mt);
2835 else if (! MPLIST_TAIL_P (plist))
2837 MPlist *tail = plist;
2838 MPlist *new = mplist ();
2839 MPlist *this = mplist ();
2842 MPLIST_DO (tail, tail)
2844 MPlist *p = MPLIST_PLIST (tail);
2848 MText *mt = MPLIST_MTEXT (p);
2850 if (count == column)
2852 mplist_add (new, Mplist, this);
2853 M17N_OBJECT_UNREF (this);
2857 mplist_add (this, Mtext, mt);
2861 mplist_add (new, Mplist, this);
2862 M17N_OBJECT_UNREF (this);
2863 mplist_set (plist, Mnil, NULL);
2864 MPLIST_DO (tail, new)
2866 MPlist *elt = MPLIST_PLIST (tail);
2868 mplist_add (plist, Mplist, elt);
2870 M17N_OBJECT_UNREF (new);
2879 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2881 MPlist *action = NULL;
2885 if (MPLIST_SYMBOL_P (action_list))
2887 MSymbol var = MPLIST_SYMBOL (action_list);
2890 MPLIST_DO (p, ic_info->vars)
2891 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2893 if (MPLIST_TAIL_P (p))
2895 action = MPLIST_NEXT (MPLIST_PLIST (p));
2896 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2899 if (MPLIST_PLIST_P (action_list))
2901 action = MPLIST_PLIST (action_list);
2902 if (MPLIST_SYMBOL_P (action))
2904 name = MPLIST_SYMBOL (action);
2905 args = MPLIST_NEXT (action);
2907 && MPLIST_PLIST_P (args))
2908 mplist_set (action, Msymbol, M_candidates);
2910 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2913 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2914 mplist_push (action, Msymbol, M_candidates);
2915 mplist_set (action_list, Mplist, action);
2916 M17N_OBJECT_UNREF (action);
2919 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2922 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2923 mplist_push (action, Msymbol, Minsert);
2924 mplist_set (action_list, Mplist, action);
2925 M17N_OBJECT_UNREF (action);
2930 /* Perform list of actions in ACTION_LIST for the current input
2931 context IC. If unhandle action was not performed, return 0.
2932 Otherwise, return -1. */
2935 take_action_list (MInputContext *ic, MPlist *action_list)
2937 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2938 MPlist *candidate_list = ic->candidate_list;
2939 int candidate_index = ic->candidate_index;
2940 int candidate_show = ic->candidate_show;
2941 MTextProperty *prop;
2943 MPLIST_DO (action_list, action_list)
2945 MPlist *action = regularize_action (action_list, ic_info);
2951 name = MPLIST_SYMBOL (action);
2952 args = MPLIST_NEXT (action);
2954 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2955 if (name == Minsert)
2957 if (MPLIST_SYMBOL_P (args))
2959 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2960 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2963 if (MPLIST_MTEXT_P (args))
2964 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2965 else /* MPLIST_INTEGER_P (args)) */
2966 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2968 else if (name == M_candidates)
2970 MPlist *plist = get_candidate_list (ic_info, args);
2973 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2975 if (MPLIST_MTEXT_P (plist))
2977 preedit_insert (ic, ic->cursor_pos, NULL,
2978 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2981 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2985 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2987 preedit_insert (ic, ic->cursor_pos, mt, 0);
2988 len = mtext_nchars (mt);
2990 plist = mplist_copy (plist);
2991 mtext_put_prop (ic->preedit,
2992 ic->cursor_pos - len, ic->cursor_pos,
2993 Mcandidate_list, plist);
2994 M17N_OBJECT_UNREF (plist);
2995 mtext_put_prop (ic->preedit,
2996 ic->cursor_pos - len, ic->cursor_pos,
2997 Mcandidate_index, (void *) 0);
2999 else if (name == Mselect)
3002 int code, idx, gindex;
3003 int pos = ic->cursor_pos;
3005 int idx_decided = 0;
3008 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3011 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3012 group = find_candidates_group (mtext_property_value (prop), idx,
3013 &start, &end, &gindex);
3014 if (MPLIST_SYMBOL_P (args))
3016 code = marker_code (MPLIST_SYMBOL (args), 0);
3019 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3020 if (! MPLIST_INTEGER_P (args))
3022 idx = start + MPLIST_INTEGER (args);
3023 if (idx < start || idx >= end)
3031 if (code != '[' && code != ']')
3036 ? new_index (NULL, ic->candidate_index - start,
3037 end - start - 1, MPLIST_SYMBOL (args),
3039 : MPLIST_INTEGER (args)));
3042 find_candidates_group (mtext_property_value (prop), -1,
3047 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3052 int ingroup_index = idx - start;
3055 group = mtext_property_value (prop);
3056 len = mplist_length (group);
3069 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3070 idx += (MPLIST_MTEXT_P (group)
3071 ? mtext_nchars (MPLIST_MTEXT (group))
3072 : mplist_length (MPLIST_PLIST (group)));
3073 len = (MPLIST_MTEXT_P (group)
3074 ? mtext_nchars (MPLIST_MTEXT (group))
3075 : mplist_length (MPLIST_PLIST (group)));
3076 if (ingroup_index >= len)
3077 ingroup_index = len - 1;
3078 idx += ingroup_index;
3080 update_candidate (ic, prop, idx);
3081 MDEBUG_PRINT1 ("(%d)", idx);
3083 else if (name == Mshow)
3084 ic->candidate_show = 1;
3085 else if (name == Mhide)
3086 ic->candidate_show = 0;
3087 else if (name == Mdelete)
3089 int len = mtext_nchars (ic->preedit);
3093 if (MPLIST_SYMBOL_P (args)
3094 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3096 to = ic->cursor_pos + pos;
3099 delete_surrounding_text (ic, to);
3104 delete_surrounding_text (ic, to - len);
3110 to = (MPLIST_SYMBOL_P (args)
3111 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3113 : MPLIST_INTEGER (args));
3119 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3120 if (to < ic->cursor_pos)
3121 preedit_delete (ic, to, ic->cursor_pos);
3122 else if (to > ic->cursor_pos)
3123 preedit_delete (ic, ic->cursor_pos, to);
3125 else if (name == Mmove)
3127 int len = mtext_nchars (ic->preedit);
3129 = (MPLIST_SYMBOL_P (args)
3130 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3132 : MPLIST_INTEGER (args));
3138 if (pos != ic->cursor_pos)
3140 ic->cursor_pos = pos;
3141 ic->preedit_changed = 1;
3143 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3145 else if (name == Mmark)
3147 int code = marker_code (MPLIST_SYMBOL (args), 0);
3151 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3152 (void *) ic->cursor_pos);
3153 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3156 else if (name == Mpushback)
3158 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3162 if (MPLIST_SYMBOL_P (args))
3164 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3165 if (MPLIST_INTEGER_P (args))
3166 num = MPLIST_INTEGER (args);
3171 num = MPLIST_INTEGER (args);
3174 ic_info->key_head -= num;
3176 ic_info->key_head = 0;
3178 ic_info->key_head = - num;
3179 if (ic_info->key_head > ic_info->used)
3180 ic_info->key_head = ic_info->used;
3182 else if (MPLIST_MTEXT_P (args))
3184 MText *mt = MPLIST_MTEXT (args);
3185 int i, len = mtext_nchars (mt);
3188 ic_info->key_head--;
3189 for (i = 0; i < len; i++)
3191 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3192 if (ic_info->key_head + i < ic_info->used)
3193 ic_info->keys[ic_info->key_head + i] = key;
3195 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3200 MPlist *plist = MPLIST_PLIST (args), *pl;
3204 ic_info->key_head--;
3206 MPLIST_DO (pl, plist)
3208 key = MPLIST_SYMBOL (pl);
3209 if (ic_info->key_head < ic_info->used)
3210 ic_info->keys[ic_info->key_head + i] = key;
3212 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3217 else if (name == Mpop)
3219 if (ic_info->key_head < ic_info->used)
3220 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3222 else if (name == Mcall)
3224 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3225 MIMExternalFunc func = NULL;
3226 MSymbol module, func_name;
3227 MPlist *func_args, *val;
3230 module = MPLIST_SYMBOL (args);
3231 args = MPLIST_NEXT (args);
3232 func_name = MPLIST_SYMBOL (args);
3234 if (im_info->externals)
3236 MIMExternalModule *external
3237 = (MIMExternalModule *) mplist_get (im_info->externals,
3240 func = ((MIMExternalFunc)
3241 mplist_get_func (external->func_list, func_name));
3245 func_args = mplist ();
3246 mplist_add (func_args, Mt, ic);
3247 MPLIST_DO (args, MPLIST_NEXT (args))
3251 if (MPLIST_KEY (args) == Msymbol
3252 && MPLIST_KEY (args) != Mnil
3253 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3255 code = new_index (ic, ic->cursor_pos,
3256 mtext_nchars (ic->preedit),
3257 MPLIST_SYMBOL (args), ic->preedit);
3258 mplist_add (func_args, Minteger, (void *) code);
3261 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3263 val = (func) (func_args);
3264 M17N_OBJECT_UNREF (func_args);
3265 if (val && ! MPLIST_TAIL_P (val))
3266 ret = take_action_list (ic, val);
3267 M17N_OBJECT_UNREF (val);
3271 else if (name == Mshift)
3273 shift_state (ic, MPLIST_SYMBOL (args));
3275 else if (name == Mundo)
3277 int intarg = (MPLIST_TAIL_P (args)
3279 : integer_value (ic, args, NULL, 0));
3281 mtext_reset (ic->preedit);
3282 mtext_reset (ic_info->preedit_saved);
3283 mtext_reset (ic->produced);
3284 M17N_OBJECT_UNREF (ic_info->vars);
3285 ic_info->vars = mplist_copy (ic_info->vars_saved);
3286 ic->cursor_pos = ic_info->state_pos = 0;
3287 ic_info->state_key_head = ic_info->key_head
3288 = ic_info->commit_key_head = 0;
3290 shift_state (ic, Mnil);
3293 if (MPLIST_TAIL_P (args))
3298 ic_info->used += intarg;
3301 ic_info->used = intarg;
3304 else if (name == Mset || name == Madd || name == Msub
3305 || name == Mmul || name == Mdiv)
3307 MSymbol sym = MPLIST_SYMBOL (args);
3312 val1 = integer_value (ic, args, &value, 0);
3313 args = MPLIST_NEXT (args);
3314 val2 = resolve_expression (ic, args);
3316 val1 = val2, op = "=";
3317 else if (name == Madd)
3318 val1 += val2, op = "+=";
3319 else if (name == Msub)
3320 val1 -= val2, op = "-=";
3321 else if (name == Mmul)
3322 val1 *= val2, op = "*=";
3324 val1 /= val2, op = "/=";
3325 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3326 MSYMBOL_NAME (sym), op, val1, val1);
3328 mplist_set (value, Minteger, (void *) val1);
3330 else if (name == Mequal || name == Mless || name == Mgreater
3331 || name == Mless_equal || name == Mgreater_equal)
3334 MPlist *actions1, *actions2;
3337 val1 = resolve_expression (ic, args);
3338 args = MPLIST_NEXT (args);
3339 val2 = resolve_expression (ic, args);
3340 args = MPLIST_NEXT (args);
3341 actions1 = MPLIST_PLIST (args);
3342 args = MPLIST_NEXT (args);
3343 if (MPLIST_TAIL_P (args))
3346 actions2 = MPLIST_PLIST (args);
3347 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3348 if (name == Mequal ? val1 == val2
3349 : name == Mless ? val1 < val2
3350 : name == Mgreater ? val1 > val2
3351 : name == Mless_equal ? val1 <= val2
3354 MDEBUG_PRINT ("ok");
3355 ret = take_action_list (ic, actions1);
3359 MDEBUG_PRINT ("no");
3361 ret = take_action_list (ic, actions2);
3366 else if (name == Mcond)
3370 MPLIST_DO (args, args)
3375 if (! MPLIST_PLIST (args))
3377 cond = MPLIST_PLIST (args);
3378 if (resolve_expression (ic, cond) != 0)
3380 MDEBUG_PRINT1 ("(%dth)", idx);
3381 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3387 else if (name == Mcommit)
3389 preedit_commit (ic, 0);
3391 else if (name == Munhandle)
3393 preedit_commit (ic, 0);
3398 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3402 && (actions = mplist_get (im_info->macros, name)))
3404 if (take_action_list (ic, actions) < 0)
3410 if (ic->candidate_list)
3412 M17N_OBJECT_UNREF (ic->candidate_list);
3413 ic->candidate_list = NULL;
3415 if (ic->cursor_pos > 0
3416 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3419 ic->candidate_list = mtext_property_value (prop);
3420 M17N_OBJECT_REF (ic->candidate_list);
3422 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3424 ic->candidate_from = mtext_property_start (prop);
3425 ic->candidate_to = mtext_property_end (prop);
3428 if (candidate_list != ic->candidate_list)
3429 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3430 if (candidate_index != ic->candidate_index)
3431 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3432 if (candidate_show != ic->candidate_show)
3433 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3438 /* Handle the input key KEY in the current state and map specified in
3439 the input context IC. If KEY is handled correctly, return 0.
3440 Otherwise, return -1. */
3443 handle_key (MInputContext *ic)
3445 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3446 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3447 MIMMap *map = ic_info->map;
3448 MIMMap *submap = NULL;
3449 MSymbol key = ic_info->keys[ic_info->key_head];
3450 MSymbol alias = Mnil;
3453 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3454 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3458 submap = mplist_get (map->submaps, key);
3461 && (alias = msymbol_get (alias, M_key_alias))
3463 submap = mplist_get (map->submaps, alias);
3468 if (! alias || alias == key)
3469 MDEBUG_PRINT (" submap-found");
3471 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3472 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3473 ic->preedit_changed = 1;
3474 ic->cursor_pos = ic_info->state_pos;
3475 ic_info->key_head++;
3476 ic_info->map = map = submap;
3477 if (map->map_actions)
3479 MDEBUG_PRINT (" map-actions:");
3480 if (take_action_list (ic, map->map_actions) < 0)
3482 MDEBUG_PRINT ("\n");
3486 else if (map->submaps)
3488 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3490 MSymbol key = ic_info->keys[i];
3491 char *name = msymbol_name (key);
3493 if (! name[0] || ! name[1])
3494 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3498 /* If this is the terminal map or we have shifted to another
3499 state, perform branch actions (if any). */
3500 if (! map->submaps || map != ic_info->map)
3502 if (map->branch_actions)
3504 MDEBUG_PRINT (" branch-actions:");
3505 if (take_action_list (ic, map->branch_actions) < 0)
3507 MDEBUG_PRINT ("\n");
3511 /* If MAP is still not the root map, shift to the current
3513 if (ic_info->map != ic_info->state->map)
3514 shift_state (ic, ic_info->state->name);
3519 /* MAP can not handle KEY. */
3521 /* Perform branch actions if any. */
3522 if (map->branch_actions)
3524 MDEBUG_PRINT (" branch-actions:");
3525 if (take_action_list (ic, map->branch_actions) < 0)
3527 MDEBUG_PRINT ("\n");
3532 if (map == ic_info->map)
3534 /* The above branch actions didn't change the state. */
3536 /* If MAP is the root map of the initial state, and there
3537 still exist an unhandled key, it means that the current
3538 input method can not handle it. */
3539 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3540 && ic_info->key_head < ic_info->used)
3542 MDEBUG_PRINT (" unhandled\n");
3546 if (map != ic_info->state->map)
3548 /* MAP is not the root map. Shift to the root map of the
3550 shift_state (ic, ic_info->state->name);
3552 else if (! map->branch_actions)
3554 /* MAP is the root map without any default branch
3555 actions. Shift to the initial state. */
3556 shift_state (ic, Mnil);
3560 MDEBUG_PRINT ("\n");
3564 /* Initialize IC->ic_info. */
3567 init_ic_info (MInputContext *ic)
3569 MInputMethodInfo *im_info = ic->im->info;
3570 MInputContextInfo *ic_info = ic->info;
3573 MLIST_INIT1 (ic_info, keys, 8);;
3575 ic_info->markers = mplist ();
3577 ic_info->vars = mplist ();
3578 if (im_info->configured_vars)
3579 MPLIST_DO (plist, im_info->configured_vars)
3581 MPlist *pl = MPLIST_PLIST (plist);
3582 MSymbol name = MPLIST_SYMBOL (pl);
3584 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3585 if (MPLIST_KEY (pl) != Mt)
3587 MPlist *p = mplist ();
3589 mplist_push (ic_info->vars, Mplist, p);
3590 M17N_OBJECT_UNREF (p);
3591 mplist_add (p, Msymbol, name);
3592 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3595 ic_info->vars_saved = mplist_copy (ic_info->vars);
3597 if (im_info->externals)
3599 MPlist *func_args = mplist (), *plist;
3601 mplist_add (func_args, Mt, ic);
3602 MPLIST_DO (plist, im_info->externals)
3604 MIMExternalModule *external = MPLIST_VAL (plist);
3605 MIMExternalFunc func
3606 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3611 M17N_OBJECT_UNREF (func_args);
3614 ic_info->preedit_saved = mtext ();
3615 ic_info->tick = im_info->tick;
3618 /* Finalize IC->ic_info. */
3621 fini_ic_info (MInputContext *ic)
3623 MInputMethodInfo *im_info = ic->im->info;
3624 MInputContextInfo *ic_info = ic->info;
3626 if (im_info->externals)
3628 MPlist *func_args = mplist (), *plist;
3630 mplist_add (func_args, Mt, ic);
3631 MPLIST_DO (plist, im_info->externals)
3633 MIMExternalModule *external = MPLIST_VAL (plist);
3634 MIMExternalFunc func
3635 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3640 M17N_OBJECT_UNREF (func_args);
3643 MLIST_FREE1 (ic_info, keys);
3644 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3645 M17N_OBJECT_UNREF (ic_info->markers);
3646 M17N_OBJECT_UNREF (ic_info->vars);
3647 M17N_OBJECT_UNREF (ic_info->vars_saved);
3648 M17N_OBJECT_UNREF (ic_info->preceding_text);
3649 M17N_OBJECT_UNREF (ic_info->following_text);
3651 memset (ic_info, 0, sizeof (MInputContextInfo));
3655 re_init_ic (MInputContext *ic, int reload)
3657 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3658 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3659 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3661 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3662 preedit_changed = mtext_nchars (ic->preedit) > 0;
3663 cursor_pos_changed = ic->cursor_pos > 0;
3664 candidates_changed = 0;
3665 if (ic->candidate_list)
3667 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3668 M17N_OBJECT_UNREF (ic->candidate_list);
3669 ic->candidate_list = NULL;
3671 if (ic->candidate_show)
3673 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3674 ic->candidate_show = 0;
3676 if (ic->candidate_index > 0)
3678 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3679 ic->candidate_index = 0;
3680 ic->candidate_from = ic->candidate_to = 0;
3682 if (mtext_nchars (ic->produced) > 0)
3683 mtext_reset (ic->produced);
3684 if (mtext_nchars (ic->preedit) > 0)
3685 mtext_reset (ic->preedit);
3687 M17N_OBJECT_UNREF (ic->plist);
3688 ic->plist = mplist ();
3692 reload_im_info (im_info);
3693 if (! im_info->states)
3695 struct MIMState *state;
3697 M17N_OBJECT (state, free_state, MERROR_IM);
3698 state->name = msymbol ("init");
3699 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3700 MSTRUCT_CALLOC (state->map, MERROR_IM);
3701 im_info->states = mplist ();
3702 mplist_add (im_info->states, state->name, state);
3705 shift_state (ic, Mnil);
3707 ic->status_changed = status_changed;
3708 ic->preedit_changed = preedit_changed;
3709 ic->cursor_pos_changed = cursor_pos_changed;
3710 ic->candidates_changed = candidates_changed;
3714 reset_ic (MInputContext *ic, MSymbol ignore)
3716 MDEBUG_PRINT ("\n [IM] reset\n");
3721 open_im (MInputMethod *im)
3723 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3725 if (! im_info || ! im_info->states)
3726 MERROR (MERROR_IM, -1);
3733 close_im (MInputMethod *im)
3739 create_ic (MInputContext *ic)
3741 MInputContextInfo *ic_info;
3743 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3746 shift_state (ic, Mnil);
3751 destroy_ic (MInputContext *ic)
3758 check_reload (MInputContext *ic, MSymbol key)
3760 MInputMethodInfo *im_info = ic->im->info;
3761 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3765 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3769 MPLIST_DO (plist, plist)
3771 MSymbol this_key, alias;
3773 if (MPLIST_MTEXT_P (plist))
3775 MText *mt = MPLIST_MTEXT (plist);
3776 int c = mtext_ref_char (mt, 0);
3780 this_key = one_char_symbol[c];
3784 MPlist *pl = MPLIST_PLIST (plist);
3786 this_key = MPLIST_SYMBOL (pl);
3790 && (alias = msymbol_get (alias, M_key_alias))
3791 && alias != this_key);
3795 if (MPLIST_TAIL_P (plist))
3798 MDEBUG_PRINT ("\n [IM] reload");
3804 /** Handle the input key KEY in the current state and map of IC->info.
3805 If KEY is handled but no text is produced, return 0, otherwise
3811 filter (MInputContext *ic, MSymbol key, void *arg)
3813 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3814 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3817 if (check_reload (ic, key))
3820 if (! ic_info->state)
3822 ic_info->key_unhandled = 1;
3825 mtext_reset (ic->produced);
3826 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3827 M17N_OBJECT_UNREF (ic_info->preceding_text);
3828 M17N_OBJECT_UNREF (ic_info->following_text);
3829 ic_info->preceding_text = ic_info->following_text = NULL;
3830 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3831 ic_info->key_unhandled = 0;
3834 if (handle_key (ic) < 0)
3836 /* KEY was not handled. Delete it from the current key sequence. */
3837 if (ic_info->used > 0)
3839 memmove (ic_info->keys, ic_info->keys + 1,
3840 sizeof (int) * (ic_info->used - 1));
3842 if (ic_info->state_key_head > 0)
3843 ic_info->state_key_head--;
3844 if (ic_info->commit_key_head > 0)
3845 ic_info->commit_key_head--;
3847 /* This forces returning 1. */
3848 ic_info->key_unhandled = 1;
3854 reset_ic (ic, Mnil);
3855 ic_info->key_unhandled = 1;
3858 /* Break the loop if all keys were handled. */
3859 } while (ic_info->key_head < ic_info->used);
3861 /* If the current map is the root of the initial state, we should
3862 produce any preedit text in ic->produced. */
3863 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3864 preedit_commit (ic, 1);
3866 if (mtext_nchars (ic->produced) > 0)
3870 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3871 MSYMBOL_NAME (ic_info->state->name));
3872 for (i = 0; i < mtext_nchars (ic->produced); i++)
3873 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3877 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3878 Mlanguage, ic->im->language);
3880 if (ic_info->commit_key_head > 0)
3882 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3883 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3884 ic_info->used -= ic_info->commit_key_head;
3885 ic_info->key_head -= ic_info->commit_key_head;
3886 ic_info->state_key_head -= ic_info->commit_key_head;
3887 ic_info->commit_key_head = 0;
3889 if (ic_info->key_unhandled)
3892 ic_info->key_head = ic_info->state_key_head
3893 = ic_info->commit_key_head = 0;
3896 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3900 /** Return 1 if the last event or key was not handled, otherwise
3903 There is no need of looking up because ic->produced should already
3904 contain the produced text (if any).
3909 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3911 mtext_cat (mt, ic->produced);
3912 mtext_reset (ic->produced);
3913 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3917 /* Input method command handler. */
3919 /* List of all (global and local) commands.
3920 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3921 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3922 Global commands are stored as (t (t COMMAND ...)) */
3925 /* Input method variable handler. */
3928 /* Support functions for mdebug_dump_im. */
3931 dump_im_map (MPlist *map_list, int indent)
3934 MSymbol key = MPLIST_KEY (map_list);
3935 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3937 prefix = (char *) alloca (indent + 1);
3938 memset (prefix, 32, indent);
3939 prefix[indent] = '\0';
3941 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3942 if (map->map_actions)
3943 mdebug_dump_plist (map->map_actions, indent + 2);
3946 MPLIST_DO (map_list, map->submaps)
3948 fprintf (stderr, "\n%s ", prefix);
3949 dump_im_map (map_list, indent + 2);
3952 if (map->branch_actions)
3954 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3955 mdebug_dump_plist (map->branch_actions, indent + 4);
3956 fprintf (stderr, ")");
3958 fprintf (stderr, ")");
3963 dump_im_state (MIMState *state, int indent)
3968 prefix = (char *) alloca (indent + 1);
3969 memset (prefix, 32, indent);
3970 prefix[indent] = '\0';
3972 fprintf (stderr, "(%s", msymbol_name (state->name));
3973 if (state->map->submaps)
3975 MPLIST_DO (map_list, state->map->submaps)
3977 fprintf (stderr, "\n%s ", prefix);
3978 dump_im_map (map_list, indent + 2);
3981 fprintf (stderr, ")");
3989 Minput_driver = msymbol ("input-driver");
3991 Minput_preedit_start = msymbol ("input-preedit-start");
3992 Minput_preedit_done = msymbol ("input-preedit-done");
3993 Minput_preedit_draw = msymbol ("input-preedit-draw");
3994 Minput_status_start = msymbol ("input-status-start");
3995 Minput_status_done = msymbol ("input-status-done");
3996 Minput_status_draw = msymbol ("input-status-draw");
3997 Minput_candidates_start = msymbol ("input-candidates-start");
3998 Minput_candidates_done = msymbol ("input-candidates-done");
3999 Minput_candidates_draw = msymbol ("input-candidates-draw");
4000 Minput_set_spot = msymbol ("input-set-spot");
4001 Minput_focus_move = msymbol ("input-focus-move");
4002 Minput_focus_in = msymbol ("input-focus-in");
4003 Minput_focus_out = msymbol ("input-focus-out");
4004 Minput_toggle = msymbol ("input-toggle");
4005 Minput_reset = msymbol ("input-reset");
4006 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4007 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4008 Mcustomized = msymbol ("customized");
4009 Mconfigured = msymbol ("configured");
4010 Minherited = msymbol ("inherited");
4012 minput_default_driver.open_im = open_im;
4013 minput_default_driver.close_im = close_im;
4014 minput_default_driver.create_ic = create_ic;
4015 minput_default_driver.destroy_ic = destroy_ic;
4016 minput_default_driver.filter = filter;
4017 minput_default_driver.lookup = lookup;
4018 minput_default_driver.callback_list = mplist ();
4019 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4020 M17N_FUNC (reset_ic));
4021 minput_driver = &minput_default_driver;
4023 fully_initialized = 0;
4030 if (fully_initialized)
4032 free_im_list (im_info_list);
4034 free_im_list (im_custom_list);
4036 free_im_list (im_config_list);
4037 M17N_OBJECT_UNREF (load_im_info_keys);
4040 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4041 M17N_OBJECT_UNREF (minput_driver->callback_list);
4046 minput__char_to_key (int c)
4048 if (c < 0 || c >= 0x100)
4051 return one_char_symbol[c];
4055 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4060 /*** @addtogroup m17nInputMethod */
4065 @name Variables: Predefined symbols for callback commands.
4067 These are the predefined symbols that are used as the @c COMMAND
4068 argument of callback functions of an input method driver (see
4069 #MInputDriver::callback_list).
4071 Most of them do not require extra argument nor return any value;
4072 exceptions are these:
4074 Minput_get_surrounding_text: When a callback function assigned for
4075 this command is called, the first element of #MInputContext::plist
4076 has key #Minteger and the value specifies which portion of the
4077 surrounding text should be retrieved. If the value is positive,
4078 it specifies the number of characters following the current cursor
4079 position. If the value is negative, the absolute value specifies
4080 the number of characters preceding the current cursor position.
4081 If the value is zero, it means that the caller just wants to know
4082 if the surrounding text is currently supported or not.
4084 If the surrounding text is currently supported, the callback
4085 function must set the key of this element to #Mtext and the value
4086 to the retrieved M-text. The length of the M-text may be shorter
4087 than the requested number of characters, if the available text is
4088 not that long. The length can be zero in the worst case. Or, the
4089 length may be longer if an application thinks it is more efficient
4090 to return that length.
4092 If the surrounding text is not currently supported, the callback
4093 function should return without changing the first element of
4094 #MInputContext::plist.
4096 Minput_delete_surrounding_text: When a callback function assigned
4097 for this command is called, the first element of
4098 #MInputContext::plist has key #Minteger and the value specifies
4099 which portion of the surrounding text should be deleted in the
4100 same way as the case of Minput_get_surrounding_text. The callback
4101 function must delete the specified text. It should not alter
4102 #MInputContext::plist. */
4104 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4106 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4107 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4109 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4111 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4112 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4113 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4114 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4115 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4116 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4117 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4119 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4120 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4121 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4122 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4123 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4125 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4126 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4128 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4129 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4130 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4131 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4132 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4133 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4137 MSymbol Minput_preedit_start;
4138 MSymbol Minput_preedit_done;
4139 MSymbol Minput_preedit_draw;
4140 MSymbol Minput_status_start;
4141 MSymbol Minput_status_done;
4142 MSymbol Minput_status_draw;
4143 MSymbol Minput_candidates_start;
4144 MSymbol Minput_candidates_done;
4145 MSymbol Minput_candidates_draw;
4146 MSymbol Minput_set_spot;
4147 MSymbol Minput_toggle;
4148 MSymbol Minput_reset;
4149 MSymbol Minput_get_surrounding_text;
4150 MSymbol Minput_delete_surrounding_text;
4156 @name Variables: Predefined symbols for special input events.
4158 These are the predefined symbols that are used as the @c KEY
4159 argument of minput_filter (). */
4161 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4163 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4168 MSymbol Minput_focus_out;
4169 MSymbol Minput_focus_in;
4170 MSymbol Minput_focus_move;
4176 @name Variables: Predefined symbols used in input method information.
4178 These are the predefined symbols describing status of input method
4179 command and variable, and are used in a return value of
4180 minput_get_command () and minput_get_variable (). */
4182 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4184 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4185 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4189 MSymbol Mcustomized;
4190 MSymbol Mconfigured;
4196 @brief The default driver for internal input methods.
4198 The variable #minput_default_driver is the default driver for
4199 internal input methods.
4201 The member MInputDriver::open_im () searches the m17n database for
4202 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4203 $NAME\> and loads it.
4205 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4206 programmers responsibility to set it to a plist of proper callback
4207 functions. Otherwise, no feedback information (e.g. preedit text)
4208 can be shown to users.
4210 The macro M17N_INIT () sets the variable #minput_driver to the
4211 pointer to this driver so that all internal input methods use it.
4213 Therefore, unless @c minput_driver is set differently, the driver
4214 dependent arguments $ARG of the functions whose name begins with
4215 "minput_" are all ignored. */
4217 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4219 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4221 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4222 \< #Minput_method, $LANGUAGE, $NAME\>
4223 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4225 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4226 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4227 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4228 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4230 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4231 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4233 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4234 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4236 MInputDriver minput_default_driver;
4240 @brief The driver for internal input methods.
4242 The variable #minput_driver is a pointer to the input method
4243 driver that is used by internal input methods. The macro
4244 M17N_INIT () initializes it to a pointer to #minput_default_driver
4245 if <m17n<EM></EM>.h> is included. */
4247 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4249 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4250 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4251 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4252 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4254 MInputDriver *minput_driver;
4256 MSymbol Minput_driver;
4271 @brief Open an input method.
4273 The minput_open_im () function opens an input method whose
4274 language and name match $LANGUAGE and $NAME, and returns a pointer
4275 to the input method object newly allocated.
4277 This function at first decides a driver for the input method as
4280 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4281 #minput_driver is used.
4283 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4284 driver pointed to by the property value is used to open the input
4285 method. If $NAME has no such a property, @c NULL is returned.
4287 Then, the member MInputDriver::open_im () of the driver is
4290 $ARG is set in the member @c arg of the structure MInputMethod so
4291 that the driver can refer to it. */
4293 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4295 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4296 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4298 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4300 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4301 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4303 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4304 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4305 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4307 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4309 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4311 @latexonly \IPAlabel{minput_open} @endlatexonly
4316 minput_open_im (MSymbol language, MSymbol name, void *arg)
4319 MInputDriver *driver;
4323 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4324 msymbol_name (language), msymbol_name (name));
4326 driver = minput_driver;
4329 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4331 MERROR (MERROR_IM, NULL);
4334 MSTRUCT_CALLOC (im, MERROR_IM);
4335 im->language = language;
4338 im->driver = *driver;
4339 if ((*im->driver.open_im) (im) < 0)
4341 MDEBUG_PRINT (" failed\n");
4345 MDEBUG_PRINT (" ok\n");
4352 @brief Close an input method.
4354 The minput_close_im () function closes the input method $IM, which
4355 must have been created by minput_open_im (). */
4358 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4360 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4361 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4364 minput_close_im (MInputMethod *im)
4366 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4367 msymbol_name (im->name), msymbol_name (im->language));
4368 (*im->driver.close_im) (im);
4370 MDEBUG_PRINT (" done\n");
4376 @brief Create an input context.
4378 The minput_create_ic () function creates an input context object
4379 associated with input method $IM, and calls callback functions
4380 corresponding to #Minput_preedit_start, #Minput_status_start, and
4381 #Minput_status_draw in this order.
4384 If an input context is successfully created, minput_create_ic ()
4385 returns a pointer to it. Otherwise it returns @c NULL. */
4388 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4390 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4391 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4392 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4393 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4396 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4397 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4401 minput_create_ic (MInputMethod *im, void *arg)
4405 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4406 msymbol_name (im->name), msymbol_name (im->language));
4407 MSTRUCT_CALLOC (ic, MERROR_IM);
4410 ic->preedit = mtext ();
4411 ic->candidate_list = NULL;
4412 ic->produced = mtext ();
4413 ic->spot.x = ic->spot.y = 0;
4415 ic->plist = mplist ();
4416 if ((*im->driver.create_ic) (ic) < 0)
4418 MDEBUG_PRINT (" failed\n");
4419 M17N_OBJECT_UNREF (ic->preedit);
4420 M17N_OBJECT_UNREF (ic->produced);
4421 M17N_OBJECT_UNREF (ic->plist);
4426 if (im->driver.callback_list)
4428 minput_callback (ic, Minput_preedit_start);
4429 minput_callback (ic, Minput_status_start);
4430 minput_callback (ic, Minput_status_draw);
4433 MDEBUG_PRINT (" ok\n");
4440 @brief Destroy an input context.
4442 The minput_destroy_ic () function destroys the input context $IC,
4443 which must have been created by minput_create_ic (). It calls
4444 callback functions corresponding to #Minput_preedit_done,
4445 #Minput_status_done, and #Minput_candidates_done in this order. */
4448 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4450 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4451 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4452 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4453 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4454 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4458 minput_destroy_ic (MInputContext *ic)
4460 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4461 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4462 if (ic->im->driver.callback_list)
4464 minput_callback (ic, Minput_preedit_done);
4465 minput_callback (ic, Minput_status_done);
4466 minput_callback (ic, Minput_candidates_done);
4468 (*ic->im->driver.destroy_ic) (ic);
4469 M17N_OBJECT_UNREF (ic->preedit);
4470 M17N_OBJECT_UNREF (ic->produced);
4471 M17N_OBJECT_UNREF (ic->plist);
4472 MDEBUG_PRINT (" done\n");
4479 @brief Filter an input key.
4481 The minput_filter () function filters input key $KEY according to
4482 input context $IC, and calls callback functions corresponding to
4483 #Minput_preedit_draw, #Minput_status_draw, and
4484 #Minput_candidates_draw if the preedit text, the status, and the
4485 current candidate are changed respectively.
4487 To make the input method commit the current preedit text (if any)
4488 and shift to the initial state, call this function with #Mnil as
4491 To inform the input method about the focus-out event, call this
4492 function with #Minput_focus_out as $KEY.
4494 To inform the input method about the focus-in event, call this
4495 function with #Minput_focus_in as $KEY.
4497 To inform the input method about the focus-move event (i.e. input
4498 spot change within the same input context), call this function
4499 with #Minput_focus_move as $KEY.
4502 If $KEY is filtered out, this function returns 1. In that case,
4503 the caller should discard the key. Otherwise, it returns 0, and
4504 the caller should handle the key, for instance, by calling the
4505 function minput_lookup () with the same key. */
4508 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4510 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4511 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4512 #Minput_preedit_draw, #Minput_status_draw,
4513 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4516 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4517 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4518 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4519 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4521 @latexonly \IPAlabel{minput_filter} @endlatexonly
4525 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4532 if (ic->im->driver.callback_list
4533 && mtext_nchars (ic->preedit) > 0)
4534 minput_callback (ic, Minput_preedit_draw);
4536 ret = (*ic->im->driver.filter) (ic, key, arg);
4538 if (ic->im->driver.callback_list)
4540 if (ic->preedit_changed)
4541 minput_callback (ic, Minput_preedit_draw);
4542 if (ic->status_changed)
4543 minput_callback (ic, Minput_status_draw);
4544 if (ic->candidates_changed)
4545 minput_callback (ic, Minput_candidates_draw);
4554 @brief Look up a text produced in the input context.
4556 The minput_lookup () function looks up a text in the input context
4557 $IC. $KEY must be identical to the one that was used in the previous call of
4560 If a text was produced by the input method, it is concatenated
4563 This function calls #MInputDriver::lookup .
4566 If $KEY was correctly handled by the input method, this function
4567 returns 0. Otherwise, it returns -1, even though some text
4568 might be produced in $MT. */
4571 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4573 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4574 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4576 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4579 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4582 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4583 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4584 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4586 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4589 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4591 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4596 @brief Set the spot of the input context.
4598 The minput_set_spot () function sets the spot of input context $IC
4599 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4600 The semantics of these values depends on the input method driver.
4602 For instance, a driver designed to work in a CUI environment may
4603 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4604 $DESCENT . A driver designed to work in a window system may
4605 interpret $X and $Y as the pixel offsets relative to the origin of the
4606 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4607 descent pixels of the line at ($X . $Y ).
4609 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4611 $MT and $POS are the M-text and the character position at the spot.
4612 $MT may be @c NULL, in which case, the input method cannot get
4613 information about the text around the spot. */
4616 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4618 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4619 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4620 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4622 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4623 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4624 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4625 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4626 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4627 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4629 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4631 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4632 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4636 minput_set_spot (MInputContext *ic, int x, int y,
4637 int ascent, int descent, int fontsize,
4642 ic->spot.ascent = ascent;
4643 ic->spot.descent = descent;
4644 ic->spot.fontsize = fontsize;
4647 if (ic->im->driver.callback_list)
4648 minput_callback (ic, Minput_set_spot);
4653 @brief Toggle input method.
4655 The minput_toggle () function toggles the input method associated
4656 with input context $IC. */
4658 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4660 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4661 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4665 minput_toggle (MInputContext *ic)
4667 if (ic->im->driver.callback_list)
4668 minput_callback (ic, Minput_toggle);
4669 ic->active = ! ic->active;
4675 @brief Reset an input context.
4677 The minput_reset_ic () function resets input context $IC by
4678 calling a callback function corresponding to #Minput_reset. It
4679 resets the status of $IC to its initial one. As the
4680 current preedit text is deleted without commitment, if necessary,
4681 call minput_filter () with the arg @r key #Mnil to force the input
4682 method to commit the preedit in advance. */
4685 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4687 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4688 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4689 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4690 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4691 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4692 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4695 minput_reset_ic (MInputContext *ic)
4697 if (ic->im->driver.callback_list)
4698 minput_callback (ic, Minput_reset);
4704 @brief Get title and icon filename of an input method.
4706 The minput_get_title_icon () function returns a plist containing a
4707 title and icon filename (if any) of an input method specified by
4708 $LANGUAGE and $NAME.
4710 The first element of the plist has key #Mtext and the value is an
4711 M-text of the title for identifying the input method. The second
4712 element (if any) has key #Mtext and the value is an M-text of the
4713 icon image (absolute) filename for the same purpose.
4716 If there exists a specified input method and it defines an title,
4717 a plist is returned. Otherwise, NULL is returned. The caller
4718 must free the plist by m17n_object_unref (). */
4720 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4722 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4723 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4726 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4727 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4728 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4731 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4732 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4733 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4736 minput_get_title_icon (MSymbol language, MSymbol name)
4738 MInputMethodInfo *im_info;
4745 im_info = get_im_info (language, name, Mnil, Mtitle);
4746 if (! im_info || !im_info->title)
4748 mt = mtext_get_prop (im_info->title, 0, Mtext);
4750 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4753 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4756 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4757 (char *) MSYMBOL_NAME (name));
4758 file = mdatabase__find_file (buf);
4759 if (! file && language == Mt)
4761 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4762 file = mdatabase__find_file (buf);
4767 mplist_add (plist, Mtext, im_info->title);
4770 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4772 mplist_add (plist, Mtext, mt);
4773 M17N_OBJECT_UNREF (mt);
4781 @brief Get description text of an input method.
4783 The minput_get_description () function returns an M-text that
4784 describes the input method specified by $LANGUAGE and $NAME.
4787 If the specified input method has a description text, a pointer to
4788 #MText is returned. The caller has to free it by m17n_object_unref ().
4789 If the input method does not have a description text, @c NULL is
4792 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4794 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4795 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4798 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4799 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4800 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4801 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4804 minput_get_description (MSymbol language, MSymbol name)
4806 MInputMethodInfo *im_info;
4814 extra = language, language = Mt;
4816 im_info = get_im_info (language, name, extra, Mdescription);
4817 if (! im_info || ! im_info->description)
4819 M17N_OBJECT_REF (im_info->description);
4820 return im_info->description;
4826 @brief Get information about input method command(s).
4828 The minput_get_command () function returns information about
4829 the command $COMMAND of the input method specified by $LANGUAGE and
4830 $NAME. An input method command is a pseudo key event to which one
4831 or more actual input key sequences are assigned.
4833 There are two kinds of commands, global and local. A global
4834 command has a global definition, and the description and the key
4835 assignment may be inherited by a local command. Each input method
4836 defines a local command which has a local key assignment. It may
4837 also declare a local command that inherits the definition of a
4838 global command of the same name.
4840 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4841 information about a global command. Otherwise information about a
4842 local command is returned.
4844 If $COMMAND is #Mnil, information about all commands is returned.
4846 The return value is a @e well-formed plist (@ref m17nPlist) of this
4849 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4851 @c NAME is a symbol representing the command name.
4853 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4854 command has no description.
4856 @c STATUS is a symbol representing how the key assignment is decided.
4857 The value is #Mnil (the default key assignment), #Mcustomized (the
4858 key assignment is customized by per-user customization file), or
4859 #Mconfigured (the key assignment is set by the call of
4860 minput_config_command ()). For a local command only, it may also
4861 be #Minherited (the key assignment is inherited from the
4862 corresponding global command).
4864 @c KEYSEQ is a plist of one or more symbols representing a key
4865 sequence assigned to the command. If there's no KEYSEQ, the
4866 command is currently disabled (i.e. no key sequence can trigger
4867 actions of the command).
4869 If $COMMAND is not #Mnil, the first element of the returned plist
4870 contains the information about $COMMAND.
4874 If the requested information was found, a pointer to a non-empty
4875 plist is returned. As the plist is kept in the library, the
4876 caller must not modify nor free it.
4878 Otherwise (the specified input method or the specified command
4879 does not exist), @c NULL is returned. */
4881 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4883 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4884 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4885 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4886 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4888 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4889 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4890 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4891 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4892 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4894 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4895 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4898 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4900 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4903 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4905 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4907 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4910 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4911 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4912 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4913 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4914 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4915 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4918 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4919 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4920 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4921 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4923 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4924 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4928 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4929 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4932 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4937 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4939 /* Return a description of the command COMMAND of the input method
4940 specified by LANGUAGE and NAME. */
4941 MPlist *cmd = minput_get_command (langauge, name, command);
4946 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4947 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4948 return (mplist_key (plist) == Mtext
4949 ? (MText *) mplist_value (plist)
4955 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4957 MInputMethodInfo *im_info;
4961 im_info = get_im_info (language, name, Mnil, Mcommand);
4963 || ! im_info->configured_cmds
4964 || MPLIST_TAIL_P (im_info->configured_cmds))
4966 if (command == Mnil)
4967 return im_info->configured_cmds;
4968 return mplist__assq (im_info->configured_cmds, command);
4974 @brief Configure the key sequence of an input method command.
4976 The minput_config_command () function assigns a list of key
4977 sequences $KEYSEQLIST to the command $COMMAND of the input method
4978 specified by $LANGUAGE and $NAME.
4980 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4981 sequences, and each key sequence must be a plist of symbols.
4983 If $KEYSEQLIST is an empty plist, any configuration and
4984 customization of the command are cancelled, and default key
4985 sequences become effective.
4987 If $KEYSEQLIST is NULL, the configuration of the command is
4988 canceled, and the original key sequences (what saved in per-user
4989 customization file, or the default one) become effective.
4991 In the latter two cases, $COMMAND can be #Mnil to make all the
4992 commands of the input method the target of the operation.
4994 If $NAME is #Mnil, this function configures the key assignment of a
4995 global command, not that of a specific input method.
4997 The configuration takes effect for input methods opened or
4998 re-opened later in the current session. In order to make the
4999 configuration take effect for the future session, it must be saved
5000 in a per-user customization file by the function
5001 minput_save_config ().
5004 If the operation was successful, this function returns 0,
5005 otherwise returns -1. The operation fails in these cases:
5007 <li>$KEYSEQLIST is not in a valid form.
5008 <li>$COMMAND is not available for the input method.
5009 <li>$LANGUAGE and $NAME do not specify an existing input method.
5013 minput_get_commands (), minput_save_config ().
5016 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5018 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5019 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5020 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5022 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5023 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5025 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5026 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5028 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5029 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5030 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5032 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5033 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5035 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5036 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5038 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5039 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5040 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5041 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5045 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5047 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5048 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5049 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5053 minput_get_commands (), minput_save_config ().
5057 /* Add "C-x u" to the "start" command of Unicode input method. */
5059 MSymbol start_command = msymbol ("start");
5060 MSymbol unicode = msymbol ("unicode");
5061 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5063 /* At first get the current key-sequence assignment. */
5064 cmd = minput_get_command (Mt, unicode, start_command);
5067 /* The input method does not have the command "start". Here
5068 should come some error handling code. */
5070 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5071 Extract the part (KEY-SEQUENCE ...). */
5072 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5073 /* Copy it because we should not modify it directly. */
5074 key_seq_list = mplist_copy (plist);
5076 key_seq = mplist ();
5077 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5078 mplist_add (key_seq, Msymbol, msymbol ("u"));
5079 mplist_add (key_seq_list, Mplist, key_seq);
5080 m17n_object_unref (key_seq);
5082 minput_config_command (Mt, unicode, start_command, key_seq_list);
5083 m17n_object_unref (key_seq_list);
5088 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5091 MInputMethodInfo *im_info, *config;
5096 im_info = get_im_info (language, name, Mnil, Mcommand);
5098 MERROR (MERROR_IM, -1);
5099 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5101 || ! mplist__assq (im_info->configured_cmds, command)))
5102 MERROR (MERROR_IM, -1);
5103 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5105 MPLIST_DO (plist, keyseqlist)
5106 if (! check_command_keyseq (plist))
5107 MERROR (MERROR_IM, -1);
5110 config = get_config_info (im_info);
5113 if (! im_config_list)
5114 im_config_list = mplist ();
5115 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5116 config->cmds = mplist ();
5117 config->vars = mplist ();
5120 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5121 /* Nothing to do. */
5124 if (command == Mnil)
5128 /* Cancal the configuration. */
5129 if (MPLIST_TAIL_P (config->cmds))
5131 mplist_set (config->cmds, Mnil, NULL);
5135 /* Cancal the customization. */
5136 MInputMethodInfo *custom = get_custom_info (im_info);
5138 if (MPLIST_TAIL_P (config->cmds)
5139 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5140 /* Nothing to do. */
5142 mplist_set (config->cmds, Mnil, NULL);
5143 MPLIST_DO (plist, custom->cmds)
5145 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5147 mplist_add (plist, Msymbol, command);
5148 mplist_push (config->cmds, Mplist, plist);
5149 M17N_OBJECT_UNREF (plist);
5155 plist = mplist__assq (config->cmds, command);
5158 /* Cancel the configuration. */
5161 mplist__pop_unref (plist);
5163 else if (MPLIST_TAIL_P (keyseqlist))
5165 /* Cancel the customization. */
5166 MInputMethodInfo *custom = get_custom_info (im_info);
5167 int no_custom = (! custom || ! custom->cmds
5168 || ! mplist__assq (custom->cmds, command));
5174 mplist_add (config->cmds, Mplist, plist);
5175 M17N_OBJECT_UNREF (plist);
5176 plist = mplist_add (plist, Msymbol, command);
5181 mplist__pop_unref (plist);
5184 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5185 plist = MPLIST_NEXT (plist);
5186 mplist_set (plist, Mnil, NULL);
5196 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5197 if (! MPLIST_TAIL_P (plist))
5198 mplist_set (plist, Mnil, NULL);
5203 mplist_add (config->cmds, Mplist, plist);
5204 M17N_OBJECT_UNREF (plist);
5205 plist = mplist_add (plist, Msymbol, command);
5206 plist = MPLIST_NEXT (plist);
5208 MPLIST_DO (keyseqlist, keyseqlist)
5210 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5211 plist = mplist_add (plist, Mplist, pl);
5212 M17N_OBJECT_UNREF (pl);
5216 config_all_commands (im_info);
5217 im_info->tick = time (NULL);
5224 @brief Get information about input method variable(s).
5226 The minput_get_variable () function returns information about
5227 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5228 An input method variable controls behavior of an input method.
5230 There are two kinds of variables, global and local. A global
5231 variable has a global definition, and the description and the value
5232 may be inherited by a local variable. Each input method defines a
5233 local variable which has local value. It may also declare a
5234 local variable that inherits definition of a global variable of
5237 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5238 variable is returned. Otherwise information about a local variable
5241 If $VARIABLE is #Mnil, information about all variables is
5244 The return value is a @e well-formed plist (@ref m17nPlist) of this
5247 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5249 @c NAME is a symbol representing the variable name.
5251 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5252 variable has no description.
5254 @c STATUS is a symbol representing how the value is decided. The
5255 value is #Mnil (the default value), #Mcustomized (the value is
5256 customized by per-user customization file), or #Mconfigured (the
5257 value is set by the call of minput_config_variable ()). For a
5258 local variable only, it may also be #Minherited (the value is
5259 inherited from the corresponding global variable).
5261 @c VALUE is the initial value of the variable. If the key of this
5262 element is #Mt, the variable has no initial value. Otherwise, the
5263 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5266 @c VALID-VALUEs (if any) specify which values the variable can have.
5267 They have the same type (i.e. having the same key) as @c VALUE except
5268 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5269 may be a plist of two integers specifying the range of possible
5272 If there no @c VALID-VALUE, the variable can have any value as long
5273 as the type is the same as @c VALUE.
5275 If $VARIABLE is not #Mnil, the first element of the returned plist
5276 contains the information about $VARIABLE.
5280 If the requested information was found, a pointer to a non-empty
5281 plist is returned. As the plist is kept in the library, the
5282 caller must not modify nor free it.
5284 Otherwise (the specified input method or the specified variable
5285 does not exist), @c NULL is returned. */
5287 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5289 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5290 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5291 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5293 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5294 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5295 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5296 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5299 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5300 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5302 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5304 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5306 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5309 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5311 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5314 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5315 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5316 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5317 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5318 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5319 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5321 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5322 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5323 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5325 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5326 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5327 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5328 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5330 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5333 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5334 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5338 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5339 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5342 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5346 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5348 MInputMethodInfo *im_info;
5352 im_info = get_im_info (language, name, Mnil, Mvariable);
5353 if (! im_info || ! im_info->configured_vars)
5355 if (variable == Mnil)
5356 return im_info->configured_vars;
5357 return mplist__assq (im_info->configured_vars, variable);
5363 @brief Configure the value of an input method variable.
5365 The minput_config_variable () function assigns $VALUE to the
5366 variable $VARIABLE of the input method specified by $LANGUAGE and
5369 If $VALUE is a non-empty plist, it must be a plist of one element
5370 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5371 the corresponding type. That value is assigned to the variable.
5373 If $VALUE is an empty plist, any configuration and customization
5374 of the variable are canceled, and the default value is assigned to
5377 If $VALUE is NULL, the configuration of the variable is canceled,
5378 and the original value (what saved in per-user customization file,
5379 or the default value) is assigned to the variable.
5381 In the latter two cases, $VARIABLE can be #Mnil to make all the
5382 variables of the input method the target of the operation.
5384 If $NAME is #Mnil, this function configures the value of global
5385 variable, not that of a specific input method.
5387 The configuration takes effect for input methods opened or
5388 re-opened later in the current session. To make the configuration
5389 take effect for the future session, it must be saved in a per-user
5390 customization file by the function minput_save_config ().
5394 If the operation was successful, this function returns 0,
5395 otherwise returns -1. The operation fails in these cases:
5397 <li>$VALUE is not in a valid form, the type does not match the
5398 definition, or the value is our of range.
5399 <li>$VARIABLE is not available for the input method.
5400 <li>$LANGUAGE and $NAME do not specify an existing input method.
5404 minput_get_variable (), minput_save_config (). */
5406 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5408 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5409 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5411 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5412 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5413 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5415 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5416 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5418 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5419 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5421 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5422 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5424 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5425 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5427 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5428 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5429 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5430 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5434 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5436 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5437 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5438 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5442 minput_get_commands (), minput_save_config ().
5445 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5448 MInputMethodInfo *im_info, *config;
5453 im_info = get_im_info (language, name, Mnil, Mvariable);
5455 MERROR (MERROR_IM, -1);
5456 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5458 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5459 MERROR (MERROR_IM, -1);
5461 if (value && ! MPLIST_TAIL_P (value))
5463 plist = MPLIST_PLIST (plist);
5464 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5465 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5466 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5467 if (MPLIST_KEY (plist) != Mt
5468 && ! check_variable_value (value, plist))
5469 MERROR (MERROR_IM, -1);
5472 config = get_config_info (im_info);
5475 if (! im_config_list)
5476 im_config_list = mplist ();
5477 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5478 config->cmds = mplist ();
5479 config->vars = mplist ();
5482 if (! value && MPLIST_TAIL_P (config->vars))
5483 /* Nothing to do. */
5486 if (variable == Mnil)
5490 /* Cancel the configuration. */
5491 if (MPLIST_TAIL_P (config->vars))
5493 mplist_set (config->vars, Mnil, NULL);
5497 /* Cancel the customization. */
5498 MInputMethodInfo *custom = get_custom_info (im_info);
5500 if (MPLIST_TAIL_P (config->vars)
5501 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5502 /* Nothing to do. */
5504 mplist_set (config->vars, Mnil, NULL);
5505 MPLIST_DO (plist, custom->vars)
5507 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5509 mplist_add (plist, Msymbol, variable);
5510 mplist_push (config->vars, Mplist, plist);
5511 M17N_OBJECT_UNREF (plist);
5517 plist = mplist__assq (config->vars, variable);
5520 /* Cancel the configuration. */
5523 mplist__pop_unref (plist);
5525 else if (MPLIST_TAIL_P (value))
5527 /* Cancel the customization. */
5528 MInputMethodInfo *custom = get_custom_info (im_info);
5529 int no_custom = (! custom || ! custom->vars
5530 || ! mplist__assq (custom->vars, variable));
5536 mplist_add (config->vars, Mplist, plist);
5537 M17N_OBJECT_UNREF (plist);
5538 plist = mplist_add (plist, Msymbol, variable);
5543 mplist__pop_unref (plist);
5546 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5547 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5548 mplist_set (plist, Mnil ,NULL);
5556 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5557 if (! MPLIST_TAIL_P (plist))
5558 mplist_set (plist, Mnil, NULL);
5563 mplist_add (config->vars, Mplist, plist);
5564 M17N_OBJECT_UNREF (plist);
5565 plist = mplist_add (plist, Msymbol, variable);
5566 plist = MPLIST_NEXT (plist);
5568 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5571 config_all_variables (im_info);
5572 im_info->tick = time (NULL);
5579 @brief Get the name of per-user customization file.
5581 The minput_config_file () function returns the absolute path name
5582 of per-user customization file into which minput_save_config ()
5583 save configurations. It is usually @c "config.mic" under the
5584 directory @c ".m17n.d" of user's home directory. It is not assured
5585 that the file of the returned name exists nor is
5586 readable/writable. If minput_save_config () fails and returns -1,
5587 an application program might check the file, make it
5588 writable (if possible), and try minput_save_config () again.
5592 This function returns a string. As the string is kept in the
5593 library, the caller must not modify nor free it.
5596 minput_save_config ()
5599 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5601 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5602 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5603 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5604 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5605 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5606 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5607 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5612 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5613 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5616 minput_save_config ()
5620 minput_config_file ()
5624 return mdatabase__file (im_custom_mdb);
5630 @brief Save configurations in per-user customization file.
5632 The minput_save_config () function saves the configurations done
5633 so far in the current session into the per-user customization
5638 If the operation was successful, 1 is returned. If the per-user
5639 customization file is currently locked, 0 is returned. In that
5640 case, the caller may wait for a while and try again. If the
5641 configuration file is not writable, -1 is returned. In that case,
5642 the caller may check the name of the file by calling
5643 minput_config_file (), make it writable if possible, and try
5647 minput_config_file () */
5649 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5651 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5652 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5656 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5657 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5658 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5659 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5663 minput_config_file () */
5666 minput_save_config (void)
5668 MPlist *data, *tail, *plist, *p, *elt;
5672 ret = mdatabase__lock (im_custom_mdb);
5675 if (! im_config_list)
5677 update_custom_info ();
5678 if (! im_custom_list)
5679 im_custom_list = mplist ();
5681 /* At first, reflect configuration in customization. */
5682 MPLIST_DO (plist, im_config_list)
5684 MPlist *pl = MPLIST_PLIST (plist);
5685 MSymbol language, name, extra, command, variable;
5686 MInputMethodInfo *custom, *config;
5688 language = MPLIST_SYMBOL (pl);
5689 pl = MPLIST_NEXT (pl);
5690 name = MPLIST_SYMBOL (pl);
5691 pl = MPLIST_NEXT (pl);
5692 extra = MPLIST_SYMBOL (pl);
5693 pl = MPLIST_NEXT (pl);
5694 config = MPLIST_VAL (pl);
5695 custom = get_custom_info (config);
5697 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5699 MPLIST_DO (pl, config->cmds)
5701 elt = MPLIST_PLIST (pl);
5702 command = MPLIST_SYMBOL (elt);
5704 p = mplist__assq (custom->cmds, command);
5706 custom->cmds = mplist (), p = NULL;
5707 elt = MPLIST_NEXT (elt);
5710 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5711 mplist_set (p, Mnil, NULL);
5716 mplist_add (custom->cmds, Mplist, p);
5717 M17N_OBJECT_UNREF (p);
5718 mplist_add (p, Msymbol, command);
5719 p = mplist_add (p, Msymbol, Mnil);
5720 p = MPLIST_NEXT (p);
5722 mplist__conc (p, elt);
5725 MPLIST_DO (pl, config->vars)
5727 elt = MPLIST_PLIST (pl);
5728 variable = MPLIST_SYMBOL (elt);
5730 p = mplist__assq (custom->vars, variable);
5732 custom->vars = mplist (), p = NULL;
5733 elt = MPLIST_NEXT (elt);
5736 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5737 mplist_set (p, Mnil, NULL);
5742 mplist_add (custom->vars, Mplist, p);
5743 M17N_OBJECT_UNREF (p);
5744 mplist_add (p, Msymbol, variable);
5745 p = mplist_add (p, Msymbol, Mnil);
5746 p = MPLIST_NEXT (p);
5748 mplist__conc (p, elt);
5751 free_im_list (im_config_list);
5752 im_config_list = NULL;
5754 /* Next, reflect customization to the actual plist to be written. */
5755 data = tail = mplist ();
5756 MPLIST_DO (plist, im_custom_list)
5758 MPlist *pl = MPLIST_PLIST (plist);
5759 MSymbol language, name, extra;
5760 MInputMethodInfo *custom, *im_info;
5762 language = MPLIST_SYMBOL (pl);
5763 pl = MPLIST_NEXT (pl);
5764 name = MPLIST_SYMBOL (pl);
5765 pl = MPLIST_NEXT (pl);
5766 extra = MPLIST_SYMBOL (pl);
5767 pl = MPLIST_NEXT (pl);
5768 custom = MPLIST_VAL (pl);
5769 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5770 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5772 im_info = lookup_im_info (im_info_list, language, name, extra);
5776 config_all_commands (im_info);
5778 config_all_variables (im_info);
5782 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5784 MPLIST_DO (p, custom->cmds)
5785 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5787 if (! MPLIST_TAIL_P (p))
5791 mplist_add (elt, Mplist, pl);
5792 M17N_OBJECT_UNREF (pl);
5793 pl = mplist_add (pl, Msymbol, Mcommand);
5794 MPLIST_DO (p, custom->cmds)
5795 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5796 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5799 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5801 MPLIST_DO (p, custom->vars)
5802 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5804 if (! MPLIST_TAIL_P (p))
5809 mplist_add (elt, Mplist, pl);
5810 M17N_OBJECT_UNREF (pl);
5811 pl = mplist_add (pl, Msymbol, Mvariable);
5812 MPLIST_DO (p, custom->vars)
5813 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5814 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5820 mplist_push (elt, Mplist, pl);
5821 M17N_OBJECT_UNREF (pl);
5822 pl = mplist_add (pl, Msymbol, Minput_method);
5823 pl = mplist_add (pl, Msymbol, language);
5824 pl = mplist_add (pl, Msymbol, name);
5826 pl = mplist_add (pl, Msymbol, extra);
5827 tail = mplist_add (tail, Mplist, elt);
5828 M17N_OBJECT_UNREF (elt);
5832 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5833 ret = mdatabase__save (im_custom_mdb, data);
5834 mdatabase__unlock (im_custom_mdb);
5835 M17N_OBJECT_UNREF (data);
5836 return (ret < 0 ? -1 : 1);
5843 @name Obsolete functions
5846 @name Obsolete ¤Ê´Ø¿ô
5852 @brief Get a list of variables of an input method (obsolete).
5854 This function is obsolete. Use minput_get_variable () instead.
5856 The minput_get_variables () function returns a plist (#MPlist) of
5857 variables used to control the behavior of the input method
5858 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5859 (@ref m17nPlist) of the following format:
5862 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5863 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5867 @c VARNAME is a symbol representing the variable name.
5869 @c DOC-MTEXT is an M-text describing the variable.
5871 @c DEFAULT-VALUE is the default value of the variable. It is a
5872 symbol, integer, or M-text.
5874 @c VALUEs (if any) specifies the possible values of the variable.
5875 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5876 @c TO), where @c FROM and @c TO specifies a range of possible
5879 For instance, suppose an input method has the variables:
5881 @li name:intvar, description:"value is an integer",
5882 initial value:0, value-range:0..3,10,20
5884 @li name:symvar, description:"value is a symbol",
5885 initial value:nil, value-range:a, b, c, nil
5887 @li name:txtvar, description:"value is an M-text",
5888 initial value:empty text, no value-range (i.e. any text)
5890 Then, the returned plist is as follows.
5893 (intvar ("value is an integer" 0 (0 3) 10 20)
5894 symvar ("value is a symbol" nil a b c nil)
5895 txtvar ("value is an M-text" ""))
5899 If the input method uses any variables, a pointer to #MPlist is
5900 returned. As the plist is kept in the library, the caller must not
5901 modify nor free it. If the input method does not use any
5902 variable, @c NULL is returned. */
5904 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5906 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5907 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5908 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5912 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5913 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5917 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5919 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5921 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5924 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5925 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5926 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5928 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5930 @li name:intvar, ÀâÌÀ:"value is an integer",
5931 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5933 @li name:symvar, ÀâÌÀ:"value is a symbol",
5934 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5936 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5937 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5939 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5942 (intvar ("value is an integer" 0 (0 3) 10 20)
5943 symvar ("value is a symbol" nil a b c nil)
5944 txtvar ("value is an M-text" ""))
5948 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5949 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5950 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5953 minput_get_variables (MSymbol language, MSymbol name)
5955 MInputMethodInfo *im_info;
5960 im_info = get_im_info (language, name, Mnil, Mvariable);
5961 if (! im_info || ! im_info->configured_vars)
5964 M17N_OBJECT_UNREF (im_info->bc_vars);
5965 im_info->bc_vars = mplist ();
5966 MPLIST_DO (vars, im_info->configured_vars)
5968 MPlist *plist = MPLIST_PLIST (vars);
5969 MPlist *elt = mplist ();
5971 mplist_push (im_info->bc_vars, Mplist, elt);
5972 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5973 elt = MPLIST_NEXT (elt);
5974 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5975 M17N_OBJECT_UNREF (elt);
5977 return im_info->bc_vars;
5983 @brief Set the initial value of an input method variable.
5985 The minput_set_variable () function sets the initial value of
5986 input method variable $VARIABLE to $VALUE for the input method
5987 specified by $LANGUAGE and $NAME.
5989 By default, the initial value is 0.
5991 This setting gets effective in a newly opened input method.
5994 If the operation was successful, 0 is returned. Otherwise -1 is
5995 returned, and #merror_code is set to #MERROR_IM. */
5997 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5999 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6000 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6001 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6003 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6005 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6008 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6009 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6012 minput_set_variable (MSymbol language, MSymbol name,
6013 MSymbol variable, void *value)
6016 MInputMethodInfo *im_info;
6021 if (variable == Mnil)
6022 MERROR (MERROR_IM, -1);
6023 plist = minput_get_variable (language, name, variable);
6024 plist = MPLIST_PLIST (plist);
6025 plist = MPLIST_NEXT (plist);
6027 mplist_add (pl, MPLIST_KEY (plist), value);
6028 ret = minput_config_variable (language, name, variable, pl);
6029 M17N_OBJECT_UNREF (pl);
6032 im_info = get_im_info (language, name, Mnil, Mvariable);
6041 @brief Get information about input method commands.
6043 The minput_get_commands () function returns information about
6044 input method commands of the input method specified by $LANGUAGE
6045 and $NAME. An input method command is a pseudo key event to which
6046 one or more actual input key sequences are assigned.
6048 There are two kinds of commands, global and local. Global
6049 commands are used by multiple input methods for the same purpose,
6050 and have global key assignments. Local commands are used only by
6051 a specific input method, and have only local key assignments.
6053 Each input method may locally change key assignments for global
6054 commands. The global key assignment for a global command is
6055 effective only when the current input method does not have local
6056 key assignments for that command.
6058 If $NAME is #Mnil, information about global commands is returned.
6059 In this case $LANGUAGE is ignored.
6061 If $NAME is not #Mnil, information about those commands that have
6062 local key assignments in the input method specified by $LANGUAGE
6063 and $NAME is returned.
6066 If no input method commands are found, this function returns @c NULL.
6068 Otherwise, a pointer to a plist is returned. The key of each
6069 element in the plist is a symbol representing a command, and the
6070 value is a plist of the form COMMAND-INFO described below.
6072 The first element of COMMAND-INFO has the key #Mtext, and the
6073 value is an M-text describing the command.
6075 If there are no more elements, that means no key sequences are
6076 assigned to the command. Otherwise, each of the remaining
6077 elements has the key #Mplist, and the value is a plist whose keys are
6078 #Msymbol and values are symbols representing input keys, which are
6079 currently assigned to the command.
6081 As the returned plist is kept in the library, the caller must not
6082 modify nor free it. */
6084 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6086 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6087 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6088 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6089 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6091 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6092 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6093 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6094 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6096 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6097 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6098 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6101 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6102 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6104 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6105 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6109 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6111 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6112 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6113 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6115 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6116 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6117 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6120 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6121 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6122 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6123 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6124 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6126 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6127 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6130 minput_get_commands (MSymbol language, MSymbol name)
6132 MInputMethodInfo *im_info;
6137 im_info = get_im_info (language, name, Mnil, Mcommand);
6138 if (! im_info || ! im_info->configured_vars)
6140 M17N_OBJECT_UNREF (im_info->bc_cmds);
6141 im_info->bc_cmds = mplist ();
6142 MPLIST_DO (cmds, im_info->configured_cmds)
6144 MPlist *plist = MPLIST_PLIST (cmds);
6145 MPlist *elt = mplist ();
6147 mplist_push (im_info->bc_cmds, Mplist, elt);
6148 mplist_add (elt, MPLIST_SYMBOL (plist),
6149 mplist_copy (MPLIST_NEXT (plist)));
6150 M17N_OBJECT_UNREF (elt);
6152 return im_info->bc_cmds;
6158 @brief Assign a key sequence to an input method command (obsolete).
6160 This function is obsolete. Use minput_config_command () instead.
6162 The minput_assign_command_keys () function assigns input key
6163 sequence $KEYSEQ to input method command $COMMAND for the input
6164 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6165 key sequence is assigned globally no matter what $LANGUAGE is.
6166 Otherwise the key sequence is assigned locally.
6168 Each element of $KEYSEQ must have the key $Msymbol and the value
6169 must be a symbol representing an input key.
6171 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6172 globally or locally.
6174 This assignment gets effective in a newly opened input method.
6177 If the operation was successful, 0 is returned. Otherwise -1 is
6178 returned, and #merror_code is set to #MERROR_IM. */
6180 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6182 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6183 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6184 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6185 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6186 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6188 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6189 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6191 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6192 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6194 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6198 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6199 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6202 minput_assign_command_keys (MSymbol language, MSymbol name,
6203 MSymbol command, MPlist *keyseq)
6209 if (command == Mnil)
6210 MERROR (MERROR_IM, -1);
6215 if (! check_command_keyseq (keyseq))
6216 MERROR (MERROR_IM, -1);
6218 mplist_add (plist, Mplist, keyseq);
6223 ret = minput_config_command (language, name, command, keyseq);
6224 M17N_OBJECT_UNREF (keyseq);
6231 @brief Call a callback function
6233 The minput_callback () functions calls a callback function
6234 $COMMAND assigned for the input context $IC. The caller must set
6235 specific elements in $IC->plist if the callback function requires.
6238 If there exists a specified callback function, 0 is returned.
6239 Otherwise -1 is returned. By side effects, $IC->plist may be
6243 minput_callback (MInputContext *ic, MSymbol command)
6245 MInputCallbackFunc func;
6247 if (! ic->im->driver.callback_list)
6249 func = ((MInputCallbackFunc)
6250 mplist_get_func (ic->im->driver.callback_list, command));
6253 (func) (ic, command);
6260 /*** @addtogroup m17nDebug */
6266 @brief Dump an input method.
6268 The mdebug_dump_im () function prints the input method $IM in a
6269 human readable way to the stderr. $INDENT specifies how many
6270 columns to indent the lines but the first one.
6273 This function returns $IM. */
6275 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6277 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6278 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6281 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6284 mdebug_dump_im (MInputMethod *im, int indent)
6286 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6289 prefix = (char *) alloca (indent + 1);
6290 memset (prefix, 32, indent);
6291 prefix[indent] = '\0';
6293 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6294 msymbol_name (im->name));
6295 mdebug_dump_mtext (im_info->title, 0, 0);
6296 if (im->name != Mnil)
6300 MPLIST_DO (state, im_info->states)
6302 fprintf (stderr, "\n%s ", prefix);
6303 dump_im_state (MPLIST_VAL (state), indent + 2);
6306 fprintf (stderr, ")");