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 - 1);
591 mt = get_surrounding_text (ic, pos);
594 len = mtext_nchars (mt);
595 if (ic_info->following_text)
597 if (mtext_nchars (ic_info->following_text) < len)
599 M17N_OBJECT_UNREF (ic_info->following_text);
600 ic_info->following_text = mt;
603 M17N_OBJECT_UNREF (mt);
606 ic_info->following_text = mt;
609 return mtext_ref_char (ic_info->following_text, pos - 1);
613 surrounding_pos (MSymbol sym)
619 name = MSYMBOL_NAME (sym);
621 && (name[1] == '-' || name[1] == '+')
622 && name[2] >= '1' && name[2] <= '9')
623 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
628 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
630 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
632 MText *preedit = ic->preedit;
633 int len = mtext_nchars (preedit);
637 if (MPLIST_INTEGER_P (arg))
638 return MPLIST_INTEGER (arg);
640 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
643 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
647 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
650 return ic_info->key_head;
651 if ((code == '-' || code == '+'))
653 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
657 pos = atoi (name + 1);
659 return get_preceding_char (ic, 0);
660 pos = ic->cursor_pos + pos;
663 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
664 return mtext_ref_char (ic->produced,
665 mtext_len (ic->produced) + pos);
666 return get_preceding_char (ic, - pos);
669 return get_following_char (ic, pos - len + 1);
672 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
674 else if (code >= '0' && code <= '9')
676 else if (code == '=')
677 pos = ic->cursor_pos;
678 else if (code == '[')
679 pos = ic->cursor_pos - 1;
680 else if (code == ']')
681 pos = ic->cursor_pos + 1;
682 else if (code == '<')
684 else if (code == '>')
686 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
690 parse_expression (MPlist *plist)
694 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
696 if (! MPLIST_PLIST_P (plist))
698 plist = MPLIST_PLIST (plist);
699 op = MPLIST_SYMBOL (plist);
700 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
701 && op != Mand && op != Mor && op != Mnot
702 && op != Mless && op != Mgreater && op != Mequal
703 && op != Mless_equal && op != Mgreater_equal)
704 MERROR (MERROR_IM, -1);
705 MPLIST_DO (plist, MPLIST_NEXT (plist))
706 if (parse_expression (plist) < 0)
712 resolve_expression (MInputContext *ic, MPlist *plist)
717 if (MPLIST_INTEGER_P (plist))
718 return MPLIST_INTEGER (plist);
719 if (MPLIST_SYMBOL_P (plist))
720 return integer_value (ic, plist, NULL, 1);
721 if (! MPLIST_PLIST_P (plist))
723 plist = MPLIST_PLIST (plist);
724 if (! MPLIST_SYMBOL_P (plist))
726 op = MPLIST_SYMBOL (plist);
727 plist = MPLIST_NEXT (plist);
728 val = resolve_expression (ic, plist);
730 MPLIST_DO (plist, MPLIST_NEXT (plist))
731 val += resolve_expression (ic, plist);
732 else if (op == Mminus)
733 MPLIST_DO (plist, MPLIST_NEXT (plist))
734 val -= resolve_expression (ic, plist);
735 else if (op == Mstar)
736 MPLIST_DO (plist, MPLIST_NEXT (plist))
737 val *= resolve_expression (ic, plist);
738 else if (op == Mslash)
739 MPLIST_DO (plist, MPLIST_NEXT (plist))
740 val /= resolve_expression (ic, plist);
742 MPLIST_DO (plist, MPLIST_NEXT (plist))
743 val &= resolve_expression (ic, plist);
745 MPLIST_DO (plist, MPLIST_NEXT (plist))
746 val |= resolve_expression (ic, plist);
749 else if (op == Mless)
750 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
751 else if (op == Mequal)
752 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
753 else if (op == Mgreater)
754 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
755 else if (op == Mless_equal)
756 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
757 else if (op == Mgreater_equal)
758 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
762 /* Parse PLIST as an action list. PLIST should have this form:
763 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
764 Return 0 if successfully parsed, otherwise return -1. */
767 parse_action_list (MPlist *plist, MPlist *macros)
769 MPLIST_DO (plist, plist)
771 if (MPLIST_MTEXT_P (plist))
773 /* This is a short form of (insert MTEXT). */
774 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
775 MERROR (MERROR_IM, -1); */
777 else if (MPLIST_PLIST_P (plist)
778 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
779 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
783 /* This is a short form of (insert (GROUPS *)). */
784 MPLIST_DO (pl, MPLIST_PLIST (plist))
786 if (MPLIST_PLIST_P (pl))
790 MPLIST_DO (elt, MPLIST_PLIST (pl))
791 if (! MPLIST_MTEXT_P (elt)
792 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
793 MERROR (MERROR_IM, -1);
797 if (! MPLIST_MTEXT_P (pl)
798 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
799 MERROR (MERROR_IM, -1);
803 else if (MPLIST_INTEGER_P (plist))
805 int c = MPLIST_INTEGER (plist);
807 if (c < 0 || c > MCHAR_MAX)
808 MERROR (MERROR_IM, -1);
810 else if (MPLIST_PLIST_P (plist)
811 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
813 MPlist *pl = MPLIST_PLIST (plist);
814 MSymbol action_name = MPLIST_SYMBOL (pl);
816 pl = MPLIST_NEXT (pl);
818 if (action_name == Minsert)
820 if (MPLIST_MTEXT_P (pl))
822 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
823 MERROR (MERROR_IM, -1);
825 else if (MPLIST_PLIST_P (pl))
827 MPLIST_DO (pl, MPLIST_PLIST (pl))
829 if (MPLIST_PLIST_P (pl))
833 MPLIST_DO (elt, MPLIST_PLIST (pl))
834 if (! MPLIST_MTEXT_P (elt)
835 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
836 MERROR (MERROR_IM, -1);
840 if (! MPLIST_MTEXT_P (pl)
841 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
842 MERROR (MERROR_IM, -1);
846 else if (! MPLIST_SYMBOL_P (pl))
847 MERROR (MERROR_IM, -1);
849 else if (action_name == Mselect
850 || action_name == Mdelete
851 || action_name == Mmove)
853 if (parse_expression (pl) < 0)
856 else if (action_name == Mmark
857 || action_name == Mcall
858 || action_name == Mshift)
860 if (! MPLIST_SYMBOL_P (pl))
861 MERROR (MERROR_IM, -1);
863 else if (action_name == Mundo)
865 if (! MPLIST_TAIL_P (pl))
867 if (! MPLIST_SYMBOL_P (pl)
868 && ! MPLIST_INTEGER_P (pl))
869 MERROR (MERROR_IM, -1);
872 else if (action_name == Mpushback)
874 if (MPLIST_MTEXT_P (pl))
876 MText *mt = MPLIST_MTEXT (pl);
878 if (mtext_nchars (mt) != mtext_nbytes (mt))
879 MERROR (MERROR_IM, -1);
881 else if (MPLIST_PLIST_P (pl))
885 MPLIST_DO (p, MPLIST_PLIST (pl))
886 if (! MPLIST_SYMBOL_P (p))
887 MERROR (MERROR_IM, -1);
889 else if (! MPLIST_INTEGER_P (pl))
890 MERROR (MERROR_IM, -1);
892 else if (action_name == Mset || action_name == Madd
893 || action_name == Msub || action_name == Mmul
894 || action_name == Mdiv)
896 if (! MPLIST_SYMBOL_P (pl))
897 MERROR (MERROR_IM, -1);
898 if (parse_expression (MPLIST_NEXT (pl)) < 0)
901 else if (action_name == Mequal || action_name == Mless
902 || action_name == Mgreater || action_name == Mless_equal
903 || action_name == Mgreater_equal)
905 if (parse_expression (pl) < 0
906 || parse_expression (MPLIST_NEXT (pl)) < 0)
908 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
909 if (! MPLIST_PLIST_P (pl))
910 MERROR (MERROR_IM, -1);
911 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
912 MERROR (MERROR_IM, -1);
913 pl = MPLIST_NEXT (pl);
914 if (MPLIST_PLIST_P (pl)
915 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
916 MERROR (MERROR_IM, -1);
918 else if (action_name == Mshow || action_name == Mhide
919 || action_name == Mcommit || action_name == Munhandle
920 || action_name == Mpop)
922 else if (action_name == Mcond)
925 if (! MPLIST_PLIST_P (pl))
926 MERROR (MERROR_IM, -1);
928 else if (! macros || ! mplist_get (macros, action_name))
929 MERROR (MERROR_IM, -1);
931 else if (! MPLIST_SYMBOL_P (plist))
932 MERROR (MERROR_IM, -1);
939 resolve_command (MPlist *cmds, MSymbol command)
943 if (! cmds || ! (plist = mplist__assq (cmds, command)))
945 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
946 plist = MPLIST_NEXT (plist);
947 plist = MPLIST_NEXT (plist);
948 plist = MPLIST_NEXT (plist);
952 /* Load a translation into MAP from PLIST.
954 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
957 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
958 MPlist *branch_actions, MPlist *macros)
963 if (MPLIST_MTEXT_P (keylist))
965 MText *mt = MPLIST_MTEXT (keylist);
967 len = mtext_nchars (mt);
968 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
970 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
971 for (i = 0; i < len; i++)
972 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
978 if (MFAILP (MPLIST_PLIST_P (keylist)))
980 elt = MPLIST_PLIST (keylist);
981 len = MPLIST_LENGTH (elt);
982 if (MFAILP (len > 0))
984 keyseq = (MSymbol *) alloca (sizeof (int) * len);
985 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
987 if (MPLIST_INTEGER_P (elt))
989 int c = MPLIST_INTEGER (elt);
991 if (MFAILP (c >= 0 && c < 0x100))
993 keyseq[i] = one_char_symbol[c];
997 if (MFAILP (MPLIST_SYMBOL_P (elt)))
999 keyseq[i] = MPLIST_SYMBOL (elt);
1004 for (i = 0; i < len; i++)
1006 MIMMap *deeper = NULL;
1009 deeper = mplist_get (map->submaps, keyseq[i]);
1011 map->submaps = mplist ();
1014 /* Fixme: It is better to make all deeper maps at once. */
1015 MSTRUCT_CALLOC (deeper, MERROR_IM);
1016 mplist_put (map->submaps, keyseq[i], deeper);
1021 /* We reach a terminal map. */
1022 if (map->map_actions
1023 || map->branch_actions)
1024 /* This map is already defined. We avoid overriding it. */
1027 if (! MPLIST_TAIL_P (map_actions))
1029 if (parse_action_list (map_actions, macros) < 0)
1030 MERROR (MERROR_IM, -1);
1031 map->map_actions = map_actions;
1035 map->branch_actions = branch_actions;
1036 M17N_OBJECT_REF (branch_actions);
1042 /* Load a branch from PLIST into MAP. PLIST has this form:
1043 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1046 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1049 MPlist *branch_actions;
1051 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1053 map_name = MPLIST_SYMBOL (plist);
1054 plist = MPLIST_NEXT (plist);
1055 if (MPLIST_TAIL_P (plist))
1056 branch_actions = NULL;
1057 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1060 branch_actions = plist;
1061 if (map_name == Mnil)
1063 map->branch_actions = branch_actions;
1065 M17N_OBJECT_REF (branch_actions);
1067 else if (map_name == Mt)
1069 map->map_actions = branch_actions;
1071 M17N_OBJECT_REF (branch_actions);
1073 else if (im_info->maps)
1075 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1076 if (! plist && im_info->configured_vars)
1078 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1080 if (p && MPLIST_PLIST_P (p))
1082 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1083 if (MPLIST_SYMBOL_P (p))
1084 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1089 MPLIST_DO (plist, plist)
1091 MPlist *keylist, *map_actions;
1093 if (! MPLIST_PLIST_P (plist))
1094 MERROR (MERROR_IM, -1);
1095 keylist = MPLIST_PLIST (plist);
1096 map_actions = MPLIST_NEXT (keylist);
1097 if (MPLIST_SYMBOL_P (keylist))
1099 MSymbol command = MPLIST_SYMBOL (keylist);
1102 if (MFAILP (command != Mat_reload))
1104 pl = resolve_command (im_info->configured_cmds, command);
1108 load_translation (map, pl, map_actions, branch_actions,
1112 load_translation (map, keylist, map_actions, branch_actions,
1121 /* Load a macro from PLIST into IM_INFO->macros.
1122 PLIST has this from:
1123 PLIST ::= ( MACRO-NAME ACTION * )
1124 IM_INFO->macros is a plist of macro names vs action list. */
1127 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1132 if (! MPLIST_SYMBOL_P (plist))
1133 MERROR (MERROR_IM, -1);
1134 name = MPLIST_SYMBOL (plist);
1135 plist = MPLIST_NEXT (plist);
1136 if (MPLIST_TAIL_P (plist)
1137 || parse_action_list (plist, im_info->macros) < 0)
1138 MERROR (MERROR_IM, -1);
1139 pl = mplist_get (im_info->macros, name);
1140 M17N_OBJECT_UNREF (pl);
1141 mplist_put (im_info->macros, name, plist);
1142 M17N_OBJECT_REF (plist);
1146 /* Load an external module from PLIST into IM_INFO->externals.
1147 PLIST has this form:
1148 PLIST ::= ( MODULE-NAME FUNCTION * )
1149 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1152 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1157 MIMExternalModule *external;
1161 if (MPLIST_MTEXT_P (plist))
1162 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1163 else if (MPLIST_SYMBOL_P (plist))
1164 module = MPLIST_SYMBOL (plist);
1165 module_file = alloca (strlen (MSYMBOL_NAME (module))
1166 + strlen (DLOPEN_SHLIB_EXT) + 1);
1167 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1169 handle = dlopen (module_file, RTLD_NOW);
1170 if (MFAILP (handle))
1172 fprintf (stderr, "%s\n", dlerror ());
1175 func_list = mplist ();
1176 MPLIST_DO (plist, MPLIST_NEXT (plist))
1178 if (! MPLIST_SYMBOL_P (plist))
1179 MERROR_GOTO (MERROR_IM, err_label);
1180 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1183 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1186 MSTRUCT_MALLOC (external, MERROR_IM);
1187 external->handle = handle;
1188 external->func_list = func_list;
1189 mplist_add (im_info->externals, module, external);
1194 M17N_OBJECT_UNREF (func_list);
1199 free_map (MIMMap *map, int top)
1204 M17N_OBJECT_UNREF (map->map_actions);
1207 MPLIST_DO (plist, map->submaps)
1208 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1209 M17N_OBJECT_UNREF (map->submaps);
1211 M17N_OBJECT_UNREF (map->branch_actions);
1216 free_state (void *object)
1218 MIMState *state = object;
1220 M17N_OBJECT_UNREF (state->title);
1222 free_map (state->map, 1);
1226 /** Load a state from PLIST into a newly allocated state object.
1227 PLIST has this form:
1228 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1229 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1230 Return the state object. */
1233 load_state (MInputMethodInfo *im_info, MPlist *plist)
1237 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1239 M17N_OBJECT (state, free_state, MERROR_IM);
1240 state->name = MPLIST_SYMBOL (plist);
1241 plist = MPLIST_NEXT (plist);
1242 if (MPLIST_MTEXT_P (plist))
1244 state->title = MPLIST_MTEXT (plist);
1245 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1246 Mlanguage, im_info->language);
1247 M17N_OBJECT_REF (state->title);
1248 plist = MPLIST_NEXT (plist);
1250 MSTRUCT_CALLOC (state->map, MERROR_IM);
1251 MPLIST_DO (plist, plist)
1253 if (MFAILP (MPLIST_PLIST_P (plist)))
1255 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1260 /* Return a newly created IM_INFO for an input method specified by
1261 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1263 static MInputMethodInfo *
1264 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1267 MInputMethodInfo *im_info;
1270 if (name == Mnil && extra == Mnil)
1271 language = Mt, extra = Mglobal;
1272 MSTRUCT_CALLOC (im_info, MERROR_IM);
1274 im_info->language = language;
1275 im_info->name = name;
1276 im_info->extra = extra;
1279 mplist_add (plist, Mplist, elt);
1280 M17N_OBJECT_UNREF (elt);
1281 elt = mplist_add (elt, Msymbol, language);
1282 elt = mplist_add (elt, Msymbol, name);
1283 elt = mplist_add (elt, Msymbol, extra);
1284 mplist_add (elt, Mt, im_info);
1290 fini_im_info (MInputMethodInfo *im_info)
1294 M17N_OBJECT_UNREF (im_info->cmds);
1295 M17N_OBJECT_UNREF (im_info->configured_cmds);
1296 M17N_OBJECT_UNREF (im_info->bc_cmds);
1297 M17N_OBJECT_UNREF (im_info->vars);
1298 M17N_OBJECT_UNREF (im_info->configured_vars);
1299 M17N_OBJECT_UNREF (im_info->bc_vars);
1300 M17N_OBJECT_UNREF (im_info->description);
1301 M17N_OBJECT_UNREF (im_info->title);
1302 if (im_info->states)
1304 MPLIST_DO (plist, im_info->states)
1306 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1308 M17N_OBJECT_UNREF (state);
1310 M17N_OBJECT_UNREF (im_info->states);
1313 if (im_info->macros)
1315 MPLIST_DO (plist, im_info->macros)
1316 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1317 M17N_OBJECT_UNREF (im_info->macros);
1320 if (im_info->externals)
1322 MPLIST_DO (plist, im_info->externals)
1324 MIMExternalModule *external = MPLIST_VAL (plist);
1326 dlclose (external->handle);
1327 M17N_OBJECT_UNREF (external->func_list);
1329 MPLIST_KEY (plist) = Mt;
1331 M17N_OBJECT_UNREF (im_info->externals);
1335 MPLIST_DO (plist, im_info->maps)
1337 MPlist *p = MPLIST_PLIST (plist);
1339 M17N_OBJECT_UNREF (p);
1341 M17N_OBJECT_UNREF (im_info->maps);
1348 free_im_info (MInputMethodInfo *im_info)
1350 fini_im_info (im_info);
1355 free_im_list (MPlist *plist)
1359 MPLIST_DO (pl, plist)
1361 MInputMethodInfo *im_info;
1363 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1364 im_info = MPLIST_VAL (elt);
1365 free_im_info (im_info);
1367 M17N_OBJECT_UNREF (plist);
1370 static MInputMethodInfo *
1371 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1373 if (name == Mnil && extra == Mnil)
1374 language = Mt, extra = Mglobal;
1375 while ((plist = mplist__assq (plist, language)))
1377 MPlist *elt = MPLIST_PLIST (plist);
1379 plist = MPLIST_NEXT (plist);
1380 elt = MPLIST_NEXT (elt);
1381 if (MPLIST_SYMBOL (elt) != name)
1383 elt = MPLIST_NEXT (elt);
1384 if (MPLIST_SYMBOL (elt) != extra)
1386 elt = MPLIST_NEXT (elt);
1387 return MPLIST_VAL (elt);
1392 static void load_im_info (MPlist *, MInputMethodInfo *);
1394 #define get_custom_info(im_info) \
1396 ? lookup_im_info (im_custom_list, (im_info)->language, \
1397 (im_info)->name, (im_info)->extra) \
1400 #define get_config_info(im_info) \
1402 ? lookup_im_info (im_config_list, (im_info)->language, \
1403 (im_info)->name, (im_info)->extra) \
1407 update_custom_info (void)
1413 if (mdatabase__check (im_custom_mdb) > 0)
1418 MDatabaseInfo *custom_dir_info;
1419 char custom_path[PATH_MAX + 1];
1421 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1422 if (! custom_dir_info->filename
1423 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1425 strcpy (custom_path, custom_dir_info->filename);
1426 strcat (custom_path, CUSTOM_FILE);
1427 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1433 free_im_list (im_custom_list);
1434 im_custom_list = NULL;
1436 plist = mdatabase_load (im_custom_mdb);
1439 im_custom_list = mplist ();
1441 MPLIST_DO (pl, plist)
1443 MSymbol language, name, extra;
1444 MInputMethodInfo *im_info;
1445 MPlist *im_data, *p;
1447 if (! MPLIST_PLIST_P (pl))
1449 p = MPLIST_PLIST (pl);
1450 im_data = MPLIST_NEXT (p);
1451 if (! MPLIST_PLIST_P (p))
1453 p = MPLIST_PLIST (p);
1454 if (! MPLIST_SYMBOL_P (p)
1455 || MPLIST_SYMBOL (p) != Minput_method)
1457 p = MPLIST_NEXT (p);
1458 if (! MPLIST_SYMBOL_P (p))
1460 language = MPLIST_SYMBOL (p);
1461 p = MPLIST_NEXT (p);
1462 if (! MPLIST_SYMBOL_P (p))
1464 name = MPLIST_SYMBOL (p);
1465 p = MPLIST_NEXT (p);
1466 if (MPLIST_TAIL_P (p))
1468 else if (MPLIST_SYMBOL_P (p))
1469 extra = MPLIST_SYMBOL (p);
1470 if (language == Mnil || (name == Mnil && extra == Mnil))
1472 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1473 load_im_info (im_data, im_info);
1475 M17N_OBJECT_UNREF (plist);
1480 update_global_info (void)
1486 int ret = mdatabase__check (global_info->mdb);
1490 fini_im_info (global_info);
1494 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1498 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1500 if (! global_info->mdb
1501 || ! (plist = mdatabase_load (global_info->mdb)))
1504 load_im_info (plist, global_info);
1505 M17N_OBJECT_UNREF (plist);
1510 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1511 and EXTRA. KEY, if not Mnil, tells which kind of information about
1512 the input method is necessary, and the returned IM_INFO may contain
1513 only that information. */
1515 static MInputMethodInfo *
1516 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1519 MInputMethodInfo *im_info;
1522 if (name == Mnil && extra == Mnil)
1523 language = Mt, extra = Mglobal;
1524 im_info = lookup_im_info (im_info_list, language, name, extra);
1527 if (key == Mnil ? im_info->states != NULL
1528 : key == Mcommand ? im_info->cmds != NULL
1529 : key == Mvariable ? im_info->vars != NULL
1530 : key == Mtitle ? im_info->title != NULL
1531 : key == Mdescription ? im_info->description != NULL
1533 /* IM_INFO already contains required information. */
1535 /* We have not yet loaded required information. */
1539 mdb = mdatabase_find (Minput_method, language, name, extra);
1542 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1547 plist = mdatabase_load (im_info->mdb);
1551 mplist_push (load_im_info_keys, key, Mt);
1552 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1553 mplist_pop (load_im_info_keys);
1557 MERROR (MERROR_IM, im_info);
1558 update_global_info ();
1559 load_im_info (plist, im_info);
1560 M17N_OBJECT_UNREF (plist);
1563 if (! im_info->cmds)
1564 im_info->cmds = mplist ();
1565 if (! im_info->vars)
1566 im_info->vars = mplist ();
1568 if (! im_info->title
1569 && (key == Mnil || key == Mtitle))
1570 im_info->title = (name == Mnil ? mtext ()
1571 : mtext_from_data (MSYMBOL_NAME (name),
1572 MSYMBOL_NAMELEN (name),
1573 MTEXT_FORMAT_US_ASCII));
1577 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1578 If updated, but got unloadable, return -1. Otherwise, update
1579 contents of IM_INFO from the new database, and return 1. */
1582 reload_im_info (MInputMethodInfo *im_info)
1587 update_custom_info ();
1588 update_global_info ();
1589 check = mdatabase__check (im_info->mdb);
1592 plist = mdatabase_load (im_info->mdb);
1595 fini_im_info (im_info);
1596 load_im_info (plist, im_info);
1597 M17N_OBJECT_UNREF (plist);
1598 if (! im_info->cmds)
1599 im_info->cmds = mplist ();
1600 if (! im_info->vars)
1601 im_info->vars = mplist ();
1602 if (! im_info->title)
1604 MSymbol name = im_info->name;
1606 im_info->title = (name == Mnil ? mtext ()
1607 : mtext_from_data (MSYMBOL_NAME (name),
1608 MSYMBOL_NAMELEN (name),
1609 MTEXT_FORMAT_US_ASCII));
1614 static MInputMethodInfo *
1615 get_im_info_by_tags (MPlist *plist)
1620 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1621 i++, plist = MPLIST_NEXT (plist))
1622 tag[i] = MPLIST_SYMBOL (plist);
1627 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1632 check_description (MPlist *plist)
1636 if (MPLIST_MTEXT_P (plist))
1638 if (MPLIST_PLIST_P (plist))
1640 MPlist *pl = MPLIST_PLIST (plist);
1642 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1644 pl =MPLIST_NEXT (pl);
1645 if (MFAILP (MPLIST_MTEXT_P (pl)))
1647 mt = MPLIST_MTEXT (pl);
1648 M17N_OBJECT_REF (mt);
1651 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1653 if (translated == (char *) MTEXT_DATA (mt))
1654 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1655 if (translated != (char *) MTEXT_DATA (mt))
1657 M17N_OBJECT_UNREF (mt);
1658 mt = mtext__from_data (translated, strlen (translated),
1659 MTEXT_FORMAT_UTF_8, 1);
1663 mplist_set (plist, Mtext, mt);
1664 M17N_OBJECT_UNREF (mt);
1667 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1673 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1677 check_command_keyseq (MPlist *keyseq)
1679 if (MPLIST_PLIST_P (keyseq))
1681 MPlist *p = MPLIST_PLIST (keyseq);
1684 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1688 if (MPLIST_MTEXT_P (keyseq))
1690 MText *mt = MPLIST_MTEXT (keyseq);
1693 for (i = 0; i < mtext_nchars (mt); i++)
1694 if (mtext_ref_char (mt, i) >= 256)
1701 /* Load command defitions from PLIST into IM_INFO->cmds.
1703 PLIST is well-formed and has this form;
1704 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1705 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1706 M-text or a plist of symbols.
1708 The returned list has the same form, but for each element...
1710 (1) If DESCRIPTION and the rest are omitted, the element is not
1711 stored in the returned list.
1713 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1714 description in global_info->cmds (if any). */
1717 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1721 im_info->cmds = tail = mplist ();
1723 MPLIST_DO (plist, MPLIST_NEXT (plist))
1725 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1728 if (MFAILP (MPLIST_PLIST_P (plist)))
1730 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1731 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1733 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1734 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1736 if (MFAILP (im_info != global_info))
1737 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1741 if (! check_description (p))
1742 mplist_set (p, Msymbol, Mnil);
1743 p = MPLIST_NEXT (p);
1744 while (! MPLIST_TAIL_P (p))
1746 if (MFAILP (check_command_keyseq (p)))
1747 mplist__pop_unref (p);
1749 p = MPLIST_NEXT (p);
1752 tail = mplist_add (tail, Mplist, pl);
1757 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1758 MPlist *config_cmds)
1760 MPlist *global = NULL, *custom = NULL, *config = NULL;
1761 MSymbol name = MPLIST_SYMBOL (plist);
1763 MPlist *description, *keyseq;
1765 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1766 global = MPLIST_NEXT (MPLIST_PLIST (global));
1768 plist = MPLIST_NEXT (plist);
1769 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1771 description = plist;
1772 plist = MPLIST_NEXT (plist);
1776 description = global;
1777 if (! MPLIST_TAIL_P (plist))
1778 plist = MPLIST_NEXT (plist);
1780 if (MPLIST_TAIL_P (plist) && global)
1782 keyseq = MPLIST_NEXT (global);
1783 status = Minherited;
1791 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1793 status = Mconfigured;
1794 config = MPLIST_NEXT (MPLIST_PLIST (config));
1795 if (! MPLIST_TAIL_P (config))
1798 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1800 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1802 if (MPLIST_TAIL_P (this_keyseq))
1803 mplist__pop_unref (custom);
1806 status = Mcustomized;
1807 keyseq = this_keyseq;
1812 mplist_add (plist, Msymbol, name);
1814 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1816 mplist_add (plist, Msymbol, Mnil);
1817 mplist_add (plist, Msymbol, status);
1818 mplist__conc (plist, keyseq);
1823 config_all_commands (MInputMethodInfo *im_info)
1825 MPlist *global_cmds, *custom_cmds, *config_cmds;
1826 MInputMethodInfo *temp;
1827 MPlist *tail, *plist;
1829 M17N_OBJECT_UNREF (im_info->configured_cmds);
1831 if (MPLIST_TAIL_P (im_info->cmds)
1835 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1836 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1837 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1839 im_info->configured_cmds = tail = mplist ();
1840 MPLIST_DO (plist, im_info->cmds)
1842 MPlist *pl = config_command (MPLIST_PLIST (plist),
1843 global_cmds, custom_cmds, config_cmds);
1846 tail = mplist_add (tail, Mplist, pl);
1847 M17N_OBJECT_UNREF (pl);
1852 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1853 valid, return 0 if not. */
1856 check_variable_value (MPlist *val, MPlist *global)
1858 MSymbol type = MPLIST_KEY (val);
1859 MPlist *valids = MPLIST_NEXT (val);
1861 if (type != Minteger && type != Mtext && type != Msymbol)
1865 if (MPLIST_KEY (global) != Mt
1866 && MPLIST_KEY (global) != MPLIST_KEY (val))
1868 if (MPLIST_TAIL_P (valids))
1869 valids = MPLIST_NEXT (global);
1871 if (MPLIST_TAIL_P (valids))
1874 if (type == Minteger)
1876 int n = MPLIST_INTEGER (val);
1878 MPLIST_DO (valids, valids)
1880 if (MPLIST_INTEGER_P (valids))
1882 if (n == MPLIST_INTEGER (valids))
1885 else if (MPLIST_PLIST_P (valids))
1887 MPlist *p = MPLIST_PLIST (valids);
1888 int min_bound, max_bound;
1890 if (! MPLIST_INTEGER_P (p))
1891 MERROR (MERROR_IM, 0);
1892 min_bound = MPLIST_INTEGER (p);
1893 p = MPLIST_NEXT (p);
1894 if (! MPLIST_INTEGER_P (p))
1895 MERROR (MERROR_IM, 0);
1896 max_bound = MPLIST_INTEGER (p);
1897 if (n >= min_bound && n <= max_bound)
1902 else if (type == Msymbol)
1904 MSymbol sym = MPLIST_SYMBOL (val);
1906 MPLIST_DO (valids, valids)
1908 if (! MPLIST_SYMBOL_P (valids))
1909 MERROR (MERROR_IM, 0);
1910 if (sym == MPLIST_SYMBOL (valids))
1916 MText *mt = MPLIST_MTEXT (val);
1918 MPLIST_DO (valids, valids)
1920 if (! MPLIST_MTEXT_P (valids))
1921 MERROR (MERROR_IM, 0);
1922 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1927 return (! MPLIST_TAIL_P (valids));
1930 /* Load variable defitions from PLIST into IM_INFO->vars.
1932 PLIST is well-formed and has this form;
1933 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1935 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1937 The returned list has the same form, but for each element...
1939 (1) If DESCRIPTION and the rest are omitted, the element is not
1940 stored in the returned list.
1942 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1943 description in global_info->vars (if any). */
1946 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1948 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1949 ? global_info->vars : NULL);
1952 im_info->vars = tail = mplist ();
1953 MPLIST_DO (plist, MPLIST_NEXT (plist))
1957 if (MFAILP (MPLIST_PLIST_P (plist)))
1959 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1960 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1962 if (im_info == global_info)
1964 /* Loading a global variable. */
1965 p = MPLIST_NEXT (pl);
1966 if (MPLIST_TAIL_P (p))
1967 mplist_add (p, Msymbol, Mnil);
1970 if (! check_description (p))
1971 mplist_set (p, Msymbol, Mnil);
1972 p = MPLIST_NEXT (p);
1973 if (MFAILP (! MPLIST_TAIL_P (p)
1974 && check_variable_value (p, NULL)))
1975 mplist_set (p, Mt, NULL);
1978 else if (im_info->mdb)
1980 /* Loading a local variable. */
1981 MSymbol name = MPLIST_SYMBOL (pl);
1982 MPlist *global = NULL;
1985 && (p = mplist__assq (global_vars, name)))
1987 /* P ::= ((NAME DESC ...) ...) */
1988 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1989 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1990 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1993 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1994 if (! MPLIST_TAIL_P (p))
1996 if (! check_description (p))
1997 mplist_set (p, Msymbol, Mnil);
1998 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1999 if (MFAILP (! MPLIST_TAIL_P (p)))
2000 mplist_set (p, Mt, NULL);
2003 MPlist *valid_values = MPLIST_NEXT (p);
2005 if (! MPLIST_TAIL_P (valid_values)
2006 ? MFAILP (check_variable_value (p, NULL))
2007 : global && MFAILP (check_variable_value (p, global)))
2008 mplist_set (p, Mt, NULL);
2014 /* Loading a variable customization. */
2015 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2016 if (MFAILP (! MPLIST_TAIL_P (p)))
2018 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2019 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2020 || MPLIST_MTEXT_P (p)))
2023 tail = mplist_add (tail, Mplist, pl);
2028 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2029 MPlist *config_vars)
2031 MPlist *global = NULL, *custom = NULL, *config = NULL;
2032 MSymbol name = MPLIST_SYMBOL (plist);
2034 MPlist *description = NULL, *value, *valids;
2038 global = mplist__assq (global_vars, name);
2040 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2043 plist = MPLIST_NEXT (plist);
2044 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2045 description = plist;
2047 description = global;
2049 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2051 if (MPLIST_TAIL_P (plist))
2053 /* Inherit from global (if any). */
2057 if (MPLIST_KEY (value) == Mt)
2059 valids = MPLIST_NEXT (global);
2060 status = Minherited;
2072 value = plist = MPLIST_NEXT (plist);
2073 valids = MPLIST_NEXT (value);
2074 if (MPLIST_KEY (value) == Mt)
2076 if (! MPLIST_TAIL_P (valids))
2079 valids = MPLIST_NEXT (global);
2083 if (config_vars && (config = mplist__assq (config_vars, name)))
2085 status = Mconfigured;
2086 config = MPLIST_NEXT (MPLIST_PLIST (config));
2087 if (! MPLIST_TAIL_P (config))
2090 if (MFAILP (check_variable_value (value, global ? global : plist)))
2094 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2096 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2098 if (MPLIST_TAIL_P (this_value))
2099 mplist__pop_unref (custom);
2103 if (MFAILP (check_variable_value (value, global ? global : plist)))
2105 status = Mcustomized;
2110 mplist_add (plist, Msymbol, name);
2112 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2114 mplist_add (plist, Msymbol, Mnil);
2115 mplist_add (plist, Msymbol, status);
2117 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2119 mplist_add (plist, Mt, NULL);
2120 if (valids && ! MPLIST_TAIL_P (valids))
2121 mplist__conc (plist, valids);
2125 /* Return a configured variable definition list based on
2126 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2127 get it from global_info->vars. */
2130 config_all_variables (MInputMethodInfo *im_info)
2132 MPlist *global_vars, *custom_vars, *config_vars;
2133 MInputMethodInfo *temp;
2134 MPlist *tail, *plist;
2136 M17N_OBJECT_UNREF (im_info->configured_vars);
2138 if (MPLIST_TAIL_P (im_info->vars)
2142 global_vars = im_info != global_info ? global_info->vars : NULL;
2143 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2144 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2146 im_info->configured_vars = tail = mplist ();
2147 MPLIST_DO (plist, im_info->vars)
2149 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2150 global_vars, custom_vars, config_vars);
2153 tail = mplist_add (tail, Mplist, pl);
2154 M17N_OBJECT_UNREF (pl);
2159 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2160 CONFIG contains configuration information of the input method. */
2163 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2167 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2169 load_commands (im_info, MPLIST_PLIST (pl));
2170 config_all_commands (im_info);
2171 pl = mplist_pop (pl);
2172 M17N_OBJECT_UNREF (pl);
2175 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2177 load_variables (im_info, MPLIST_PLIST (pl));
2178 config_all_variables (im_info);
2179 pl = mplist_pop (pl);
2180 M17N_OBJECT_UNREF (pl);
2183 MPLIST_DO (plist, plist)
2184 if (MPLIST_PLIST_P (plist))
2186 MPlist *elt = MPLIST_PLIST (plist);
2189 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2191 key = MPLIST_SYMBOL (elt);
2196 elt = MPLIST_NEXT (elt);
2197 if (MFAILP (MPLIST_MTEXT_P (elt)))
2199 im_info->title = MPLIST_MTEXT (elt);
2200 M17N_OBJECT_REF (im_info->title);
2202 else if (key == Mmap)
2204 pl = mplist__from_alist (MPLIST_NEXT (elt));
2207 if (! im_info->maps)
2211 mplist__conc (im_info->maps, pl);
2212 M17N_OBJECT_UNREF (pl);
2215 else if (key == Mmacro)
2217 if (! im_info->macros)
2218 im_info->macros = mplist ();
2219 MPLIST_DO (elt, MPLIST_NEXT (elt))
2221 if (MFAILP (MPLIST_PLIST_P (elt)))
2223 load_macros (im_info, MPLIST_PLIST (elt));
2226 else if (key == Mmodule)
2228 if (! im_info->externals)
2229 im_info->externals = mplist ();
2230 MPLIST_DO (elt, MPLIST_NEXT (elt))
2232 if (MFAILP (MPLIST_PLIST_P (elt)))
2234 load_external_module (im_info, MPLIST_PLIST (elt));
2237 else if (key == Mstate)
2239 MPLIST_DO (elt, MPLIST_NEXT (elt))
2243 if (MFAILP (MPLIST_PLIST_P (elt)))
2245 pl = MPLIST_PLIST (elt);
2246 if (! im_info->states)
2247 im_info->states = mplist ();
2248 state = load_state (im_info, MPLIST_PLIST (elt));
2251 mplist_put (im_info->states, state->name, state);
2254 else if (key == Minclude)
2256 /* elt ::= include (tag1 tag2 ...) key item ... */
2258 MInputMethodInfo *temp;
2260 elt = MPLIST_NEXT (elt);
2261 if (MFAILP (MPLIST_PLIST_P (elt)))
2263 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2266 elt = MPLIST_NEXT (elt);
2267 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2269 key = MPLIST_SYMBOL (elt);
2270 elt = MPLIST_NEXT (elt);
2273 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2275 if (! im_info->maps)
2276 im_info->maps = mplist ();
2277 MPLIST_DO (pl, temp->maps)
2279 p = MPLIST_VAL (pl);
2280 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2281 M17N_OBJECT_REF (p);
2284 else if (key == Mmacro)
2286 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2288 if (! im_info->macros)
2289 im_info->macros = mplist ();
2290 MPLIST_DO (pl, temp->macros)
2292 p = MPLIST_VAL (pl);
2293 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2294 M17N_OBJECT_REF (p);
2297 else if (key == Mstate)
2299 if (! temp->states || MPLIST_TAIL_P (temp->states))
2301 if (! im_info->states)
2302 im_info->states = mplist ();
2303 MPLIST_DO (pl, temp->states)
2305 MIMState *state = MPLIST_VAL (pl);
2307 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2308 M17N_OBJECT_REF (state);
2312 else if (key == Mdescription)
2314 if (im_info->description)
2316 elt = MPLIST_NEXT (elt);
2317 if (! check_description (elt))
2319 im_info->description = MPLIST_MTEXT (elt);
2320 M17N_OBJECT_REF (im_info->description);
2323 im_info->tick = time (NULL);
2328 static int take_action_list (MInputContext *ic, MPlist *action_list);
2329 static void preedit_commit (MInputContext *ic, int need_prefix);
2332 shift_state (MInputContext *ic, MSymbol state_name)
2334 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2335 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2336 MIMState *orig_state = ic_info->state, *state;
2338 /* Find a state to shift to. If not found, shift to the initial
2340 if (state_name == Mt)
2342 if (! ic_info->prev_state)
2344 state = ic_info->prev_state;
2346 else if (state_name == Mnil)
2348 state = (MIMState *) MPLIST_VAL (im_info->states);
2352 state = (MIMState *) mplist_get (im_info->states, state_name);
2354 state = (MIMState *) MPLIST_VAL (im_info->states);
2360 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2361 MSYMBOL_NAME (orig_state->name),
2362 MSYMBOL_NAME (state->name));
2364 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2367 /* Enter the new state. */
2368 ic_info->state = state;
2369 ic_info->map = state->map;
2370 ic_info->state_key_head = ic_info->key_head;
2371 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2373 /* We have shifted to the initial state. */
2374 preedit_commit (ic, 0);
2375 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2376 ic_info->state_pos = ic->cursor_pos;
2377 if (state != orig_state)
2379 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2381 /* Shifted to the initial state. */
2382 ic_info->prev_state = NULL;
2383 M17N_OBJECT_UNREF (ic_info->vars_saved);
2384 ic_info->vars_saved = mplist_copy (ic_info->vars);
2387 ic_info->prev_state = orig_state;
2390 ic->status = state->title;
2392 ic->status = im_info->title;
2393 ic->status_changed = 1;
2394 if (ic_info->map == ic_info->state->map
2395 && ic_info->map->map_actions)
2397 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2398 MSYMBOL_NAME (state->name));
2399 take_action_list (ic, ic_info->map->map_actions);
2404 /* Find a candidate group that contains a candidate number INDEX from
2405 PLIST. Set START_INDEX to the first candidate number of the group,
2406 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2407 candidate group number if they are non-NULL. If INDEX is -1, find
2408 the last candidate group. */
2411 find_candidates_group (MPlist *plist, int index,
2412 int *start_index, int *end_index, int *group_index)
2414 int i = 0, gidx = 0, len;
2416 MPLIST_DO (plist, plist)
2418 if (MPLIST_MTEXT_P (plist))
2419 len = mtext_nchars (MPLIST_MTEXT (plist));
2421 len = mplist_length (MPLIST_PLIST (plist));
2422 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2428 *end_index = i + len;
2430 *group_index = gidx;
2439 /* Adjust markers for the change of preedit text.
2440 If FROM == TO, the change is insertion of INS chars.
2441 If FROM < TO and INS == 0, the change is deletion of the range.
2442 If FROM < TO and INS > 0, the change is replacement. */
2445 adjust_markers (MInputContext *ic, int from, int to, int ins)
2447 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2452 MPLIST_DO (markers, ic_info->markers)
2453 if (MPLIST_INTEGER (markers) > from)
2454 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2455 if (ic->cursor_pos >= from)
2456 ic->cursor_pos += ins;
2460 MPLIST_DO (markers, ic_info->markers)
2462 if (MPLIST_INTEGER (markers) >= to)
2463 MPLIST_VAL (markers)
2464 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2465 else if (MPLIST_INTEGER (markers) > from)
2466 MPLIST_VAL (markers) = (void *) from;
2468 if (ic->cursor_pos >= to)
2469 ic->cursor_pos += ins - (to - from);
2470 else if (ic->cursor_pos > from)
2471 ic->cursor_pos = from;
2477 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2479 int nchars = mt ? mtext_nchars (mt) : 1;
2483 mtext_ins (ic->preedit, pos, mt);
2484 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2488 mtext_ins_char (ic->preedit, pos, c, 1);
2489 MDEBUG_PRINT1 ("('%c')", c);
2491 adjust_markers (ic, pos, pos, nchars);
2492 ic->preedit_changed = 1;
2497 preedit_delete (MInputContext *ic, int from, int to)
2499 mtext_del (ic->preedit, from, to);
2500 adjust_markers (ic, from, to, 0);
2501 ic->preedit_changed = 1;
2505 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2509 mtext_del (ic->preedit, from, to);
2512 mtext_ins (ic->preedit, from, mt);
2513 ins = mtext_nchars (mt);
2517 mtext_ins_char (ic->preedit, from, c, 1);
2520 adjust_markers (ic, from, to, ins);
2521 ic->preedit_changed = 1;
2526 preedit_commit (MInputContext *ic, int need_prefix)
2528 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2529 int preedit_len = mtext_nchars (ic->preedit);
2531 if (preedit_len > 0)
2535 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2536 Mcandidate_list, NULL, 0);
2537 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2538 Mcandidate_index, NULL, 0);
2539 mtext_cat (ic->produced, ic->preedit);
2545 MDEBUG_PRINT1 ("\n [IM] [%s]",
2546 MSYMBOL_NAME (ic_info->state->name));
2547 MDEBUG_PRINT (" (commit");
2548 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2549 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2553 mtext_reset (ic->preedit);
2554 mtext_reset (ic_info->preedit_saved);
2555 MPLIST_DO (p, ic_info->markers)
2557 ic->cursor_pos = ic_info->state_pos = 0;
2558 ic->preedit_changed = 1;
2559 ic_info->commit_key_head = ic_info->key_head;
2561 if (ic->candidate_list)
2563 M17N_OBJECT_UNREF (ic->candidate_list);
2564 ic->candidate_list = NULL;
2565 ic->candidate_index = 0;
2566 ic->candidate_from = ic->candidate_to = 0;
2567 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2568 if (ic->candidate_show)
2570 ic->candidate_show = 0;
2571 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2577 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2579 int code = marker_code (sym, 0);
2581 if (mt && (code == '[' || code == ']'))
2585 if (code == '[' && current > 0)
2587 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2591 else if (code == ']' && current < mtext_nchars (mt))
2593 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2599 return (code == '<' ? 0
2600 : code == '>' ? limit
2601 : code == '-' ? current - 1
2602 : code == '+' ? current + 1
2603 : code == '=' ? current
2604 : code - '0' > limit ? limit
2608 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2612 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2614 int from = mtext_property_start (prop);
2615 int to = mtext_property_end (prop);
2617 MPlist *candidate_list = mtext_property_value (prop);
2618 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2620 int ingroup_index = idx - start;
2623 candidate_list = mplist_copy (candidate_list);
2624 if (MPLIST_MTEXT_P (group))
2626 mt = MPLIST_MTEXT (group);
2627 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2635 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2636 i++, plist = MPLIST_NEXT (plist));
2637 mt = MPLIST_MTEXT (plist);
2638 preedit_replace (ic, from, to, mt, 0);
2639 to = from + mtext_nchars (mt);
2641 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2642 M17N_OBJECT_UNREF (candidate_list);
2643 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2644 ic->cursor_pos = to;
2648 get_select_charset (MInputContextInfo * ic_info)
2650 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2653 if (! MPLIST_VAL (plist))
2655 sym = MPLIST_SYMBOL (plist);
2658 return MCHARSET (sym);
2662 adjust_candidates (MPlist *plist, MCharset *charset)
2666 /* plist ::= MTEXT ... | PLIST ... */
2667 plist = mplist_copy (plist);
2668 if (MPLIST_MTEXT_P (plist))
2671 while (! MPLIST_TAIL_P (pl))
2673 /* pl ::= MTEXT ... */
2674 MText *mt = MPLIST_MTEXT (pl);
2678 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2680 c = mtext_ref_char (mt, i);
2681 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2685 mt = mtext_dup (mt);
2686 mplist_set (pl, Mtext, mt);
2687 M17N_OBJECT_UNREF (mt);
2690 mtext_del (mt, i, i + 1);
2693 if (mtext_len (mt) > 0)
2694 pl = MPLIST_NEXT (pl);
2698 M17N_OBJECT_UNREF (mt);
2702 else /* MPLIST_PLIST_P (plist) */
2705 while (! MPLIST_TAIL_P (pl))
2707 /* pl ::= (MTEXT ...) ... */
2708 MPlist *p = MPLIST_PLIST (pl);
2710 /* p ::= MTEXT ... */
2714 while (! MPLIST_TAIL_P (p0))
2716 MText *mt = MPLIST_MTEXT (p0);
2719 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2721 c = mtext_ref_char (mt, i);
2722 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2727 p0 = MPLIST_NEXT (p0);
2734 p = mplist_copy (p);
2735 mplist_set (pl, Mplist, p);
2736 M17N_OBJECT_UNREF (p);
2740 p0 = MPLIST_NEXT (p0);
2743 M17N_OBJECT_UNREF (mt);
2746 if (! MPLIST_TAIL_P (p))
2747 pl = MPLIST_NEXT (pl);
2751 M17N_OBJECT_UNREF (p);
2755 if (MPLIST_TAIL_P (plist))
2757 M17N_OBJECT_UNREF (plist);
2764 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2766 MCharset *charset = get_select_charset (ic_info);
2771 plist = resolve_variable (ic_info, Mcandidates_group_size);
2772 column = MPLIST_INTEGER (plist);
2774 plist = MPLIST_PLIST (args);
2776 plist = adjust_candidates (plist, charset);
2778 if (plist && column > 0)
2780 if (MPLIST_MTEXT_P (plist))
2782 MText *mt = MPLIST_MTEXT (plist);
2783 MPlist *next = MPLIST_NEXT (plist);
2785 if (MPLIST_TAIL_P (next))
2786 M17N_OBJECT_REF (mt);
2789 mt = mtext_dup (mt);
2790 while (! MPLIST_TAIL_P (next))
2792 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2793 next = MPLIST_NEXT (next);
2797 M17N_OBJECT_UNREF (plist);
2799 len = mtext_nchars (mt);
2801 mplist_add (plist, Mtext, mt);
2804 for (i = 0; i < len; i += column)
2806 int to = (i + column < len ? i + column : len);
2807 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2809 mplist_add (plist, Mtext, sub);
2810 M17N_OBJECT_UNREF (sub);
2813 M17N_OBJECT_UNREF (mt);
2815 else if (! MPLIST_TAIL_P (plist))
2817 MPlist *tail = plist;
2818 MPlist *new = mplist ();
2819 MPlist *this = mplist ();
2822 MPLIST_DO (tail, tail)
2824 MPlist *p = MPLIST_PLIST (tail);
2828 MText *mt = MPLIST_MTEXT (p);
2830 if (count == column)
2832 mplist_add (new, Mplist, this);
2833 M17N_OBJECT_UNREF (this);
2837 mplist_add (this, Mtext, mt);
2841 mplist_add (new, Mplist, this);
2842 M17N_OBJECT_UNREF (this);
2843 mplist_set (plist, Mnil, NULL);
2844 MPLIST_DO (tail, new)
2846 MPlist *elt = MPLIST_PLIST (tail);
2848 mplist_add (plist, Mplist, elt);
2850 M17N_OBJECT_UNREF (new);
2859 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2861 MPlist *action = NULL;
2865 if (MPLIST_SYMBOL_P (action_list))
2867 MSymbol var = MPLIST_SYMBOL (action_list);
2870 MPLIST_DO (p, ic_info->vars)
2871 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2873 if (MPLIST_TAIL_P (p))
2875 action = MPLIST_NEXT (MPLIST_PLIST (p));
2876 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2879 if (MPLIST_PLIST_P (action_list))
2881 action = MPLIST_PLIST (action_list);
2882 if (MPLIST_SYMBOL_P (action))
2884 name = MPLIST_SYMBOL (action);
2885 args = MPLIST_NEXT (action);
2887 && MPLIST_PLIST_P (args))
2888 mplist_set (action, Msymbol, M_candidates);
2890 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2893 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2894 mplist_push (action, Msymbol, M_candidates);
2895 mplist_set (action_list, Mplist, action);
2896 M17N_OBJECT_UNREF (action);
2899 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2902 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2903 mplist_push (action, Msymbol, Minsert);
2904 mplist_set (action_list, Mplist, action);
2905 M17N_OBJECT_UNREF (action);
2910 /* Perform list of actions in ACTION_LIST for the current input
2911 context IC. If unhandle action was not performed, return 0.
2912 Otherwise, return -1. */
2915 take_action_list (MInputContext *ic, MPlist *action_list)
2917 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2918 MPlist *candidate_list = ic->candidate_list;
2919 int candidate_index = ic->candidate_index;
2920 int candidate_show = ic->candidate_show;
2921 MTextProperty *prop;
2923 MPLIST_DO (action_list, action_list)
2925 MPlist *action = regularize_action (action_list, ic_info);
2931 name = MPLIST_SYMBOL (action);
2932 args = MPLIST_NEXT (action);
2934 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2935 if (name == Minsert)
2937 if (MPLIST_SYMBOL_P (args))
2939 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2940 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2943 if (MPLIST_MTEXT_P (args))
2944 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2945 else /* MPLIST_INTEGER_P (args)) */
2946 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2948 else if (name == M_candidates)
2950 MPlist *plist = get_candidate_list (ic_info, args);
2953 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2955 if (MPLIST_MTEXT_P (plist))
2957 preedit_insert (ic, ic->cursor_pos, NULL,
2958 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2961 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2965 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2967 preedit_insert (ic, ic->cursor_pos, mt, 0);
2968 len = mtext_nchars (mt);
2970 plist = mplist_copy (plist);
2971 mtext_put_prop (ic->preedit,
2972 ic->cursor_pos - len, ic->cursor_pos,
2973 Mcandidate_list, plist);
2974 M17N_OBJECT_UNREF (plist);
2975 mtext_put_prop (ic->preedit,
2976 ic->cursor_pos - len, ic->cursor_pos,
2977 Mcandidate_index, (void *) 0);
2979 else if (name == Mselect)
2982 int code, idx, gindex;
2983 int pos = ic->cursor_pos;
2985 int idx_decided = 0;
2988 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2991 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2992 group = find_candidates_group (mtext_property_value (prop), idx,
2993 &start, &end, &gindex);
2994 if (MPLIST_SYMBOL_P (args))
2996 code = marker_code (MPLIST_SYMBOL (args), 0);
2999 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3000 if (! MPLIST_INTEGER_P (args))
3002 idx = start + MPLIST_INTEGER (args);
3003 if (idx < start || idx >= end)
3011 if (code != '[' && code != ']')
3016 ? new_index (NULL, ic->candidate_index - start,
3017 end - start - 1, MPLIST_SYMBOL (args),
3019 : MPLIST_INTEGER (args)));
3022 find_candidates_group (mtext_property_value (prop), -1,
3027 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3032 int ingroup_index = idx - start;
3035 group = mtext_property_value (prop);
3036 len = mplist_length (group);
3049 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3050 idx += (MPLIST_MTEXT_P (group)
3051 ? mtext_nchars (MPLIST_MTEXT (group))
3052 : mplist_length (MPLIST_PLIST (group)));
3053 len = (MPLIST_MTEXT_P (group)
3054 ? mtext_nchars (MPLIST_MTEXT (group))
3055 : mplist_length (MPLIST_PLIST (group)));
3056 if (ingroup_index >= len)
3057 ingroup_index = len - 1;
3058 idx += ingroup_index;
3060 update_candidate (ic, prop, idx);
3061 MDEBUG_PRINT1 ("(%d)", idx);
3063 else if (name == Mshow)
3064 ic->candidate_show = 1;
3065 else if (name == Mhide)
3066 ic->candidate_show = 0;
3067 else if (name == Mdelete)
3069 int len = mtext_nchars (ic->preedit);
3073 if (MPLIST_SYMBOL_P (args)
3074 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3076 to = ic->cursor_pos + pos;
3079 delete_surrounding_text (ic, to);
3084 delete_surrounding_text (ic, to - len);
3090 to = (MPLIST_SYMBOL_P (args)
3091 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3093 : MPLIST_INTEGER (args));
3099 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3100 if (to < ic->cursor_pos)
3101 preedit_delete (ic, to, ic->cursor_pos);
3102 else if (to > ic->cursor_pos)
3103 preedit_delete (ic, ic->cursor_pos, to);
3105 else if (name == Mmove)
3107 int len = mtext_nchars (ic->preedit);
3109 = (MPLIST_SYMBOL_P (args)
3110 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3112 : MPLIST_INTEGER (args));
3118 if (pos != ic->cursor_pos)
3120 ic->cursor_pos = pos;
3121 ic->preedit_changed = 1;
3123 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3125 else if (name == Mmark)
3127 int code = marker_code (MPLIST_SYMBOL (args), 0);
3131 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3132 (void *) ic->cursor_pos);
3133 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3136 else if (name == Mpushback)
3138 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3142 if (MPLIST_SYMBOL_P (args))
3144 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3145 if (MPLIST_INTEGER_P (args))
3146 num = MPLIST_INTEGER (args);
3151 num = MPLIST_INTEGER (args);
3154 ic_info->key_head -= num;
3156 ic_info->key_head = 0;
3158 ic_info->key_head = - num;
3159 if (ic_info->key_head > ic_info->used)
3160 ic_info->key_head = ic_info->used;
3162 else if (MPLIST_MTEXT_P (args))
3164 MText *mt = MPLIST_MTEXT (args);
3165 int i, len = mtext_nchars (mt);
3168 ic_info->key_head--;
3169 for (i = 0; i < len; i++)
3171 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3172 if (ic_info->key_head + i < ic_info->used)
3173 ic_info->keys[ic_info->key_head + i] = key;
3175 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3180 MPlist *plist = MPLIST_PLIST (args), *pl;
3184 ic_info->key_head--;
3186 MPLIST_DO (pl, plist)
3188 key = MPLIST_SYMBOL (pl);
3189 if (ic_info->key_head < ic_info->used)
3190 ic_info->keys[ic_info->key_head + i] = key;
3192 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3197 else if (name == Mpop)
3199 if (ic_info->key_head < ic_info->used)
3200 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3202 else if (name == Mcall)
3204 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3205 MIMExternalFunc func = NULL;
3206 MSymbol module, func_name;
3207 MPlist *func_args, *val;
3210 module = MPLIST_SYMBOL (args);
3211 args = MPLIST_NEXT (args);
3212 func_name = MPLIST_SYMBOL (args);
3214 if (im_info->externals)
3216 MIMExternalModule *external
3217 = (MIMExternalModule *) mplist_get (im_info->externals,
3220 func = ((MIMExternalFunc)
3221 mplist_get_func (external->func_list, func_name));
3225 func_args = mplist ();
3226 mplist_add (func_args, Mt, ic);
3227 MPLIST_DO (args, MPLIST_NEXT (args))
3231 if (MPLIST_KEY (args) == Msymbol
3232 && MPLIST_KEY (args) != Mnil
3233 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3235 code = new_index (ic, ic->cursor_pos,
3236 mtext_nchars (ic->preedit),
3237 MPLIST_SYMBOL (args), ic->preedit);
3238 mplist_add (func_args, Minteger, (void *) code);
3241 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3243 val = (func) (func_args);
3244 M17N_OBJECT_UNREF (func_args);
3245 if (val && ! MPLIST_TAIL_P (val))
3246 ret = take_action_list (ic, val);
3247 M17N_OBJECT_UNREF (val);
3251 else if (name == Mshift)
3253 shift_state (ic, MPLIST_SYMBOL (args));
3255 else if (name == Mundo)
3257 int intarg = (MPLIST_TAIL_P (args)
3259 : integer_value (ic, args, NULL, 0));
3261 mtext_reset (ic->preedit);
3262 mtext_reset (ic_info->preedit_saved);
3263 mtext_reset (ic->produced);
3264 M17N_OBJECT_UNREF (ic_info->vars);
3265 ic_info->vars = mplist_copy (ic_info->vars_saved);
3266 ic->cursor_pos = ic_info->state_pos = 0;
3267 ic_info->state_key_head = ic_info->key_head
3268 = ic_info->commit_key_head = 0;
3270 shift_state (ic, Mnil);
3273 if (MPLIST_TAIL_P (args))
3278 ic_info->used += intarg;
3281 ic_info->used = intarg;
3284 else if (name == Mset || name == Madd || name == Msub
3285 || name == Mmul || name == Mdiv)
3287 MSymbol sym = MPLIST_SYMBOL (args);
3292 val1 = integer_value (ic, args, &value, 0);
3293 args = MPLIST_NEXT (args);
3294 val2 = resolve_expression (ic, args);
3296 val1 = val2, op = "=";
3297 else if (name == Madd)
3298 val1 += val2, op = "+=";
3299 else if (name == Msub)
3300 val1 -= val2, op = "-=";
3301 else if (name == Mmul)
3302 val1 *= val2, op = "*=";
3304 val1 /= val2, op = "/=";
3305 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3306 MSYMBOL_NAME (sym), op, val1, val1);
3308 mplist_set (value, Minteger, (void *) val1);
3310 else if (name == Mequal || name == Mless || name == Mgreater
3311 || name == Mless_equal || name == Mgreater_equal)
3314 MPlist *actions1, *actions2;
3317 val1 = resolve_expression (ic, args);
3318 args = MPLIST_NEXT (args);
3319 val2 = resolve_expression (ic, args);
3320 args = MPLIST_NEXT (args);
3321 actions1 = MPLIST_PLIST (args);
3322 args = MPLIST_NEXT (args);
3323 if (MPLIST_TAIL_P (args))
3326 actions2 = MPLIST_PLIST (args);
3327 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3328 if (name == Mequal ? val1 == val2
3329 : name == Mless ? val1 < val2
3330 : name == Mgreater ? val1 > val2
3331 : name == Mless_equal ? val1 <= val2
3334 MDEBUG_PRINT ("ok");
3335 ret = take_action_list (ic, actions1);
3339 MDEBUG_PRINT ("no");
3341 ret = take_action_list (ic, actions2);
3346 else if (name == Mcond)
3350 MPLIST_DO (args, args)
3355 if (! MPLIST_PLIST (args))
3357 cond = MPLIST_PLIST (args);
3358 if (resolve_expression (ic, cond) != 0)
3360 MDEBUG_PRINT1 ("(%dth)", idx);
3361 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3367 else if (name == Mcommit)
3369 preedit_commit (ic, 0);
3371 else if (name == Munhandle)
3373 preedit_commit (ic, 0);
3378 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3382 && (actions = mplist_get (im_info->macros, name)))
3384 if (take_action_list (ic, actions) < 0)
3390 if (ic->candidate_list)
3392 M17N_OBJECT_UNREF (ic->candidate_list);
3393 ic->candidate_list = NULL;
3395 if (ic->cursor_pos > 0
3396 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3399 ic->candidate_list = mtext_property_value (prop);
3400 M17N_OBJECT_REF (ic->candidate_list);
3402 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3404 ic->candidate_from = mtext_property_start (prop);
3405 ic->candidate_to = mtext_property_end (prop);
3408 if (candidate_list != ic->candidate_list)
3409 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3410 if (candidate_index != ic->candidate_index)
3411 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3412 if (candidate_show != ic->candidate_show)
3413 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3418 /* Handle the input key KEY in the current state and map specified in
3419 the input context IC. If KEY is handled correctly, return 0.
3420 Otherwise, return -1. */
3423 handle_key (MInputContext *ic)
3425 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3426 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3427 MIMMap *map = ic_info->map;
3428 MIMMap *submap = NULL;
3429 MSymbol key = ic_info->keys[ic_info->key_head];
3430 MSymbol alias = Mnil;
3433 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3434 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3438 submap = mplist_get (map->submaps, key);
3441 && (alias = msymbol_get (alias, M_key_alias))
3443 submap = mplist_get (map->submaps, alias);
3448 if (! alias || alias == key)
3449 MDEBUG_PRINT (" submap-found");
3451 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3452 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3453 ic->preedit_changed = 1;
3454 ic->cursor_pos = ic_info->state_pos;
3455 ic_info->key_head++;
3456 ic_info->map = map = submap;
3457 if (map->map_actions)
3459 MDEBUG_PRINT (" map-actions:");
3460 if (take_action_list (ic, map->map_actions) < 0)
3462 MDEBUG_PRINT ("\n");
3466 else if (map->submaps)
3468 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3470 MSymbol key = ic_info->keys[i];
3471 char *name = msymbol_name (key);
3473 if (! name[0] || ! name[1])
3474 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3478 /* If this is the terminal map or we have shifted to another
3479 state, perform branch actions (if any). */
3480 if (! map->submaps || map != ic_info->map)
3482 if (map->branch_actions)
3484 MDEBUG_PRINT (" branch-actions:");
3485 if (take_action_list (ic, map->branch_actions) < 0)
3487 MDEBUG_PRINT ("\n");
3491 /* If MAP is still not the root map, shift to the current
3493 if (ic_info->map != ic_info->state->map)
3494 shift_state (ic, ic_info->state->name);
3499 /* MAP can not handle KEY. */
3501 /* Perform branch actions if any. */
3502 if (map->branch_actions)
3504 MDEBUG_PRINT (" branch-actions:");
3505 if (take_action_list (ic, map->branch_actions) < 0)
3507 MDEBUG_PRINT ("\n");
3512 if (map == ic_info->map)
3514 /* The above branch actions didn't change the state. */
3516 /* If MAP is the root map of the initial state, and there
3517 still exist an unhandled key, it means that the current
3518 input method can not handle it. */
3519 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3520 && ic_info->key_head < ic_info->used)
3522 MDEBUG_PRINT (" unhandled\n");
3526 if (map != ic_info->state->map)
3528 /* MAP is not the root map. Shift to the root map of the
3530 shift_state (ic, ic_info->state->name);
3532 else if (! map->branch_actions)
3534 /* MAP is the root map without any default branch
3535 actions. Shift to the initial state. */
3536 shift_state (ic, Mnil);
3540 MDEBUG_PRINT ("\n");
3544 /* Initialize IC->ic_info. */
3547 init_ic_info (MInputContext *ic)
3549 MInputMethodInfo *im_info = ic->im->info;
3550 MInputContextInfo *ic_info = ic->info;
3553 MLIST_INIT1 (ic_info, keys, 8);;
3555 ic_info->markers = mplist ();
3557 ic_info->vars = mplist ();
3558 if (im_info->configured_vars)
3559 MPLIST_DO (plist, im_info->configured_vars)
3561 MPlist *pl = MPLIST_PLIST (plist);
3562 MSymbol name = MPLIST_SYMBOL (pl);
3564 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3565 if (MPLIST_KEY (pl) != Mt)
3567 MPlist *p = mplist ();
3569 mplist_push (ic_info->vars, Mplist, p);
3570 M17N_OBJECT_UNREF (p);
3571 mplist_add (p, Msymbol, name);
3572 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3575 ic_info->vars_saved = mplist_copy (ic_info->vars);
3577 if (im_info->externals)
3579 MPlist *func_args = mplist (), *plist;
3581 mplist_add (func_args, Mt, ic);
3582 MPLIST_DO (plist, im_info->externals)
3584 MIMExternalModule *external = MPLIST_VAL (plist);
3585 MIMExternalFunc func
3586 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3591 M17N_OBJECT_UNREF (func_args);
3594 ic_info->preedit_saved = mtext ();
3595 ic_info->tick = im_info->tick;
3598 /* Finalize IC->ic_info. */
3601 fini_ic_info (MInputContext *ic)
3603 MInputMethodInfo *im_info = ic->im->info;
3604 MInputContextInfo *ic_info = ic->info;
3606 if (im_info->externals)
3608 MPlist *func_args = mplist (), *plist;
3610 mplist_add (func_args, Mt, ic);
3611 MPLIST_DO (plist, im_info->externals)
3613 MIMExternalModule *external = MPLIST_VAL (plist);
3614 MIMExternalFunc func
3615 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3620 M17N_OBJECT_UNREF (func_args);
3623 MLIST_FREE1 (ic_info, keys);
3624 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3625 M17N_OBJECT_UNREF (ic_info->markers);
3626 M17N_OBJECT_UNREF (ic_info->vars);
3627 M17N_OBJECT_UNREF (ic_info->vars_saved);
3628 M17N_OBJECT_UNREF (ic_info->preceding_text);
3629 M17N_OBJECT_UNREF (ic_info->following_text);
3631 memset (ic_info, 0, sizeof (MInputContextInfo));
3635 re_init_ic (MInputContext *ic, int reload)
3637 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3638 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3639 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3641 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3642 preedit_changed = mtext_nchars (ic->preedit) > 0;
3643 cursor_pos_changed = ic->cursor_pos > 0;
3644 candidates_changed = 0;
3645 if (ic->candidate_list)
3647 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3648 M17N_OBJECT_UNREF (ic->candidate_list);
3649 ic->candidate_list = NULL;
3651 if (ic->candidate_show)
3653 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3654 ic->candidate_show = 0;
3656 if (ic->candidate_index > 0)
3658 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3659 ic->candidate_index = 0;
3660 ic->candidate_from = ic->candidate_to = 0;
3662 if (mtext_nchars (ic->produced) > 0)
3663 mtext_reset (ic->produced);
3664 if (mtext_nchars (ic->preedit) > 0)
3665 mtext_reset (ic->preedit);
3667 M17N_OBJECT_UNREF (ic->plist);
3668 ic->plist = mplist ();
3672 reload_im_info (im_info);
3673 if (! im_info->states)
3675 struct MIMState *state;
3677 M17N_OBJECT (state, free_state, MERROR_IM);
3678 state->name = msymbol ("init");
3679 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3680 MSTRUCT_CALLOC (state->map, MERROR_IM);
3681 im_info->states = mplist ();
3682 mplist_add (im_info->states, state->name, state);
3685 shift_state (ic, Mnil);
3687 ic->status_changed = status_changed;
3688 ic->preedit_changed = preedit_changed;
3689 ic->cursor_pos_changed = cursor_pos_changed;
3690 ic->candidates_changed = candidates_changed;
3694 reset_ic (MInputContext *ic, MSymbol ignore)
3696 MDEBUG_PRINT ("\n [IM] reset\n");
3701 open_im (MInputMethod *im)
3703 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3705 if (! im_info || ! im_info->states)
3706 MERROR (MERROR_IM, -1);
3713 close_im (MInputMethod *im)
3719 create_ic (MInputContext *ic)
3721 MInputContextInfo *ic_info;
3723 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3726 shift_state (ic, Mnil);
3731 destroy_ic (MInputContext *ic)
3738 check_reload (MInputContext *ic, MSymbol key)
3740 MInputMethodInfo *im_info = ic->im->info;
3741 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3745 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3749 MPLIST_DO (plist, plist)
3751 MSymbol this_key, alias;
3753 if (MPLIST_MTEXT_P (plist))
3755 MText *mt = MPLIST_MTEXT (plist);
3756 int c = mtext_ref_char (mt, 0);
3760 this_key = one_char_symbol[c];
3764 MPlist *pl = MPLIST_PLIST (plist);
3766 this_key = MPLIST_SYMBOL (pl);
3770 && (alias = msymbol_get (alias, M_key_alias))
3771 && alias != this_key);
3775 if (MPLIST_TAIL_P (plist))
3778 MDEBUG_PRINT ("\n [IM] reload");
3784 /** Handle the input key KEY in the current state and map of IC->info.
3785 If KEY is handled but no text is produced, return 0, otherwise
3791 filter (MInputContext *ic, MSymbol key, void *arg)
3793 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3794 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3797 if (check_reload (ic, key))
3800 if (! ic_info->state)
3802 ic_info->key_unhandled = 1;
3805 mtext_reset (ic->produced);
3806 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3807 M17N_OBJECT_UNREF (ic_info->preceding_text);
3808 M17N_OBJECT_UNREF (ic_info->following_text);
3809 ic_info->preceding_text = ic_info->following_text = NULL;
3810 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3811 ic_info->key_unhandled = 0;
3814 if (handle_key (ic) < 0)
3816 /* KEY was not handled. Delete it from the current key sequence. */
3817 if (ic_info->used > 0)
3819 memmove (ic_info->keys, ic_info->keys + 1,
3820 sizeof (int) * (ic_info->used - 1));
3822 if (ic_info->state_key_head > 0)
3823 ic_info->state_key_head--;
3824 if (ic_info->commit_key_head > 0)
3825 ic_info->commit_key_head--;
3827 /* This forces returning 1. */
3828 ic_info->key_unhandled = 1;
3834 reset_ic (ic, Mnil);
3835 ic_info->key_unhandled = 1;
3838 /* Break the loop if all keys were handled. */
3839 } while (ic_info->key_head < ic_info->used);
3841 /* If the current map is the root of the initial state, we should
3842 produce any preedit text in ic->produced. */
3843 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3844 preedit_commit (ic, 1);
3846 if (mtext_nchars (ic->produced) > 0)
3850 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3851 MSYMBOL_NAME (ic_info->state->name));
3852 for (i = 0; i < mtext_nchars (ic->produced); i++)
3853 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3857 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3858 Mlanguage, ic->im->language);
3860 if (ic_info->commit_key_head > 0)
3862 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3863 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3864 ic_info->used -= ic_info->commit_key_head;
3865 ic_info->key_head -= ic_info->commit_key_head;
3866 ic_info->state_key_head -= ic_info->commit_key_head;
3867 ic_info->commit_key_head = 0;
3869 if (ic_info->key_unhandled)
3872 ic_info->key_head = ic_info->state_key_head
3873 = ic_info->commit_key_head = 0;
3876 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3880 /** Return 1 if the last event or key was not handled, otherwise
3883 There is no need of looking up because ic->produced should already
3884 contain the produced text (if any).
3889 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3891 mtext_cat (mt, ic->produced);
3892 mtext_reset (ic->produced);
3893 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3897 /* Input method command handler. */
3899 /* List of all (global and local) commands.
3900 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3901 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3902 Global commands are stored as (t (t COMMAND ...)) */
3905 /* Input method variable handler. */
3908 /* Support functions for mdebug_dump_im. */
3911 dump_im_map (MPlist *map_list, int indent)
3914 MSymbol key = MPLIST_KEY (map_list);
3915 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3917 prefix = (char *) alloca (indent + 1);
3918 memset (prefix, 32, indent);
3919 prefix[indent] = '\0';
3921 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3922 if (map->map_actions)
3923 mdebug_dump_plist (map->map_actions, indent + 2);
3926 MPLIST_DO (map_list, map->submaps)
3928 fprintf (stderr, "\n%s ", prefix);
3929 dump_im_map (map_list, indent + 2);
3932 if (map->branch_actions)
3934 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3935 mdebug_dump_plist (map->branch_actions, indent + 4);
3936 fprintf (stderr, ")");
3938 fprintf (stderr, ")");
3943 dump_im_state (MIMState *state, int indent)
3948 prefix = (char *) alloca (indent + 1);
3949 memset (prefix, 32, indent);
3950 prefix[indent] = '\0';
3952 fprintf (stderr, "(%s", msymbol_name (state->name));
3953 if (state->map->submaps)
3955 MPLIST_DO (map_list, state->map->submaps)
3957 fprintf (stderr, "\n%s ", prefix);
3958 dump_im_map (map_list, indent + 2);
3961 fprintf (stderr, ")");
3969 Minput_driver = msymbol ("input-driver");
3971 Minput_preedit_start = msymbol ("input-preedit-start");
3972 Minput_preedit_done = msymbol ("input-preedit-done");
3973 Minput_preedit_draw = msymbol ("input-preedit-draw");
3974 Minput_status_start = msymbol ("input-status-start");
3975 Minput_status_done = msymbol ("input-status-done");
3976 Minput_status_draw = msymbol ("input-status-draw");
3977 Minput_candidates_start = msymbol ("input-candidates-start");
3978 Minput_candidates_done = msymbol ("input-candidates-done");
3979 Minput_candidates_draw = msymbol ("input-candidates-draw");
3980 Minput_set_spot = msymbol ("input-set-spot");
3981 Minput_focus_move = msymbol ("input-focus-move");
3982 Minput_focus_in = msymbol ("input-focus-in");
3983 Minput_focus_out = msymbol ("input-focus-out");
3984 Minput_toggle = msymbol ("input-toggle");
3985 Minput_reset = msymbol ("input-reset");
3986 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3987 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3988 Mcustomized = msymbol ("customized");
3989 Mconfigured = msymbol ("configured");
3990 Minherited = msymbol ("inherited");
3992 minput_default_driver.open_im = open_im;
3993 minput_default_driver.close_im = close_im;
3994 minput_default_driver.create_ic = create_ic;
3995 minput_default_driver.destroy_ic = destroy_ic;
3996 minput_default_driver.filter = filter;
3997 minput_default_driver.lookup = lookup;
3998 minput_default_driver.callback_list = mplist ();
3999 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4000 M17N_FUNC (reset_ic));
4001 minput_driver = &minput_default_driver;
4003 fully_initialized = 0;
4010 if (fully_initialized)
4012 free_im_list (im_info_list);
4014 free_im_list (im_custom_list);
4016 free_im_list (im_config_list);
4017 M17N_OBJECT_UNREF (load_im_info_keys);
4020 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4021 M17N_OBJECT_UNREF (minput_driver->callback_list);
4026 minput__char_to_key (int c)
4028 if (c < 0 || c >= 0x100)
4031 return one_char_symbol[c];
4035 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4040 /*** @addtogroup m17nInputMethod */
4045 @name Variables: Predefined symbols for callback commands.
4047 These are the predefined symbols that are used as the @c COMMAND
4048 argument of callback functions of an input method driver (see
4049 #MInputDriver::callback_list).
4051 Most of them do not require extra argument nor return any value;
4052 exceptions are these:
4054 Minput_get_surrounding_text: When a callback function assigned for
4055 this command is called, the first element of #MInputContext::plist
4056 has key #Minteger and the value specifies which portion of the
4057 surrounding text should be retrieved. If the value is positive,
4058 it specifies the number of characters following the current cursor
4059 position. If the value is negative, the absolute value specifies
4060 the number of characters preceding the current cursor position.
4061 If the value is zero, it means that the caller just wants to know
4062 if the surrounding text is currently supported or not.
4064 If the surrounding text is currently supported, the callback
4065 function must set the key of this element to #Mtext and the value
4066 to the retrieved M-text. The length of the M-text may be shorter
4067 than the requested number of characters, if the available text is
4068 not that long. The length can be zero in the worst case. Or, the
4069 length may be longer if an application thinks it is more efficient
4070 to return that length.
4072 If the surrounding text is not currently supported, the callback
4073 function should return without changing the first element of
4074 #MInputContext::plist.
4076 Minput_delete_surrounding_text: When a callback function assigned
4077 for this command is called, the first element of
4078 #MInputContext::plist has key #Minteger and the value specifies
4079 which portion of the surrounding text should be deleted in the
4080 same way as the case of Minput_get_surrounding_text. The callback
4081 function must delete the specified text. It should not alter
4082 #MInputContext::plist. */
4084 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4086 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4087 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4089 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4091 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4092 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4093 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4094 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4095 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4096 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4097 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4099 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4100 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4101 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4102 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4103 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4105 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4106 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4108 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4109 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4110 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4111 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4112 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4113 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4117 MSymbol Minput_preedit_start;
4118 MSymbol Minput_preedit_done;
4119 MSymbol Minput_preedit_draw;
4120 MSymbol Minput_status_start;
4121 MSymbol Minput_status_done;
4122 MSymbol Minput_status_draw;
4123 MSymbol Minput_candidates_start;
4124 MSymbol Minput_candidates_done;
4125 MSymbol Minput_candidates_draw;
4126 MSymbol Minput_set_spot;
4127 MSymbol Minput_toggle;
4128 MSymbol Minput_reset;
4129 MSymbol Minput_get_surrounding_text;
4130 MSymbol Minput_delete_surrounding_text;
4136 @name Variables: Predefined symbols for special input events.
4138 These are the predefined symbols that are used as the @c KEY
4139 argument of minput_filter (). */
4141 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4143 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4148 MSymbol Minput_focus_out;
4149 MSymbol Minput_focus_in;
4150 MSymbol Minput_focus_move;
4156 @name Variables: Predefined symbols used in input method information.
4158 These are the predefined symbols describing status of input method
4159 command and variable, and are used in a return value of
4160 minput_get_command () and minput_get_variable (). */
4162 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4164 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4165 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4169 MSymbol Mcustomized;
4170 MSymbol Mconfigured;
4176 @brief The default driver for internal input methods.
4178 The variable #minput_default_driver is the default driver for
4179 internal input methods.
4181 The member MInputDriver::open_im () searches the m17n database for
4182 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4183 $NAME\> and loads it.
4185 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4186 programmers responsibility to set it to a plist of proper callback
4187 functions. Otherwise, no feedback information (e.g. preedit text)
4188 can be shown to users.
4190 The macro M17N_INIT () sets the variable #minput_driver to the
4191 pointer to this driver so that all internal input methods use it.
4193 Therefore, unless @c minput_driver is set differently, the driver
4194 dependent arguments $ARG of the functions whose name begins with
4195 "minput_" are all ignored. */
4197 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4199 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4201 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4202 \< #Minput_method, $LANGUAGE, $NAME\>
4203 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4205 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4206 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4207 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4208 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4210 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4211 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4213 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4214 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4216 MInputDriver minput_default_driver;
4220 @brief The driver for internal input methods.
4222 The variable #minput_driver is a pointer to the input method
4223 driver that is used by internal input methods. The macro
4224 M17N_INIT () initializes it to a pointer to #minput_default_driver
4225 if <m17n<EM></EM>.h> is included. */
4227 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4229 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4230 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4231 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4232 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4234 MInputDriver *minput_driver;
4236 MSymbol Minput_driver;
4251 @brief Open an input method.
4253 The minput_open_im () function opens an input method whose
4254 language and name match $LANGUAGE and $NAME, and returns a pointer
4255 to the input method object newly allocated.
4257 This function at first decides a driver for the input method as
4260 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4261 #minput_driver is used.
4263 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4264 driver pointed to by the property value is used to open the input
4265 method. If $NAME has no such a property, @c NULL is returned.
4267 Then, the member MInputDriver::open_im () of the driver is
4270 $ARG is set in the member @c arg of the structure MInputMethod so
4271 that the driver can refer to it. */
4273 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4275 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4276 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4278 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4280 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4281 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4283 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4284 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4285 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4287 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4289 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4291 @latexonly \IPAlabel{minput_open} @endlatexonly
4296 minput_open_im (MSymbol language, MSymbol name, void *arg)
4299 MInputDriver *driver;
4303 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4304 msymbol_name (language), msymbol_name (name));
4306 driver = minput_driver;
4309 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4311 MERROR (MERROR_IM, NULL);
4314 MSTRUCT_CALLOC (im, MERROR_IM);
4315 im->language = language;
4318 im->driver = *driver;
4319 if ((*im->driver.open_im) (im) < 0)
4321 MDEBUG_PRINT (" failed\n");
4325 MDEBUG_PRINT (" ok\n");
4332 @brief Close an input method.
4334 The minput_close_im () function closes the input method $IM, which
4335 must have been created by minput_open_im (). */
4338 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4340 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4341 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4344 minput_close_im (MInputMethod *im)
4346 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4347 msymbol_name (im->name), msymbol_name (im->language));
4348 (*im->driver.close_im) (im);
4350 MDEBUG_PRINT (" done\n");
4356 @brief Create an input context.
4358 The minput_create_ic () function creates an input context object
4359 associated with input method $IM, and calls callback functions
4360 corresponding to #Minput_preedit_start, #Minput_status_start, and
4361 #Minput_status_draw in this order.
4364 If an input context is successfully created, minput_create_ic ()
4365 returns a pointer to it. Otherwise it returns @c NULL. */
4368 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4370 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4371 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4372 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4373 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4376 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4377 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4381 minput_create_ic (MInputMethod *im, void *arg)
4385 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4386 msymbol_name (im->name), msymbol_name (im->language));
4387 MSTRUCT_CALLOC (ic, MERROR_IM);
4390 ic->preedit = mtext ();
4391 ic->candidate_list = NULL;
4392 ic->produced = mtext ();
4393 ic->spot.x = ic->spot.y = 0;
4395 ic->plist = mplist ();
4396 if ((*im->driver.create_ic) (ic) < 0)
4398 MDEBUG_PRINT (" failed\n");
4399 M17N_OBJECT_UNREF (ic->preedit);
4400 M17N_OBJECT_UNREF (ic->produced);
4401 M17N_OBJECT_UNREF (ic->plist);
4406 if (im->driver.callback_list)
4408 minput_callback (ic, Minput_preedit_start);
4409 minput_callback (ic, Minput_status_start);
4410 minput_callback (ic, Minput_status_draw);
4413 MDEBUG_PRINT (" ok\n");
4420 @brief Destroy an input context.
4422 The minput_destroy_ic () function destroys the input context $IC,
4423 which must have been created by minput_create_ic (). It calls
4424 callback functions corresponding to #Minput_preedit_done,
4425 #Minput_status_done, and #Minput_candidates_done in this order. */
4428 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4430 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4431 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4432 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4433 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4434 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4438 minput_destroy_ic (MInputContext *ic)
4440 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4441 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4442 if (ic->im->driver.callback_list)
4444 minput_callback (ic, Minput_preedit_done);
4445 minput_callback (ic, Minput_status_done);
4446 minput_callback (ic, Minput_candidates_done);
4448 (*ic->im->driver.destroy_ic) (ic);
4449 M17N_OBJECT_UNREF (ic->preedit);
4450 M17N_OBJECT_UNREF (ic->produced);
4451 M17N_OBJECT_UNREF (ic->plist);
4452 MDEBUG_PRINT (" done\n");
4459 @brief Filter an input key.
4461 The minput_filter () function filters input key $KEY according to
4462 input context $IC, and calls callback functions corresponding to
4463 #Minput_preedit_draw, #Minput_status_draw, and
4464 #Minput_candidates_draw if the preedit text, the status, and the
4465 current candidate are changed respectively.
4467 To make the input method commit the current preedit text (if any)
4468 and shift to the initial state, call this function with #Mnil as
4471 To inform the input method about the focus-out event, call this
4472 function with #Minput_focus_out as $KEY.
4474 To inform the input method about the focus-in event, call this
4475 function with #Minput_focus_in as $KEY.
4477 To inform the input method about the focus-move event (i.e. input
4478 spot change within the same input context), call this function
4479 with #Minput_focus_move as $KEY.
4482 If $KEY is filtered out, this function returns 1. In that case,
4483 the caller should discard the key. Otherwise, it returns 0, and
4484 the caller should handle the key, for instance, by calling the
4485 function minput_lookup () with the same key. */
4488 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4490 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4491 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4492 #Minput_preedit_draw, #Minput_status_draw,
4493 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4496 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4497 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4498 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4499 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4501 @latexonly \IPAlabel{minput_filter} @endlatexonly
4505 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4512 if (ic->im->driver.callback_list
4513 && mtext_nchars (ic->preedit) > 0)
4514 minput_callback (ic, Minput_preedit_draw);
4516 ret = (*ic->im->driver.filter) (ic, key, arg);
4518 if (ic->im->driver.callback_list)
4520 if (ic->preedit_changed)
4521 minput_callback (ic, Minput_preedit_draw);
4522 if (ic->status_changed)
4523 minput_callback (ic, Minput_status_draw);
4524 if (ic->candidates_changed)
4525 minput_callback (ic, Minput_candidates_draw);
4534 @brief Look up a text produced in the input context.
4536 The minput_lookup () function looks up a text in the input context
4537 $IC. $KEY must be identical to the one that was used in the previous call of
4540 If a text was produced by the input method, it is concatenated
4543 This function calls #MInputDriver::lookup .
4546 If $KEY was correctly handled by the input method, this function
4547 returns 0. Otherwise, it returns -1, even though some text
4548 might be produced in $MT. */
4551 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4553 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4554 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4556 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4559 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4562 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4563 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4564 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4566 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4569 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4571 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4576 @brief Set the spot of the input context.
4578 The minput_set_spot () function sets the spot of input context $IC
4579 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4580 The semantics of these values depends on the input method driver.
4582 For instance, a driver designed to work in a CUI environment may
4583 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4584 $DESCENT . A driver designed to work in a window system may
4585 interpret $X and $Y as the pixel offsets relative to the origin of the
4586 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4587 descent pixels of the line at ($X . $Y ).
4589 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4591 $MT and $POS are the M-text and the character position at the spot.
4592 $MT may be @c NULL, in which case, the input method cannot get
4593 information about the text around the spot. */
4596 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4598 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4599 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4600 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4602 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4603 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4604 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4605 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4606 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4607 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4609 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4611 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4612 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4616 minput_set_spot (MInputContext *ic, int x, int y,
4617 int ascent, int descent, int fontsize,
4622 ic->spot.ascent = ascent;
4623 ic->spot.descent = descent;
4624 ic->spot.fontsize = fontsize;
4627 if (ic->im->driver.callback_list)
4628 minput_callback (ic, Minput_set_spot);
4633 @brief Toggle input method.
4635 The minput_toggle () function toggles the input method associated
4636 with input context $IC. */
4638 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4640 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4641 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4645 minput_toggle (MInputContext *ic)
4647 if (ic->im->driver.callback_list)
4648 minput_callback (ic, Minput_toggle);
4649 ic->active = ! ic->active;
4655 @brief Reset an input context.
4657 The minput_reset_ic () function resets input context $IC by
4658 calling a callback function corresponding to #Minput_reset. It
4659 resets the status of $IC to its initial one. As the
4660 current preedit text is deleted without commitment, if necessary,
4661 call minput_filter () with the arg @r key #Mnil to force the input
4662 method to commit the preedit in advance. */
4665 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4667 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4668 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4669 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4670 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4671 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4672 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4675 minput_reset_ic (MInputContext *ic)
4677 if (ic->im->driver.callback_list)
4678 minput_callback (ic, Minput_reset);
4684 @brief Get title and icon filename of an input method.
4686 The minput_get_title_icon () function returns a plist containing a
4687 title and icon filename (if any) of an input method specified by
4688 $LANGUAGE and $NAME.
4690 The first element of the plist has key #Mtext and the value is an
4691 M-text of the title for identifying the input method. The second
4692 element (if any) has key #Mtext and the value is an M-text of the
4693 icon image (absolute) filename for the same purpose.
4696 If there exists a specified input method and it defines an title,
4697 a plist is returned. Otherwise, NULL is returned. The caller
4698 must free the plist by m17n_object_unref (). */
4700 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4702 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4703 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4706 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4707 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4708 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4711 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4712 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4713 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4716 minput_get_title_icon (MSymbol language, MSymbol name)
4718 MInputMethodInfo *im_info;
4725 im_info = get_im_info (language, name, Mnil, Mtitle);
4726 if (! im_info || !im_info->title)
4728 mt = mtext_get_prop (im_info->title, 0, Mtext);
4730 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4733 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4736 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4737 (char *) MSYMBOL_NAME (name));
4738 file = mdatabase__find_file (buf);
4739 if (! file && language == Mt)
4741 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4742 file = mdatabase__find_file (buf);
4747 mplist_add (plist, Mtext, im_info->title);
4750 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4752 mplist_add (plist, Mtext, mt);
4753 M17N_OBJECT_UNREF (mt);
4761 @brief Get description text of an input method.
4763 The minput_get_description () function returns an M-text that
4764 describes the input method specified by $LANGUAGE and $NAME.
4767 If the specified input method has a description text, a pointer to
4768 #MText is returned. The caller has to free it by m17n_object_unref ().
4769 If the input method does not have a description text, @c NULL is
4772 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4774 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4775 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4777 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4778 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4779 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4780 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4783 minput_get_description (MSymbol language, MSymbol name)
4785 MInputMethodInfo *im_info;
4793 extra = language, language = Mt;
4795 im_info = get_im_info (language, name, extra, Mdescription);
4796 if (! im_info || ! im_info->description)
4798 M17N_OBJECT_REF (im_info->description);
4799 return im_info->description;
4805 @brief Get information about input method command(s).
4807 The minput_get_command () function returns information about
4808 the command $COMMAND of the input method specified by $LANGUAGE and
4809 $NAME. An input method command is a pseudo key event to which one
4810 or more actual input key sequences are assigned.
4812 There are two kinds of commands, global and local. A global
4813 command has a global definition, and the description and the key
4814 assignment may be inherited by a local command. Each input method
4815 defines a local command which has a local key assignment. It may
4816 also declare a local command that inherits the definition of a
4817 global command of the same name.
4819 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4820 information about a global command. Otherwise information about a
4821 local command is returned.
4823 If $COMMAND is #Mnil, information about all commands is returned.
4825 The return value is a @e well-formed plist (@ref m17nPlist) of this
4828 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4830 @c NAME is a symbol representing the command name.
4832 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4833 command has no description.
4835 @c STATUS is a symbol representing how the key assignment is decided.
4836 The value is #Mnil (the default key assignment), #Mcustomized (the
4837 key assignment is customized by per-user customization file), or
4838 #Mconfigured (the key assignment is set by the call of
4839 minput_config_command ()). For a local command only, it may also
4840 be #Minherited (the key assignment is inherited from the
4841 corresponding global command).
4843 @c KEYSEQ is a plist of one or more symbols representing a key
4844 sequence assigned to the command. If there's no KEYSEQ, the
4845 command is currently disabled (i.e. no key sequence can trigger
4846 actions of the command).
4848 If $COMMAND is not #Mnil, the first element of the returned plist
4849 contains the information about $COMMAND.
4853 If the requested information was found, a pointer to a non-empty
4854 plist is returned. As the plist is kept in the library, the
4855 caller must not modify nor free it.
4857 Otherwise (the specified input method or the specified command
4858 does not exist), @c NULL is returned. */
4860 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4862 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4863 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4864 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4865 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4867 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4868 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4869 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4870 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4871 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4873 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4874 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4877 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4879 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4882 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4884 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4886 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4889 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4890 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4891 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4892 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4893 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4894 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4897 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4898 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4899 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4900 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4902 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4903 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4907 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4908 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4911 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4916 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4918 /* Return a description of the command COMMAND of the input method
4919 specified by LANGUAGE and NAME. */
4920 MPlist *cmd = minput_get_command (langauge, name, command);
4925 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4926 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4927 return (mplist_key (plist) == Mtext
4928 ? (MText *) mplist_value (plist)
4934 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4936 MInputMethodInfo *im_info;
4940 im_info = get_im_info (language, name, Mnil, Mcommand);
4942 || ! im_info->configured_cmds
4943 || MPLIST_TAIL_P (im_info->configured_cmds))
4945 if (command == Mnil)
4946 return im_info->configured_cmds;
4947 return mplist__assq (im_info->configured_cmds, command);
4953 @brief Configure the key sequence of an input method command.
4955 The minput_config_command () function assigns a list of key
4956 sequences $KEYSEQLIST to the command $COMMAND of the input method
4957 specified by $LANGUAGE and $NAME.
4959 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4960 sequences, and each key sequence must be a plist of symbols.
4962 If $KEYSEQLIST is an empty plist, any configuration and
4963 customization of the command are cancelled, and default key
4964 sequences become effective.
4966 If $KEYSEQLIST is NULL, the configuration of the command is
4967 canceled, and the original key sequences (what saved in per-user
4968 customization file, or the default one) become effective.
4970 In the latter two cases, $COMMAND can be #Mnil to make all the
4971 commands of the input method the target of the operation.
4973 If $NAME is #Mnil, this function configures the key assignment of a
4974 global command, not that of a specific input method.
4976 The configuration takes effect for input methods opened or
4977 re-opened later in the current session. In order to make the
4978 configuration take effect for the future session, it must be saved
4979 in a per-user customization file by the function
4980 minput_save_config ().
4983 If the operation was successful, this function returns 0,
4984 otherwise returns -1. The operation fails in these cases:
4986 <li>$KEYSEQLIST is not in a valid form.
4987 <li>$COMMAND is not available for the input method.
4988 <li>$LANGUAGE and $NAME do not specify an existing input method.
4992 minput_get_commands (), minput_save_config ().
4995 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4997 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4998 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4999 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5001 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5002 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5004 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5005 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5007 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5008 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5009 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5011 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5012 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5014 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5015 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5017 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5018 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5019 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5020 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5024 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5026 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5027 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5028 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5032 minput_get_commands (), minput_save_config ().
5036 /* Add "C-x u" to the "start" command of Unicode input method. */
5038 MSymbol start_command = msymbol ("start");
5039 MSymbol unicode = msymbol ("unicode");
5040 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5042 /* At first get the current key-sequence assignment. */
5043 cmd = minput_get_command (Mt, unicode, start_command);
5046 /* The input method does not have the command "start". Here
5047 should come some error handling code. */
5049 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5050 Extract the part (KEY-SEQUENCE ...). */
5051 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5052 /* Copy it because we should not modify it directly. */
5053 key_seq_list = mplist_copy (plist);
5055 key_seq = mplist ();
5056 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5057 mplist_add (key_seq, Msymbol, msymbol ("u"));
5058 mplist_add (key_seq_list, Mplist, key_seq);
5059 m17n_object_unref (key_seq);
5061 minput_config_command (Mt, unicode, start_command, key_seq_list);
5062 m17n_object_unref (key_seq_list);
5067 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5070 MInputMethodInfo *im_info, *config;
5075 im_info = get_im_info (language, name, Mnil, Mcommand);
5077 MERROR (MERROR_IM, -1);
5078 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5080 || ! mplist__assq (im_info->configured_cmds, command)))
5081 MERROR (MERROR_IM, -1);
5082 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5084 MPLIST_DO (plist, keyseqlist)
5085 if (! check_command_keyseq (plist))
5086 MERROR (MERROR_IM, -1);
5089 config = get_config_info (im_info);
5092 if (! im_config_list)
5093 im_config_list = mplist ();
5094 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5095 config->cmds = mplist ();
5096 config->vars = mplist ();
5099 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5100 /* Nothing to do. */
5103 if (command == Mnil)
5107 /* Cancal the configuration. */
5108 if (MPLIST_TAIL_P (config->cmds))
5110 mplist_set (config->cmds, Mnil, NULL);
5114 /* Cancal the customization. */
5115 MInputMethodInfo *custom = get_custom_info (im_info);
5117 if (MPLIST_TAIL_P (config->cmds)
5118 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5119 /* Nothing to do. */
5121 mplist_set (config->cmds, Mnil, NULL);
5122 MPLIST_DO (plist, custom->cmds)
5124 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5126 mplist_add (plist, Msymbol, command);
5127 mplist_push (config->cmds, Mplist, plist);
5128 M17N_OBJECT_UNREF (plist);
5134 plist = mplist__assq (config->cmds, command);
5137 /* Cancel the configuration. */
5140 mplist__pop_unref (plist);
5142 else if (MPLIST_TAIL_P (keyseqlist))
5144 /* Cancel the customization. */
5145 MInputMethodInfo *custom = get_custom_info (im_info);
5146 int no_custom = (! custom || ! custom->cmds
5147 || ! mplist__assq (custom->cmds, command));
5153 mplist_add (config->cmds, Mplist, plist);
5154 M17N_OBJECT_UNREF (plist);
5155 plist = mplist_add (plist, Msymbol, command);
5160 mplist__pop_unref (plist);
5163 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5164 plist = MPLIST_NEXT (plist);
5165 mplist_set (plist, Mnil, NULL);
5175 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5176 if (! MPLIST_TAIL_P (plist))
5177 mplist_set (plist, Mnil, NULL);
5182 mplist_add (config->cmds, Mplist, plist);
5183 M17N_OBJECT_UNREF (plist);
5184 plist = mplist_add (plist, Msymbol, command);
5185 plist = MPLIST_NEXT (plist);
5187 MPLIST_DO (keyseqlist, keyseqlist)
5189 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5190 plist = mplist_add (plist, Mplist, pl);
5191 M17N_OBJECT_UNREF (pl);
5195 config_all_commands (im_info);
5196 im_info->tick = time (NULL);
5203 @brief Get information about input method variable(s).
5205 The minput_get_variable () function returns information about
5206 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5207 An input method variable controls behavior of an input method.
5209 There are two kinds of variables, global and local. A global
5210 variable has a global definition, and the description and the value
5211 may be inherited by a local variable. Each input method defines a
5212 local variable which has local value. It may also declare a
5213 local variable that inherits definition of a global variable of
5216 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5217 variable is returned. Otherwise information about a local variable
5220 If $VARIABLE is #Mnil, information about all variables is
5223 The return value is a @e well-formed plist (@ref m17nPlist) of this
5226 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5228 @c NAME is a symbol representing the variable name.
5230 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5231 variable has no description.
5233 @c STATUS is a symbol representing how the value is decided. The
5234 value is #Mnil (the default value), #Mcustomized (the value is
5235 customized by per-user customization file), or #Mconfigured (the
5236 value is set by the call of minput_config_variable ()). For a
5237 local variable only, it may also be #Minherited (the value is
5238 inherited from the corresponding global variable).
5240 @c VALUE is the initial value of the variable. If the key of this
5241 element is #Mt, the variable has no initial value. Otherwise, the
5242 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5245 @c VALID-VALUEs (if any) specify which values the variable can have.
5246 They have the same type (i.e. having the same key) as @c VALUE except
5247 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5248 may be a plist of two integers specifying the range of possible
5251 If there no @c VALID-VALUE, the variable can have any value as long
5252 as the type is the same as @c VALUE.
5254 If $VARIABLE is not #Mnil, the first element of the returned plist
5255 contains the information about $VARIABLE.
5259 If the requested information was found, a pointer to a non-empty
5260 plist is returned. As the plist is kept in the library, the
5261 caller must not modify nor free it.
5263 Otherwise (the specified input method or the specified variable
5264 does not exist), @c NULL is returned. */
5266 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5268 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5269 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5270 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5272 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5273 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5274 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5275 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5278 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5279 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5281 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5283 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5285 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5288 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5290 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5293 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5294 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5295 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5296 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5297 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5298 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5300 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5301 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5302 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5304 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5305 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5306 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5307 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5309 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5312 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5313 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5317 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5318 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5321 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5325 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5327 MInputMethodInfo *im_info;
5331 im_info = get_im_info (language, name, Mnil, Mvariable);
5332 if (! im_info || ! im_info->configured_vars)
5334 if (variable == Mnil)
5335 return im_info->configured_vars;
5336 return mplist__assq (im_info->configured_vars, variable);
5342 @brief Configure the value of an input method variable.
5344 The minput_config_variable () function assigns $VALUE to the
5345 variable $VARIABLE of the input method specified by $LANGUAGE and
5348 If $VALUE is a non-empty plist, it must be a plist of one element
5349 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5350 the corresponding type. That value is assigned to the variable.
5352 If $VALUE is an empty plist, any configuration and customization
5353 of the variable are canceled, and the default value is assigned to
5356 If $VALUE is NULL, the configuration of the variable is canceled,
5357 and the original value (what saved in per-user customization file,
5358 or the default value) is assigned to the variable.
5360 In the latter two cases, $VARIABLE can be #Mnil to make all the
5361 variables of the input method the target of the operation.
5363 If $NAME is #Mnil, this function configures the value of global
5364 variable, not that of a specific input method.
5366 The configuration takes effect for input methods opened or
5367 re-opened later in the current session. To make the configuration
5368 take effect for the future session, it must be saved in a per-user
5369 customization file by the function minput_save_config ().
5373 If the operation was successful, this function returns 0,
5374 otherwise returns -1. The operation fails in these cases:
5376 <li>$VALUE is not in a valid form, the type does not match the
5377 definition, or the value is our of range.
5378 <li>$VARIABLE is not available for the input method.
5379 <li>$LANGUAGE and $NAME do not specify an existing input method.
5383 minput_get_variable (), minput_save_config (). */
5385 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5387 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5388 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5390 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5391 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5392 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5394 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5395 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5397 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5398 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5400 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5401 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5403 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5404 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5406 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5407 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5408 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5409 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5413 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5415 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5416 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5417 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5421 minput_get_commands (), minput_save_config ().
5424 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5427 MInputMethodInfo *im_info, *config;
5432 im_info = get_im_info (language, name, Mnil, Mvariable);
5434 MERROR (MERROR_IM, -1);
5435 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5437 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5438 MERROR (MERROR_IM, -1);
5440 if (value && ! MPLIST_TAIL_P (value))
5442 plist = MPLIST_PLIST (plist);
5443 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5444 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5445 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5446 if (MPLIST_KEY (plist) != Mt
5447 && ! check_variable_value (value, plist))
5448 MERROR (MERROR_IM, -1);
5451 config = get_config_info (im_info);
5454 if (! im_config_list)
5455 im_config_list = mplist ();
5456 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5457 config->cmds = mplist ();
5458 config->vars = mplist ();
5461 if (! value && MPLIST_TAIL_P (config->vars))
5462 /* Nothing to do. */
5465 if (variable == Mnil)
5469 /* Cancel the configuration. */
5470 if (MPLIST_TAIL_P (config->vars))
5472 mplist_set (config->vars, Mnil, NULL);
5476 /* Cancel the customization. */
5477 MInputMethodInfo *custom = get_custom_info (im_info);
5479 if (MPLIST_TAIL_P (config->vars)
5480 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5481 /* Nothing to do. */
5483 mplist_set (config->vars, Mnil, NULL);
5484 MPLIST_DO (plist, custom->vars)
5486 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5488 mplist_add (plist, Msymbol, variable);
5489 mplist_push (config->vars, Mplist, plist);
5490 M17N_OBJECT_UNREF (plist);
5496 plist = mplist__assq (config->vars, variable);
5499 /* Cancel the configuration. */
5502 mplist__pop_unref (plist);
5504 else if (MPLIST_TAIL_P (value))
5506 /* Cancel the customization. */
5507 MInputMethodInfo *custom = get_custom_info (im_info);
5508 int no_custom = (! custom || ! custom->vars
5509 || ! mplist__assq (custom->vars, variable));
5515 mplist_add (config->vars, Mplist, plist);
5516 M17N_OBJECT_UNREF (plist);
5517 plist = mplist_add (plist, Msymbol, variable);
5522 mplist__pop_unref (plist);
5525 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5526 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5527 mplist_set (plist, Mnil ,NULL);
5535 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5536 if (! MPLIST_TAIL_P (plist))
5537 mplist_set (plist, Mnil, NULL);
5542 mplist_add (config->vars, Mplist, plist);
5543 M17N_OBJECT_UNREF (plist);
5544 plist = mplist_add (plist, Msymbol, variable);
5545 plist = MPLIST_NEXT (plist);
5547 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5550 config_all_variables (im_info);
5551 im_info->tick = time (NULL);
5558 @brief Get the name of per-user customization file.
5560 The minput_config_file () function returns the absolute path name
5561 of per-user customization file into which minput_save_config ()
5562 save configurations. It is usually @c "config.mic" under the
5563 directory @c ".m17n.d" of user's home directory. It is not assured
5564 that the file of the returned name exists nor is
5565 readable/writable. If minput_save_config () fails and returns -1,
5566 an application program might check the file, make it
5567 writable (if possible), and try minput_save_config () again.
5571 This function returns a string. As the string is kept in the
5572 library, the caller must not modify nor free it.
5575 minput_save_config ()
5578 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5580 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5581 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5582 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5583 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5584 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5585 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5586 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5591 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5592 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5595 minput_save_config ()
5599 minput_config_file ()
5603 return mdatabase__file (im_custom_mdb);
5609 @brief Save configurations in per-user customization file.
5611 The minput_save_config () function saves the configurations done
5612 so far in the current session into the per-user customization
5617 If the operation was successful, 1 is returned. If the per-user
5618 customization file is currently locked, 0 is returned. In that
5619 case, the caller may wait for a while and try again. If the
5620 configuration file is not writable, -1 is returned. In that case,
5621 the caller may check the name of the file by calling
5622 minput_config_file (), make it writable if possible, and try
5626 minput_config_file () */
5628 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5630 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5631 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5635 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5636 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5637 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5638 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5642 minput_config_file () */
5645 minput_save_config (void)
5647 MPlist *data, *tail, *plist, *p, *elt;
5651 ret = mdatabase__lock (im_custom_mdb);
5654 if (! im_config_list)
5656 update_custom_info ();
5657 if (! im_custom_list)
5658 im_custom_list = mplist ();
5660 /* At first, reflect configuration in customization. */
5661 MPLIST_DO (plist, im_config_list)
5663 MPlist *pl = MPLIST_PLIST (plist);
5664 MSymbol language, name, extra, command, variable;
5665 MInputMethodInfo *custom, *config;
5667 language = MPLIST_SYMBOL (pl);
5668 pl = MPLIST_NEXT (pl);
5669 name = MPLIST_SYMBOL (pl);
5670 pl = MPLIST_NEXT (pl);
5671 extra = MPLIST_SYMBOL (pl);
5672 pl = MPLIST_NEXT (pl);
5673 config = MPLIST_VAL (pl);
5674 custom = get_custom_info (config);
5676 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5678 MPLIST_DO (pl, config->cmds)
5680 elt = MPLIST_PLIST (pl);
5681 command = MPLIST_SYMBOL (elt);
5683 p = mplist__assq (custom->cmds, command);
5685 custom->cmds = mplist (), p = NULL;
5686 elt = MPLIST_NEXT (elt);
5689 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5690 mplist_set (p, Mnil, NULL);
5695 mplist_add (custom->cmds, Mplist, p);
5696 M17N_OBJECT_UNREF (p);
5697 mplist_add (p, Msymbol, command);
5698 p = mplist_add (p, Msymbol, Mnil);
5699 p = MPLIST_NEXT (p);
5701 mplist__conc (p, elt);
5704 MPLIST_DO (pl, config->vars)
5706 elt = MPLIST_PLIST (pl);
5707 variable = MPLIST_SYMBOL (elt);
5709 p = mplist__assq (custom->vars, variable);
5711 custom->vars = mplist (), p = NULL;
5712 elt = MPLIST_NEXT (elt);
5715 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5716 mplist_set (p, Mnil, NULL);
5721 mplist_add (custom->vars, Mplist, p);
5722 M17N_OBJECT_UNREF (p);
5723 mplist_add (p, Msymbol, variable);
5724 p = mplist_add (p, Msymbol, Mnil);
5725 p = MPLIST_NEXT (p);
5727 mplist__conc (p, elt);
5730 free_im_list (im_config_list);
5731 im_config_list = NULL;
5733 /* Next, reflect customization to the actual plist to be written. */
5734 data = tail = mplist ();
5735 MPLIST_DO (plist, im_custom_list)
5737 MPlist *pl = MPLIST_PLIST (plist);
5738 MSymbol language, name, extra;
5739 MInputMethodInfo *custom, *im_info;
5741 language = MPLIST_SYMBOL (pl);
5742 pl = MPLIST_NEXT (pl);
5743 name = MPLIST_SYMBOL (pl);
5744 pl = MPLIST_NEXT (pl);
5745 extra = MPLIST_SYMBOL (pl);
5746 pl = MPLIST_NEXT (pl);
5747 custom = MPLIST_VAL (pl);
5748 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5749 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5751 im_info = lookup_im_info (im_info_list, language, name, extra);
5755 config_all_commands (im_info);
5757 config_all_variables (im_info);
5761 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5763 MPLIST_DO (p, custom->cmds)
5764 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5766 if (! MPLIST_TAIL_P (p))
5770 mplist_add (elt, Mplist, pl);
5771 M17N_OBJECT_UNREF (pl);
5772 pl = mplist_add (pl, Msymbol, Mcommand);
5773 MPLIST_DO (p, custom->cmds)
5774 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5775 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5778 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5780 MPLIST_DO (p, custom->vars)
5781 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5783 if (! MPLIST_TAIL_P (p))
5788 mplist_add (elt, Mplist, pl);
5789 M17N_OBJECT_UNREF (pl);
5790 pl = mplist_add (pl, Msymbol, Mvariable);
5791 MPLIST_DO (p, custom->vars)
5792 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5793 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5799 mplist_push (elt, Mplist, pl);
5800 M17N_OBJECT_UNREF (pl);
5801 pl = mplist_add (pl, Msymbol, Minput_method);
5802 pl = mplist_add (pl, Msymbol, language);
5803 pl = mplist_add (pl, Msymbol, name);
5805 pl = mplist_add (pl, Msymbol, extra);
5806 tail = mplist_add (tail, Mplist, elt);
5807 M17N_OBJECT_UNREF (elt);
5811 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5812 ret = mdatabase__save (im_custom_mdb, data);
5813 mdatabase__unlock (im_custom_mdb);
5814 M17N_OBJECT_UNREF (data);
5815 return (ret < 0 ? -1 : 1);
5822 @name Obsolete functions
5825 @name Obsolete ¤Ê´Ø¿ô
5831 @brief Get a list of variables of an input method (obsolete).
5833 This function is obsolete. Use minput_get_variable () instead.
5835 The minput_get_variables () function returns a plist (#MPlist) of
5836 variables used to control the behavior of the input method
5837 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5838 (@ref m17nPlist) of the following format:
5841 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5842 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5846 @c VARNAME is a symbol representing the variable name.
5848 @c DOC-MTEXT is an M-text describing the variable.
5850 @c DEFAULT-VALUE is the default value of the variable. It is a
5851 symbol, integer, or M-text.
5853 @c VALUEs (if any) specifies the possible values of the variable.
5854 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5855 @c TO), where @c FROM and @c TO specifies a range of possible
5858 For instance, suppose an input method has the variables:
5860 @li name:intvar, description:"value is an integer",
5861 initial value:0, value-range:0..3,10,20
5863 @li name:symvar, description:"value is a symbol",
5864 initial value:nil, value-range:a, b, c, nil
5866 @li name:txtvar, description:"value is an M-text",
5867 initial value:empty text, no value-range (i.e. any text)
5869 Then, the returned plist is as follows.
5872 (intvar ("value is an integer" 0 (0 3) 10 20)
5873 symvar ("value is a symbol" nil a b c nil)
5874 txtvar ("value is an M-text" ""))
5878 If the input method uses any variables, a pointer to #MPlist is
5879 returned. As the plist is kept in the library, the caller must not
5880 modify nor free it. If the input method does not use any
5881 variable, @c NULL is returned. */
5883 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5885 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5886 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5887 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5891 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5892 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5896 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5898 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5900 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5903 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5904 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5905 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5907 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5909 @li name:intvar, ÀâÌÀ:"value is an integer",
5910 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5912 @li name:symvar, ÀâÌÀ:"value is a symbol",
5913 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5915 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5916 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5918 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5921 (intvar ("value is an integer" 0 (0 3) 10 20)
5922 symvar ("value is a symbol" nil a b c nil)
5923 txtvar ("value is an M-text" ""))
5927 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5928 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5929 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5932 minput_get_variables (MSymbol language, MSymbol name)
5934 MInputMethodInfo *im_info;
5939 im_info = get_im_info (language, name, Mnil, Mvariable);
5940 if (! im_info || ! im_info->configured_vars)
5943 M17N_OBJECT_UNREF (im_info->bc_vars);
5944 im_info->bc_vars = mplist ();
5945 MPLIST_DO (vars, im_info->configured_vars)
5947 MPlist *plist = MPLIST_PLIST (vars);
5948 MPlist *elt = mplist ();
5950 mplist_push (im_info->bc_vars, Mplist, elt);
5951 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5952 elt = MPLIST_NEXT (elt);
5953 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5954 M17N_OBJECT_UNREF (elt);
5956 return im_info->bc_vars;
5962 @brief Set the initial value of an input method variable.
5964 The minput_set_variable () function sets the initial value of
5965 input method variable $VARIABLE to $VALUE for the input method
5966 specified by $LANGUAGE and $NAME.
5968 By default, the initial value is 0.
5970 This setting gets effective in a newly opened input method.
5973 If the operation was successful, 0 is returned. Otherwise -1 is
5974 returned, and #merror_code is set to #MERROR_IM. */
5976 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5978 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5979 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5980 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5982 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5984 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5987 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5988 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5991 minput_set_variable (MSymbol language, MSymbol name,
5992 MSymbol variable, void *value)
5995 MInputMethodInfo *im_info;
6000 if (variable == Mnil)
6001 MERROR (MERROR_IM, -1);
6002 plist = minput_get_variable (language, name, variable);
6003 plist = MPLIST_PLIST (plist);
6004 plist = MPLIST_NEXT (plist);
6006 mplist_add (pl, MPLIST_KEY (plist), value);
6007 ret = minput_config_variable (language, name, variable, pl);
6008 M17N_OBJECT_UNREF (pl);
6011 im_info = get_im_info (language, name, Mnil, Mvariable);
6020 @brief Get information about input method commands.
6022 The minput_get_commands () function returns information about
6023 input method commands of the input method specified by $LANGUAGE
6024 and $NAME. An input method command is a pseudo key event to which
6025 one or more actual input key sequences are assigned.
6027 There are two kinds of commands, global and local. Global
6028 commands are used by multiple input methods for the same purpose,
6029 and have global key assignments. Local commands are used only by
6030 a specific input method, and have only local key assignments.
6032 Each input method may locally change key assignments for global
6033 commands. The global key assignment for a global command is
6034 effective only when the current input method does not have local
6035 key assignments for that command.
6037 If $NAME is #Mnil, information about global commands is returned.
6038 In this case $LANGUAGE is ignored.
6040 If $NAME is not #Mnil, information about those commands that have
6041 local key assignments in the input method specified by $LANGUAGE
6042 and $NAME is returned.
6045 If no input method commands are found, this function returns @c NULL.
6047 Otherwise, a pointer to a plist is returned. The key of each
6048 element in the plist is a symbol representing a command, and the
6049 value is a plist of the form COMMAND-INFO described below.
6051 The first element of COMMAND-INFO has the key #Mtext, and the
6052 value is an M-text describing the command.
6054 If there are no more elements, that means no key sequences are
6055 assigned to the command. Otherwise, each of the remaining
6056 elements has the key #Mplist, and the value is a plist whose keys are
6057 #Msymbol and values are symbols representing input keys, which are
6058 currently assigned to the command.
6060 As the returned plist is kept in the library, the caller must not
6061 modify nor free it. */
6063 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6065 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6066 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6067 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6068 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6070 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6071 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6072 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6073 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6075 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6076 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6077 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6080 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6081 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6083 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6084 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6088 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6090 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6091 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6092 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6094 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6095 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6096 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6099 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6100 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6101 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6102 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6103 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6105 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6106 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6109 minput_get_commands (MSymbol language, MSymbol name)
6111 MInputMethodInfo *im_info;
6116 im_info = get_im_info (language, name, Mnil, Mcommand);
6117 if (! im_info || ! im_info->configured_vars)
6119 M17N_OBJECT_UNREF (im_info->bc_cmds);
6120 im_info->bc_cmds = mplist ();
6121 MPLIST_DO (cmds, im_info->configured_cmds)
6123 MPlist *plist = MPLIST_PLIST (cmds);
6124 MPlist *elt = mplist ();
6126 mplist_push (im_info->bc_cmds, Mplist, elt);
6127 mplist_add (elt, MPLIST_SYMBOL (plist),
6128 mplist_copy (MPLIST_NEXT (plist)));
6129 M17N_OBJECT_UNREF (elt);
6131 return im_info->bc_cmds;
6137 @brief Assign a key sequence to an input method command (obsolete).
6139 This function is obsolete. Use minput_config_command () instead.
6141 The minput_assign_command_keys () function assigns input key
6142 sequence $KEYSEQ to input method command $COMMAND for the input
6143 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6144 key sequence is assigned globally no matter what $LANGUAGE is.
6145 Otherwise the key sequence is assigned locally.
6147 Each element of $KEYSEQ must have the key $Msymbol and the value
6148 must be a symbol representing an input key.
6150 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6151 globally or locally.
6153 This assignment gets effective in a newly opened input method.
6156 If the operation was successful, 0 is returned. Otherwise -1 is
6157 returned, and #merror_code is set to #MERROR_IM. */
6159 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6161 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6162 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6163 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6164 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6165 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6167 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6168 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6170 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6171 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6173 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6176 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6177 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6180 minput_assign_command_keys (MSymbol language, MSymbol name,
6181 MSymbol command, MPlist *keyseq)
6187 if (command == Mnil)
6188 MERROR (MERROR_IM, -1);
6193 if (! check_command_keyseq (keyseq))
6194 MERROR (MERROR_IM, -1);
6196 mplist_add (plist, Mplist, keyseq);
6201 ret = minput_config_command (language, name, command, keyseq);
6202 M17N_OBJECT_UNREF (keyseq);
6209 @brief Call a callback function
6211 The minput_callback () functions calls a callback function
6212 $COMMAND assigned for the input context $IC. The caller must set
6213 specific elements in $IC->plist if the callback function requires.
6216 If there exists a specified callback function, 0 is returned.
6217 Otherwise -1 is returned. By side effects, $IC->plist may be
6221 minput_callback (MInputContext *ic, MSymbol command)
6223 MInputCallbackFunc func;
6225 if (! ic->im->driver.callback_list)
6227 func = ((MInputCallbackFunc)
6228 mplist_get_func (ic->im->driver.callback_list, command));
6231 (func) (ic, command);
6238 /*** @addtogroup m17nDebug */
6244 @brief Dump an input method.
6246 The mdebug_dump_im () function prints the input method $IM in a
6247 human readable way to the stderr. $INDENT specifies how many
6248 columns to indent the lines but the first one.
6251 This function returns $IM. */
6253 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6255 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6256 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6259 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6262 mdebug_dump_im (MInputMethod *im, int indent)
6264 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6267 prefix = (char *) alloca (indent + 1);
6268 memset (prefix, 32, indent);
6269 prefix[indent] = '\0';
6271 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6272 msymbol_name (im->name));
6273 mdebug_dump_mtext (im_info->title, 0, 0);
6274 if (im->name != Mnil)
6278 MPLIST_DO (state, im_info->states)
6280 fprintf (stderr, "\n%s ", prefix);
6281 dump_im_state (MPLIST_VAL (state), indent + 2);
6284 fprintf (stderr, ")");