1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mpop = msymbol ("pop");
406 Mundo = msymbol ("undo");
407 Mcall = msymbol ("call");
408 Mshift = msymbol ("shift");
409 Mselect = msymbol ("select");
410 Mshow = msymbol ("show");
411 Mhide = msymbol ("hide");
412 Mcommit = msymbol ("commit");
413 Munhandle = msymbol ("unhandle");
414 Mset = msymbol ("set");
415 Madd = msymbol ("add");
416 Msub = msymbol ("sub");
417 Mmul = msymbol ("mul");
418 Mdiv = msymbol ("div");
419 Mequal = msymbol ("=");
420 Mless = msymbol ("<");
421 Mgreater = msymbol (">");
422 Mless_equal = msymbol ("<=");
423 Mgreater_equal = msymbol (">=");
424 Mcond = msymbol ("cond");
425 Mplus = msymbol ("+");
426 Mminus = msymbol ("-");
427 Mstar = msymbol ("*");
428 Mslash = msymbol ("/");
429 Mand = msymbol ("&");
431 Mnot = msymbol ("!");
433 Mat_reload = msymbol ("@reload");
435 Mcandidates_group_size = msymbol ("candidates-group-size");
436 Mcandidates_charset = msymbol ("candidates-charset");
438 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
439 Mcandidate_index = msymbol (" candidate-index");
441 Minit = msymbol ("init");
442 Mfini = msymbol ("fini");
444 Mdescription = msymbol ("description");
445 Mcommand = msymbol ("command");
446 Mvariable = msymbol ("variable");
447 Mglobal = msymbol ("global");
448 Mconfig = msymbol ("config");
449 M_gettext = msymbol ("_");
451 load_im_info_keys = mplist ();
452 mplist_add (load_im_info_keys, Mstate, Mnil);
453 mplist_push (load_im_info_keys, Mmap, Mnil);
455 im_info_list = mplist ();
456 im_config_list = im_custom_list = NULL;
457 im_custom_mdb = NULL;
458 update_custom_info ();
460 update_global_info ();
462 fully_initialized = 1;
465 #define MINPUT__INIT() \
467 if (! fully_initialized) \
468 fully_initialize (); \
473 marker_code (MSymbol sym, int surrounding)
479 name = MSYMBOL_NAME (sym);
480 return (name[0] != '@' ? -1
481 : (((name[1] >= '0' && name[1] <= '9')
482 || name[1] == '<' || name[1] == '>' || name[1] == '='
483 || name[1] == '[' || name[1] == ']'
485 && name[2] == '\0') ? name[1]
486 : (name[1] != '+' && name[1] != '-') ? -1
487 : (name[2] == '\0' || surrounding) ? name[1]
493 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
495 MPlist *plist = mplist__assq (ic_info->vars, var);
499 plist = MPLIST_PLIST (plist);
500 return MPLIST_NEXT (plist);
504 mplist_push (ic_info->vars, Mplist, plist);
505 M17N_OBJECT_UNREF (plist);
506 plist = mplist_add (plist, Msymbol, var);
507 plist = mplist_add (plist, Minteger, (void *) 0);
512 get_surrounding_text (MInputContext *ic, int len)
516 mplist_push (ic->plist, Minteger, (void *) len);
517 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
518 && MPLIST_MTEXT_P (ic->plist))
519 mt = MPLIST_MTEXT (ic->plist);
520 mplist_pop (ic->plist);
525 delete_surrounding_text (MInputContext *ic, int pos)
527 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
529 mplist_push (ic->plist, Minteger, (void *) pos);
530 minput_callback (ic, Minput_delete_surrounding_text);
531 mplist_pop (ic->plist);
534 M17N_OBJECT_UNREF (ic_info->preceding_text);
535 ic_info->preceding_text = NULL;
539 M17N_OBJECT_UNREF (ic_info->following_text);
540 ic_info->following_text = NULL;
545 get_preceding_char (MInputContext *ic, int pos)
547 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
551 if (pos && ic_info->preceding_text)
553 len = mtext_nchars (ic_info->preceding_text);
555 return mtext_ref_char (ic_info->preceding_text, len - pos);
557 mt = get_surrounding_text (ic, - pos);
560 len = mtext_nchars (mt);
561 if (ic_info->preceding_text)
563 if (mtext_nchars (ic_info->preceding_text) < len)
565 M17N_OBJECT_UNREF (ic_info->preceding_text);
566 ic_info->preceding_text = mt;
569 M17N_OBJECT_UNREF (mt);
572 ic_info->preceding_text = mt;
575 return mtext_ref_char (ic_info->preceding_text, len - pos);
579 get_following_char (MInputContext *ic, int pos)
581 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
585 if (ic_info->following_text)
587 len = mtext_nchars (ic_info->following_text);
589 return mtext_ref_char (ic_info->following_text, pos);
591 mt = get_surrounding_text (ic, pos + 1);
594 len = mtext_nchars (mt);
595 if (ic_info->following_text)
597 if (mtext_nchars (ic_info->following_text) < len)
599 M17N_OBJECT_UNREF (ic_info->following_text);
600 ic_info->following_text = mt;
603 M17N_OBJECT_UNREF (mt);
606 ic_info->following_text = mt;
609 return mtext_ref_char (ic_info->following_text, pos);
613 surrounding_pos (MSymbol sym)
619 name = MSYMBOL_NAME (sym);
621 && (name[1] == '-' || name[1] == '+')
622 && name[2] >= '1' && name[2] <= '9')
623 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
628 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
630 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
632 MText *preedit = ic->preedit;
633 int len = mtext_nchars (preedit);
637 if (MPLIST_INTEGER_P (arg))
638 return MPLIST_INTEGER (arg);
640 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
643 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
647 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
650 return ic_info->key_head;
651 if ((code == '-' || code == '+'))
653 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
657 pos = atoi (name + 1);
659 return get_preceding_char (ic, 0);
661 pos = ic->cursor_pos + pos;
663 pos = ic->cursor_pos + pos - 1;
666 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
667 return mtext_ref_char (ic->produced,
668 mtext_len (ic->produced) + pos);
669 return get_preceding_char (ic, - pos);
672 return get_following_char (ic, pos - len);
675 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
677 else if (code >= '0' && code <= '9')
679 else if (code == '=')
680 pos = ic->cursor_pos;
681 else if (code == '[')
682 pos = ic->cursor_pos - 1;
683 else if (code == ']')
684 pos = ic->cursor_pos + 1;
685 else if (code == '<')
687 else if (code == '>')
689 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
693 parse_expression (MPlist *plist)
697 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
699 if (! MPLIST_PLIST_P (plist))
701 plist = MPLIST_PLIST (plist);
702 op = MPLIST_SYMBOL (plist);
703 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
704 && op != Mand && op != Mor && op != Mnot
705 && op != Mless && op != Mgreater && op != Mequal
706 && op != Mless_equal && op != Mgreater_equal)
707 MERROR (MERROR_IM, -1);
708 MPLIST_DO (plist, MPLIST_NEXT (plist))
709 if (parse_expression (plist) < 0)
715 resolve_expression (MInputContext *ic, MPlist *plist)
720 if (MPLIST_INTEGER_P (plist))
721 return MPLIST_INTEGER (plist);
722 if (MPLIST_SYMBOL_P (plist))
723 return integer_value (ic, plist, NULL, 1);
724 if (! MPLIST_PLIST_P (plist))
726 plist = MPLIST_PLIST (plist);
727 if (! MPLIST_SYMBOL_P (plist))
729 op = MPLIST_SYMBOL (plist);
730 plist = MPLIST_NEXT (plist);
731 val = resolve_expression (ic, plist);
733 MPLIST_DO (plist, MPLIST_NEXT (plist))
734 val += resolve_expression (ic, plist);
735 else if (op == Mminus)
736 MPLIST_DO (plist, MPLIST_NEXT (plist))
737 val -= resolve_expression (ic, plist);
738 else if (op == Mstar)
739 MPLIST_DO (plist, MPLIST_NEXT (plist))
740 val *= resolve_expression (ic, plist);
741 else if (op == Mslash)
742 MPLIST_DO (plist, MPLIST_NEXT (plist))
743 val /= resolve_expression (ic, plist);
745 MPLIST_DO (plist, MPLIST_NEXT (plist))
746 val &= resolve_expression (ic, plist);
748 MPLIST_DO (plist, MPLIST_NEXT (plist))
749 val |= resolve_expression (ic, plist);
752 else if (op == Mless)
753 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
754 else if (op == Mequal)
755 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
756 else if (op == Mgreater)
757 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
758 else if (op == Mless_equal)
759 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
760 else if (op == Mgreater_equal)
761 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
765 /* Parse PLIST as an action list. PLIST should have this form:
766 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
767 Return 0 if successfully parsed, otherwise return -1. */
770 parse_action_list (MPlist *plist, MPlist *macros)
772 MPLIST_DO (plist, plist)
774 if (MPLIST_MTEXT_P (plist))
776 /* This is a short form of (insert MTEXT). */
777 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
778 MERROR (MERROR_IM, -1); */
780 else if (MPLIST_PLIST_P (plist)
781 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
782 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
786 /* This is a short form of (insert (GROUPS *)). */
787 MPLIST_DO (pl, MPLIST_PLIST (plist))
789 if (MPLIST_PLIST_P (pl))
793 MPLIST_DO (elt, MPLIST_PLIST (pl))
794 if (! MPLIST_MTEXT_P (elt)
795 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
796 MERROR (MERROR_IM, -1);
800 if (! MPLIST_MTEXT_P (pl)
801 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
802 MERROR (MERROR_IM, -1);
806 else if (MPLIST_INTEGER_P (plist))
808 int c = MPLIST_INTEGER (plist);
810 if (c < 0 || c > MCHAR_MAX)
811 MERROR (MERROR_IM, -1);
813 else if (MPLIST_PLIST_P (plist)
814 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
816 MPlist *pl = MPLIST_PLIST (plist);
817 MSymbol action_name = MPLIST_SYMBOL (pl);
819 pl = MPLIST_NEXT (pl);
821 if (action_name == Minsert)
823 if (MPLIST_MTEXT_P (pl))
825 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
826 MERROR (MERROR_IM, -1);
828 else if (MPLIST_PLIST_P (pl))
830 MPLIST_DO (pl, MPLIST_PLIST (pl))
832 if (MPLIST_PLIST_P (pl))
836 MPLIST_DO (elt, MPLIST_PLIST (pl))
837 if (! MPLIST_MTEXT_P (elt)
838 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
839 MERROR (MERROR_IM, -1);
843 if (! MPLIST_MTEXT_P (pl)
844 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
845 MERROR (MERROR_IM, -1);
849 else if (! MPLIST_SYMBOL_P (pl))
850 MERROR (MERROR_IM, -1);
852 else if (action_name == Mselect
853 || action_name == Mdelete
854 || action_name == Mmove)
856 if (parse_expression (pl) < 0)
859 else if (action_name == Mmark
860 || action_name == Mcall
861 || action_name == Mshift)
863 if (! MPLIST_SYMBOL_P (pl))
864 MERROR (MERROR_IM, -1);
866 else if (action_name == Mundo)
868 if (! MPLIST_TAIL_P (pl))
870 if (! MPLIST_SYMBOL_P (pl)
871 && ! MPLIST_INTEGER_P (pl))
872 MERROR (MERROR_IM, -1);
875 else if (action_name == Mpushback)
877 if (MPLIST_MTEXT_P (pl))
879 MText *mt = MPLIST_MTEXT (pl);
881 if (mtext_nchars (mt) != mtext_nbytes (mt))
882 MERROR (MERROR_IM, -1);
884 else if (MPLIST_PLIST_P (pl))
888 MPLIST_DO (p, MPLIST_PLIST (pl))
889 if (! MPLIST_SYMBOL_P (p))
890 MERROR (MERROR_IM, -1);
892 else if (! MPLIST_INTEGER_P (pl))
893 MERROR (MERROR_IM, -1);
895 else if (action_name == Mset || action_name == Madd
896 || action_name == Msub || action_name == Mmul
897 || action_name == Mdiv)
899 if (! MPLIST_SYMBOL_P (pl))
900 MERROR (MERROR_IM, -1);
901 if (parse_expression (MPLIST_NEXT (pl)) < 0)
904 else if (action_name == Mequal || action_name == Mless
905 || action_name == Mgreater || action_name == Mless_equal
906 || action_name == Mgreater_equal)
908 if (parse_expression (pl) < 0
909 || parse_expression (MPLIST_NEXT (pl)) < 0)
911 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
912 if (! MPLIST_PLIST_P (pl))
913 MERROR (MERROR_IM, -1);
914 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
915 MERROR (MERROR_IM, -1);
916 pl = MPLIST_NEXT (pl);
917 if (MPLIST_PLIST_P (pl)
918 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
919 MERROR (MERROR_IM, -1);
921 else if (action_name == Mshow || action_name == Mhide
922 || action_name == Mcommit || action_name == Munhandle
923 || action_name == Mpop)
925 else if (action_name == Mcond)
928 if (! MPLIST_PLIST_P (pl))
929 MERROR (MERROR_IM, -1);
931 else if (! macros || ! mplist_get (macros, action_name))
932 MERROR (MERROR_IM, -1);
934 else if (! MPLIST_SYMBOL_P (plist))
935 MERROR (MERROR_IM, -1);
942 resolve_command (MPlist *cmds, MSymbol command)
946 if (! cmds || ! (plist = mplist__assq (cmds, command)))
948 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
949 plist = MPLIST_NEXT (plist);
950 plist = MPLIST_NEXT (plist);
951 plist = MPLIST_NEXT (plist);
955 /* Load a translation into MAP from PLIST.
957 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
960 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
961 MPlist *branch_actions, MPlist *macros)
966 if (MPLIST_MTEXT_P (keylist))
968 MText *mt = MPLIST_MTEXT (keylist);
970 len = mtext_nchars (mt);
971 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
973 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
974 for (i = 0; i < len; i++)
975 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
981 if (MFAILP (MPLIST_PLIST_P (keylist)))
983 elt = MPLIST_PLIST (keylist);
984 len = MPLIST_LENGTH (elt);
985 if (MFAILP (len > 0))
987 keyseq = (MSymbol *) alloca (sizeof (int) * len);
988 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
990 if (MPLIST_INTEGER_P (elt))
992 int c = MPLIST_INTEGER (elt);
994 if (MFAILP (c >= 0 && c < 0x100))
996 keyseq[i] = one_char_symbol[c];
1000 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1002 keyseq[i] = MPLIST_SYMBOL (elt);
1007 for (i = 0; i < len; i++)
1009 MIMMap *deeper = NULL;
1012 deeper = mplist_get (map->submaps, keyseq[i]);
1014 map->submaps = mplist ();
1017 /* Fixme: It is better to make all deeper maps at once. */
1018 MSTRUCT_CALLOC (deeper, MERROR_IM);
1019 mplist_put (map->submaps, keyseq[i], deeper);
1024 /* We reach a terminal map. */
1025 if (map->map_actions
1026 || map->branch_actions)
1027 /* This map is already defined. We avoid overriding it. */
1030 if (! MPLIST_TAIL_P (map_actions))
1032 if (parse_action_list (map_actions, macros) < 0)
1033 MERROR (MERROR_IM, -1);
1034 map->map_actions = map_actions;
1038 map->branch_actions = branch_actions;
1039 M17N_OBJECT_REF (branch_actions);
1045 /* Load a branch from PLIST into MAP. PLIST has this form:
1046 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1049 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1052 MPlist *branch_actions;
1054 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1056 map_name = MPLIST_SYMBOL (plist);
1057 plist = MPLIST_NEXT (plist);
1058 if (MPLIST_TAIL_P (plist))
1059 branch_actions = NULL;
1060 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1063 branch_actions = plist;
1064 if (map_name == Mnil)
1066 map->branch_actions = branch_actions;
1068 M17N_OBJECT_REF (branch_actions);
1070 else if (map_name == Mt)
1072 map->map_actions = branch_actions;
1074 M17N_OBJECT_REF (branch_actions);
1076 else if (im_info->maps)
1078 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1079 if (! plist && im_info->configured_vars)
1081 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1083 if (p && MPLIST_PLIST_P (p))
1085 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1086 if (MPLIST_SYMBOL_P (p))
1087 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1092 MPLIST_DO (plist, plist)
1094 MPlist *keylist, *map_actions;
1096 if (! MPLIST_PLIST_P (plist))
1097 MERROR (MERROR_IM, -1);
1098 keylist = MPLIST_PLIST (plist);
1099 map_actions = MPLIST_NEXT (keylist);
1100 if (MPLIST_SYMBOL_P (keylist))
1102 MSymbol command = MPLIST_SYMBOL (keylist);
1105 if (MFAILP (command != Mat_reload))
1107 pl = resolve_command (im_info->configured_cmds, command);
1111 load_translation (map, pl, map_actions, branch_actions,
1115 load_translation (map, keylist, map_actions, branch_actions,
1124 /* Load a macro from PLIST into IM_INFO->macros.
1125 PLIST has this from:
1126 PLIST ::= ( MACRO-NAME ACTION * )
1127 IM_INFO->macros is a plist of macro names vs action list. */
1130 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1135 if (! MPLIST_SYMBOL_P (plist))
1136 MERROR (MERROR_IM, -1);
1137 name = MPLIST_SYMBOL (plist);
1138 plist = MPLIST_NEXT (plist);
1139 if (MPLIST_TAIL_P (plist)
1140 || parse_action_list (plist, im_info->macros) < 0)
1141 MERROR (MERROR_IM, -1);
1142 pl = mplist_get (im_info->macros, name);
1143 M17N_OBJECT_UNREF (pl);
1144 mplist_put (im_info->macros, name, plist);
1145 M17N_OBJECT_REF (plist);
1149 /* Load an external module from PLIST into IM_INFO->externals.
1150 PLIST has this form:
1151 PLIST ::= ( MODULE-NAME FUNCTION * )
1152 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1155 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1160 MIMExternalModule *external;
1164 if (MPLIST_MTEXT_P (plist))
1165 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1166 else if (MPLIST_SYMBOL_P (plist))
1167 module = MPLIST_SYMBOL (plist);
1168 module_file = alloca (strlen (MSYMBOL_NAME (module))
1169 + strlen (DLOPEN_SHLIB_EXT) + 1);
1170 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1172 handle = dlopen (module_file, RTLD_NOW);
1173 if (MFAILP (handle))
1175 fprintf (stderr, "%s\n", dlerror ());
1178 func_list = mplist ();
1179 MPLIST_DO (plist, MPLIST_NEXT (plist))
1181 if (! MPLIST_SYMBOL_P (plist))
1182 MERROR_GOTO (MERROR_IM, err_label);
1183 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1186 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1189 MSTRUCT_MALLOC (external, MERROR_IM);
1190 external->handle = handle;
1191 external->func_list = func_list;
1192 mplist_add (im_info->externals, module, external);
1197 M17N_OBJECT_UNREF (func_list);
1202 free_map (MIMMap *map, int top)
1207 M17N_OBJECT_UNREF (map->map_actions);
1210 MPLIST_DO (plist, map->submaps)
1211 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1212 M17N_OBJECT_UNREF (map->submaps);
1214 M17N_OBJECT_UNREF (map->branch_actions);
1219 free_state (void *object)
1221 MIMState *state = object;
1223 M17N_OBJECT_UNREF (state->title);
1225 free_map (state->map, 1);
1229 /** Load a state from PLIST into a newly allocated state object.
1230 PLIST has this form:
1231 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1232 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1233 Return the state object. */
1236 load_state (MInputMethodInfo *im_info, MPlist *plist)
1240 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1242 M17N_OBJECT (state, free_state, MERROR_IM);
1243 state->name = MPLIST_SYMBOL (plist);
1244 plist = MPLIST_NEXT (plist);
1245 if (MPLIST_MTEXT_P (plist))
1247 state->title = MPLIST_MTEXT (plist);
1248 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1249 Mlanguage, im_info->language);
1250 M17N_OBJECT_REF (state->title);
1251 plist = MPLIST_NEXT (plist);
1253 MSTRUCT_CALLOC (state->map, MERROR_IM);
1254 MPLIST_DO (plist, plist)
1256 if (MFAILP (MPLIST_PLIST_P (plist)))
1258 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1263 /* Return a newly created IM_INFO for an input method specified by
1264 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1266 static MInputMethodInfo *
1267 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1270 MInputMethodInfo *im_info;
1273 if (name == Mnil && extra == Mnil)
1274 language = Mt, extra = Mglobal;
1275 MSTRUCT_CALLOC (im_info, MERROR_IM);
1277 im_info->language = language;
1278 im_info->name = name;
1279 im_info->extra = extra;
1282 mplist_add (plist, Mplist, elt);
1283 M17N_OBJECT_UNREF (elt);
1284 elt = mplist_add (elt, Msymbol, language);
1285 elt = mplist_add (elt, Msymbol, name);
1286 elt = mplist_add (elt, Msymbol, extra);
1287 mplist_add (elt, Mt, im_info);
1293 fini_im_info (MInputMethodInfo *im_info)
1297 M17N_OBJECT_UNREF (im_info->cmds);
1298 M17N_OBJECT_UNREF (im_info->configured_cmds);
1299 M17N_OBJECT_UNREF (im_info->bc_cmds);
1300 M17N_OBJECT_UNREF (im_info->vars);
1301 M17N_OBJECT_UNREF (im_info->configured_vars);
1302 M17N_OBJECT_UNREF (im_info->bc_vars);
1303 M17N_OBJECT_UNREF (im_info->description);
1304 M17N_OBJECT_UNREF (im_info->title);
1305 if (im_info->states)
1307 MPLIST_DO (plist, im_info->states)
1309 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1311 M17N_OBJECT_UNREF (state);
1313 M17N_OBJECT_UNREF (im_info->states);
1316 if (im_info->macros)
1318 MPLIST_DO (plist, im_info->macros)
1319 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1320 M17N_OBJECT_UNREF (im_info->macros);
1323 if (im_info->externals)
1325 MPLIST_DO (plist, im_info->externals)
1327 MIMExternalModule *external = MPLIST_VAL (plist);
1329 dlclose (external->handle);
1330 M17N_OBJECT_UNREF (external->func_list);
1332 MPLIST_KEY (plist) = Mt;
1334 M17N_OBJECT_UNREF (im_info->externals);
1338 MPLIST_DO (plist, im_info->maps)
1340 MPlist *p = MPLIST_PLIST (plist);
1342 M17N_OBJECT_UNREF (p);
1344 M17N_OBJECT_UNREF (im_info->maps);
1351 free_im_info (MInputMethodInfo *im_info)
1353 fini_im_info (im_info);
1358 free_im_list (MPlist *plist)
1362 MPLIST_DO (pl, plist)
1364 MInputMethodInfo *im_info;
1366 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1367 im_info = MPLIST_VAL (elt);
1368 free_im_info (im_info);
1370 M17N_OBJECT_UNREF (plist);
1373 static MInputMethodInfo *
1374 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1376 if (name == Mnil && extra == Mnil)
1377 language = Mt, extra = Mglobal;
1378 while ((plist = mplist__assq (plist, language)))
1380 MPlist *elt = MPLIST_PLIST (plist);
1382 plist = MPLIST_NEXT (plist);
1383 elt = MPLIST_NEXT (elt);
1384 if (MPLIST_SYMBOL (elt) != name)
1386 elt = MPLIST_NEXT (elt);
1387 if (MPLIST_SYMBOL (elt) != extra)
1389 elt = MPLIST_NEXT (elt);
1390 return MPLIST_VAL (elt);
1395 static void load_im_info (MPlist *, MInputMethodInfo *);
1397 #define get_custom_info(im_info) \
1399 ? lookup_im_info (im_custom_list, (im_info)->language, \
1400 (im_info)->name, (im_info)->extra) \
1403 #define get_config_info(im_info) \
1405 ? lookup_im_info (im_config_list, (im_info)->language, \
1406 (im_info)->name, (im_info)->extra) \
1410 update_custom_info (void)
1416 if (mdatabase__check (im_custom_mdb) > 0)
1421 MDatabaseInfo *custom_dir_info;
1422 char custom_path[PATH_MAX + 1];
1424 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1425 if (! custom_dir_info->filename
1426 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1428 strcpy (custom_path, custom_dir_info->filename);
1429 strcat (custom_path, CUSTOM_FILE);
1430 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1436 free_im_list (im_custom_list);
1437 im_custom_list = NULL;
1439 plist = mdatabase_load (im_custom_mdb);
1442 im_custom_list = mplist ();
1444 MPLIST_DO (pl, plist)
1446 MSymbol language, name, extra;
1447 MInputMethodInfo *im_info;
1448 MPlist *im_data, *p;
1450 if (! MPLIST_PLIST_P (pl))
1452 p = MPLIST_PLIST (pl);
1453 im_data = MPLIST_NEXT (p);
1454 if (! MPLIST_PLIST_P (p))
1456 p = MPLIST_PLIST (p);
1457 if (! MPLIST_SYMBOL_P (p)
1458 || MPLIST_SYMBOL (p) != Minput_method)
1460 p = MPLIST_NEXT (p);
1461 if (! MPLIST_SYMBOL_P (p))
1463 language = MPLIST_SYMBOL (p);
1464 p = MPLIST_NEXT (p);
1465 if (! MPLIST_SYMBOL_P (p))
1467 name = MPLIST_SYMBOL (p);
1468 p = MPLIST_NEXT (p);
1469 if (MPLIST_TAIL_P (p))
1471 else if (MPLIST_SYMBOL_P (p))
1472 extra = MPLIST_SYMBOL (p);
1473 if (language == Mnil || (name == Mnil && extra == Mnil))
1475 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1476 load_im_info (im_data, im_info);
1478 M17N_OBJECT_UNREF (plist);
1483 update_global_info (void)
1489 int ret = mdatabase__check (global_info->mdb);
1493 fini_im_info (global_info);
1497 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1501 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1503 if (! global_info->mdb
1504 || ! (plist = mdatabase_load (global_info->mdb)))
1507 load_im_info (plist, global_info);
1508 M17N_OBJECT_UNREF (plist);
1513 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1514 and EXTRA. KEY, if not Mnil, tells which kind of information about
1515 the input method is necessary, and the returned IM_INFO may contain
1516 only that information. */
1518 static MInputMethodInfo *
1519 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1522 MInputMethodInfo *im_info;
1525 if (name == Mnil && extra == Mnil)
1526 language = Mt, extra = Mglobal;
1527 im_info = lookup_im_info (im_info_list, language, name, extra);
1530 if (key == Mnil ? im_info->states != NULL
1531 : key == Mcommand ? im_info->cmds != NULL
1532 : key == Mvariable ? im_info->vars != NULL
1533 : key == Mtitle ? im_info->title != NULL
1534 : key == Mdescription ? im_info->description != NULL
1536 /* IM_INFO already contains required information. */
1538 /* We have not yet loaded required information. */
1542 mdb = mdatabase_find (Minput_method, language, name, extra);
1545 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1550 plist = mdatabase_load (im_info->mdb);
1554 mplist_push (load_im_info_keys, key, Mt);
1555 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1556 mplist_pop (load_im_info_keys);
1560 MERROR (MERROR_IM, im_info);
1561 update_global_info ();
1562 load_im_info (plist, im_info);
1563 M17N_OBJECT_UNREF (plist);
1566 if (! im_info->cmds)
1567 im_info->cmds = mplist ();
1568 if (! im_info->vars)
1569 im_info->vars = mplist ();
1571 if (! im_info->title
1572 && (key == Mnil || key == Mtitle))
1573 im_info->title = (name == Mnil ? mtext ()
1574 : mtext_from_data (MSYMBOL_NAME (name),
1575 MSYMBOL_NAMELEN (name),
1576 MTEXT_FORMAT_US_ASCII));
1580 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1581 If updated, but got unloadable, return -1. Otherwise, update
1582 contents of IM_INFO from the new database, and return 1. */
1585 reload_im_info (MInputMethodInfo *im_info)
1590 update_custom_info ();
1591 update_global_info ();
1592 check = mdatabase__check (im_info->mdb);
1595 plist = mdatabase_load (im_info->mdb);
1598 fini_im_info (im_info);
1599 load_im_info (plist, im_info);
1600 M17N_OBJECT_UNREF (plist);
1601 if (! im_info->cmds)
1602 im_info->cmds = mplist ();
1603 if (! im_info->vars)
1604 im_info->vars = mplist ();
1605 if (! im_info->title)
1607 MSymbol name = im_info->name;
1609 im_info->title = (name == Mnil ? mtext ()
1610 : mtext_from_data (MSYMBOL_NAME (name),
1611 MSYMBOL_NAMELEN (name),
1612 MTEXT_FORMAT_US_ASCII));
1617 static MInputMethodInfo *
1618 get_im_info_by_tags (MPlist *plist)
1623 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1624 i++, plist = MPLIST_NEXT (plist))
1625 tag[i] = MPLIST_SYMBOL (plist);
1630 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1635 check_description (MPlist *plist)
1639 if (MPLIST_MTEXT_P (plist))
1641 if (MPLIST_PLIST_P (plist))
1643 MPlist *pl = MPLIST_PLIST (plist);
1645 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1647 pl =MPLIST_NEXT (pl);
1648 if (MFAILP (MPLIST_MTEXT_P (pl)))
1650 mt = MPLIST_MTEXT (pl);
1651 M17N_OBJECT_REF (mt);
1654 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1656 if (translated == (char *) MTEXT_DATA (mt))
1657 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1658 if (translated != (char *) MTEXT_DATA (mt))
1660 M17N_OBJECT_UNREF (mt);
1661 mt = mtext__from_data (translated, strlen (translated),
1662 MTEXT_FORMAT_UTF_8, 1);
1666 mplist_set (plist, Mtext, mt);
1667 M17N_OBJECT_UNREF (mt);
1670 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1676 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1680 check_command_keyseq (MPlist *keyseq)
1682 if (MPLIST_PLIST_P (keyseq))
1684 MPlist *p = MPLIST_PLIST (keyseq);
1687 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1691 if (MPLIST_MTEXT_P (keyseq))
1693 MText *mt = MPLIST_MTEXT (keyseq);
1696 for (i = 0; i < mtext_nchars (mt); i++)
1697 if (mtext_ref_char (mt, i) >= 256)
1704 /* Load command defitions from PLIST into IM_INFO->cmds.
1706 PLIST is well-formed and has this form;
1707 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1708 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1709 M-text or a plist of symbols.
1711 The returned list has the same form, but for each element...
1713 (1) If DESCRIPTION and the rest are omitted, the element is not
1714 stored in the returned list.
1716 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1717 description in global_info->cmds (if any). */
1720 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1724 im_info->cmds = tail = mplist ();
1726 MPLIST_DO (plist, MPLIST_NEXT (plist))
1728 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1731 if (MFAILP (MPLIST_PLIST_P (plist)))
1733 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1734 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1736 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1737 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1739 if (MFAILP (im_info != global_info))
1740 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1744 if (! check_description (p))
1745 mplist_set (p, Msymbol, Mnil);
1746 p = MPLIST_NEXT (p);
1747 while (! MPLIST_TAIL_P (p))
1749 if (MFAILP (check_command_keyseq (p)))
1750 mplist__pop_unref (p);
1752 p = MPLIST_NEXT (p);
1755 tail = mplist_add (tail, Mplist, pl);
1760 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1761 MPlist *config_cmds)
1763 MPlist *global = NULL, *custom = NULL, *config = NULL;
1764 MSymbol name = MPLIST_SYMBOL (plist);
1766 MPlist *description, *keyseq;
1768 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1769 global = MPLIST_NEXT (MPLIST_PLIST (global));
1771 plist = MPLIST_NEXT (plist);
1772 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1774 description = plist;
1775 plist = MPLIST_NEXT (plist);
1779 description = global;
1780 if (! MPLIST_TAIL_P (plist))
1781 plist = MPLIST_NEXT (plist);
1783 if (MPLIST_TAIL_P (plist) && global)
1785 keyseq = MPLIST_NEXT (global);
1786 status = Minherited;
1794 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1796 status = Mconfigured;
1797 config = MPLIST_NEXT (MPLIST_PLIST (config));
1798 if (! MPLIST_TAIL_P (config))
1801 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1803 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1805 if (MPLIST_TAIL_P (this_keyseq))
1806 mplist__pop_unref (custom);
1809 status = Mcustomized;
1810 keyseq = this_keyseq;
1815 mplist_add (plist, Msymbol, name);
1817 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1819 mplist_add (plist, Msymbol, Mnil);
1820 mplist_add (plist, Msymbol, status);
1821 mplist__conc (plist, keyseq);
1826 config_all_commands (MInputMethodInfo *im_info)
1828 MPlist *global_cmds, *custom_cmds, *config_cmds;
1829 MInputMethodInfo *temp;
1830 MPlist *tail, *plist;
1832 M17N_OBJECT_UNREF (im_info->configured_cmds);
1834 if (MPLIST_TAIL_P (im_info->cmds)
1838 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1839 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1840 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1842 im_info->configured_cmds = tail = mplist ();
1843 MPLIST_DO (plist, im_info->cmds)
1845 MPlist *pl = config_command (MPLIST_PLIST (plist),
1846 global_cmds, custom_cmds, config_cmds);
1849 tail = mplist_add (tail, Mplist, pl);
1850 M17N_OBJECT_UNREF (pl);
1855 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1856 valid, return 0 if not. */
1859 check_variable_value (MPlist *val, MPlist *global)
1861 MSymbol type = MPLIST_KEY (val);
1862 MPlist *valids = MPLIST_NEXT (val);
1864 if (type != Minteger && type != Mtext && type != Msymbol)
1868 if (MPLIST_KEY (global) != Mt
1869 && MPLIST_KEY (global) != MPLIST_KEY (val))
1871 if (MPLIST_TAIL_P (valids))
1872 valids = MPLIST_NEXT (global);
1874 if (MPLIST_TAIL_P (valids))
1877 if (type == Minteger)
1879 int n = MPLIST_INTEGER (val);
1881 MPLIST_DO (valids, valids)
1883 if (MPLIST_INTEGER_P (valids))
1885 if (n == MPLIST_INTEGER (valids))
1888 else if (MPLIST_PLIST_P (valids))
1890 MPlist *p = MPLIST_PLIST (valids);
1891 int min_bound, max_bound;
1893 if (! MPLIST_INTEGER_P (p))
1894 MERROR (MERROR_IM, 0);
1895 min_bound = MPLIST_INTEGER (p);
1896 p = MPLIST_NEXT (p);
1897 if (! MPLIST_INTEGER_P (p))
1898 MERROR (MERROR_IM, 0);
1899 max_bound = MPLIST_INTEGER (p);
1900 if (n >= min_bound && n <= max_bound)
1905 else if (type == Msymbol)
1907 MSymbol sym = MPLIST_SYMBOL (val);
1909 MPLIST_DO (valids, valids)
1911 if (! MPLIST_SYMBOL_P (valids))
1912 MERROR (MERROR_IM, 0);
1913 if (sym == MPLIST_SYMBOL (valids))
1919 MText *mt = MPLIST_MTEXT (val);
1921 MPLIST_DO (valids, valids)
1923 if (! MPLIST_MTEXT_P (valids))
1924 MERROR (MERROR_IM, 0);
1925 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1930 return (! MPLIST_TAIL_P (valids));
1933 /* Load variable defitions from PLIST into IM_INFO->vars.
1935 PLIST is well-formed and has this form;
1936 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1938 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1940 The returned list has the same form, but for each element...
1942 (1) If DESCRIPTION and the rest are omitted, the element is not
1943 stored in the returned list.
1945 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1946 description in global_info->vars (if any). */
1949 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1951 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1952 ? global_info->vars : NULL);
1955 im_info->vars = tail = mplist ();
1956 MPLIST_DO (plist, MPLIST_NEXT (plist))
1960 if (MFAILP (MPLIST_PLIST_P (plist)))
1962 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1963 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1965 if (im_info == global_info)
1967 /* Loading a global variable. */
1968 p = MPLIST_NEXT (pl);
1969 if (MPLIST_TAIL_P (p))
1970 mplist_add (p, Msymbol, Mnil);
1973 if (! check_description (p))
1974 mplist_set (p, Msymbol, Mnil);
1975 p = MPLIST_NEXT (p);
1976 if (MFAILP (! MPLIST_TAIL_P (p)
1977 && check_variable_value (p, NULL)))
1978 mplist_set (p, Mt, NULL);
1981 else if (im_info->mdb)
1983 /* Loading a local variable. */
1984 MSymbol name = MPLIST_SYMBOL (pl);
1985 MPlist *global = NULL;
1988 && (p = mplist__assq (global_vars, name)))
1990 /* P ::= ((NAME DESC ...) ...) */
1991 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1992 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1993 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1996 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1997 if (! MPLIST_TAIL_P (p))
1999 if (! check_description (p))
2000 mplist_set (p, Msymbol, Mnil);
2001 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2002 if (MFAILP (! MPLIST_TAIL_P (p)))
2003 mplist_set (p, Mt, NULL);
2006 MPlist *valid_values = MPLIST_NEXT (p);
2008 if (! MPLIST_TAIL_P (valid_values)
2009 ? MFAILP (check_variable_value (p, NULL))
2010 : global && MFAILP (check_variable_value (p, global)))
2011 mplist_set (p, Mt, NULL);
2017 /* Loading a variable customization. */
2018 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2019 if (MFAILP (! MPLIST_TAIL_P (p)))
2021 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2022 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2023 || MPLIST_MTEXT_P (p)))
2026 tail = mplist_add (tail, Mplist, pl);
2031 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2032 MPlist *config_vars)
2034 MPlist *global = NULL, *custom = NULL, *config = NULL;
2035 MSymbol name = MPLIST_SYMBOL (plist);
2037 MPlist *description = NULL, *value, *valids;
2041 global = mplist__assq (global_vars, name);
2043 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2046 plist = MPLIST_NEXT (plist);
2047 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2048 description = plist;
2050 description = global;
2052 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2054 if (MPLIST_TAIL_P (plist))
2056 /* Inherit from global (if any). */
2060 if (MPLIST_KEY (value) == Mt)
2062 valids = MPLIST_NEXT (global);
2063 status = Minherited;
2075 value = plist = MPLIST_NEXT (plist);
2076 valids = MPLIST_NEXT (value);
2077 if (MPLIST_KEY (value) == Mt)
2079 if (! MPLIST_TAIL_P (valids))
2082 valids = MPLIST_NEXT (global);
2086 if (config_vars && (config = mplist__assq (config_vars, name)))
2088 status = Mconfigured;
2089 config = MPLIST_NEXT (MPLIST_PLIST (config));
2090 if (! MPLIST_TAIL_P (config))
2093 if (MFAILP (check_variable_value (value, global ? global : plist)))
2097 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2099 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2101 if (MPLIST_TAIL_P (this_value))
2102 mplist__pop_unref (custom);
2106 if (MFAILP (check_variable_value (value, global ? global : plist)))
2108 status = Mcustomized;
2113 mplist_add (plist, Msymbol, name);
2115 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2117 mplist_add (plist, Msymbol, Mnil);
2118 mplist_add (plist, Msymbol, status);
2120 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2122 mplist_add (plist, Mt, NULL);
2123 if (valids && ! MPLIST_TAIL_P (valids))
2124 mplist__conc (plist, valids);
2128 /* Return a configured variable definition list based on
2129 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2130 get it from global_info->vars. */
2133 config_all_variables (MInputMethodInfo *im_info)
2135 MPlist *global_vars, *custom_vars, *config_vars;
2136 MInputMethodInfo *temp;
2137 MPlist *tail, *plist;
2139 M17N_OBJECT_UNREF (im_info->configured_vars);
2141 if (MPLIST_TAIL_P (im_info->vars)
2145 global_vars = im_info != global_info ? global_info->vars : NULL;
2146 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2147 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2149 im_info->configured_vars = tail = mplist ();
2150 MPLIST_DO (plist, im_info->vars)
2152 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2153 global_vars, custom_vars, config_vars);
2156 tail = mplist_add (tail, Mplist, pl);
2157 M17N_OBJECT_UNREF (pl);
2162 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2163 CONFIG contains configuration information of the input method. */
2166 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2170 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2172 load_commands (im_info, MPLIST_PLIST (pl));
2173 config_all_commands (im_info);
2174 pl = mplist_pop (pl);
2175 M17N_OBJECT_UNREF (pl);
2178 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2180 load_variables (im_info, MPLIST_PLIST (pl));
2181 config_all_variables (im_info);
2182 pl = mplist_pop (pl);
2183 M17N_OBJECT_UNREF (pl);
2186 MPLIST_DO (plist, plist)
2187 if (MPLIST_PLIST_P (plist))
2189 MPlist *elt = MPLIST_PLIST (plist);
2192 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2194 key = MPLIST_SYMBOL (elt);
2199 elt = MPLIST_NEXT (elt);
2200 if (MFAILP (MPLIST_MTEXT_P (elt)))
2202 im_info->title = MPLIST_MTEXT (elt);
2203 M17N_OBJECT_REF (im_info->title);
2205 else if (key == Mmap)
2207 pl = mplist__from_alist (MPLIST_NEXT (elt));
2210 if (! im_info->maps)
2214 mplist__conc (im_info->maps, pl);
2215 M17N_OBJECT_UNREF (pl);
2218 else if (key == Mmacro)
2220 if (! im_info->macros)
2221 im_info->macros = mplist ();
2222 MPLIST_DO (elt, MPLIST_NEXT (elt))
2224 if (MFAILP (MPLIST_PLIST_P (elt)))
2226 load_macros (im_info, MPLIST_PLIST (elt));
2229 else if (key == Mmodule)
2231 if (! im_info->externals)
2232 im_info->externals = mplist ();
2233 MPLIST_DO (elt, MPLIST_NEXT (elt))
2235 if (MFAILP (MPLIST_PLIST_P (elt)))
2237 load_external_module (im_info, MPLIST_PLIST (elt));
2240 else if (key == Mstate)
2242 MPLIST_DO (elt, MPLIST_NEXT (elt))
2246 if (MFAILP (MPLIST_PLIST_P (elt)))
2248 pl = MPLIST_PLIST (elt);
2249 if (! im_info->states)
2250 im_info->states = mplist ();
2251 state = load_state (im_info, MPLIST_PLIST (elt));
2254 mplist_put (im_info->states, state->name, state);
2257 else if (key == Minclude)
2259 /* elt ::= include (tag1 tag2 ...) key item ... */
2261 MInputMethodInfo *temp;
2263 elt = MPLIST_NEXT (elt);
2264 if (MFAILP (MPLIST_PLIST_P (elt)))
2266 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2269 elt = MPLIST_NEXT (elt);
2270 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2272 key = MPLIST_SYMBOL (elt);
2273 elt = MPLIST_NEXT (elt);
2276 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2278 if (! im_info->maps)
2279 im_info->maps = mplist ();
2280 MPLIST_DO (pl, temp->maps)
2282 p = MPLIST_VAL (pl);
2283 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2284 M17N_OBJECT_REF (p);
2287 else if (key == Mmacro)
2289 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2291 if (! im_info->macros)
2292 im_info->macros = mplist ();
2293 MPLIST_DO (pl, temp->macros)
2295 p = MPLIST_VAL (pl);
2296 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2297 M17N_OBJECT_REF (p);
2300 else if (key == Mstate)
2302 if (! temp->states || MPLIST_TAIL_P (temp->states))
2304 if (! im_info->states)
2305 im_info->states = mplist ();
2306 MPLIST_DO (pl, temp->states)
2308 MIMState *state = MPLIST_VAL (pl);
2310 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2311 M17N_OBJECT_REF (state);
2315 else if (key == Mdescription)
2317 if (im_info->description)
2319 elt = MPLIST_NEXT (elt);
2320 if (! check_description (elt))
2322 im_info->description = MPLIST_MTEXT (elt);
2323 M17N_OBJECT_REF (im_info->description);
2326 im_info->tick = time (NULL);
2331 static int take_action_list (MInputContext *ic, MPlist *action_list);
2332 static void preedit_commit (MInputContext *ic, int need_prefix);
2335 shift_state (MInputContext *ic, MSymbol state_name)
2337 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2338 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2339 MIMState *orig_state = ic_info->state, *state;
2341 /* Find a state to shift to. If not found, shift to the initial
2343 if (state_name == Mt)
2345 if (! ic_info->prev_state)
2347 state = ic_info->prev_state;
2349 else if (state_name == Mnil)
2351 state = (MIMState *) MPLIST_VAL (im_info->states);
2355 state = (MIMState *) mplist_get (im_info->states, state_name);
2357 state = (MIMState *) MPLIST_VAL (im_info->states);
2363 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2364 MSYMBOL_NAME (orig_state->name),
2365 MSYMBOL_NAME (state->name));
2367 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2370 /* Enter the new state. */
2371 ic_info->state = state;
2372 ic_info->map = state->map;
2373 ic_info->state_key_head = ic_info->key_head;
2374 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2376 /* We have shifted to the initial state. */
2377 preedit_commit (ic, 0);
2378 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2379 ic_info->state_pos = ic->cursor_pos;
2380 if (state != orig_state)
2382 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2384 /* Shifted to the initial state. */
2385 ic_info->prev_state = NULL;
2386 M17N_OBJECT_UNREF (ic_info->vars_saved);
2387 ic_info->vars_saved = mplist_copy (ic_info->vars);
2390 ic_info->prev_state = orig_state;
2393 ic->status = state->title;
2395 ic->status = im_info->title;
2396 ic->status_changed = 1;
2397 if (ic_info->map == ic_info->state->map
2398 && ic_info->map->map_actions)
2400 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2401 MSYMBOL_NAME (state->name));
2402 take_action_list (ic, ic_info->map->map_actions);
2407 /* Find a candidate group that contains a candidate number INDEX from
2408 PLIST. Set START_INDEX to the first candidate number of the group,
2409 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2410 candidate group number if they are non-NULL. If INDEX is -1, find
2411 the last candidate group. */
2414 find_candidates_group (MPlist *plist, int index,
2415 int *start_index, int *end_index, int *group_index)
2417 int i = 0, gidx = 0, len;
2419 MPLIST_DO (plist, plist)
2421 if (MPLIST_MTEXT_P (plist))
2422 len = mtext_nchars (MPLIST_MTEXT (plist));
2424 len = mplist_length (MPLIST_PLIST (plist));
2425 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2431 *end_index = i + len;
2433 *group_index = gidx;
2442 /* Adjust markers for the change of preedit text.
2443 If FROM == TO, the change is insertion of INS chars.
2444 If FROM < TO and INS == 0, the change is deletion of the range.
2445 If FROM < TO and INS > 0, the change is replacement. */
2448 adjust_markers (MInputContext *ic, int from, int to, int ins)
2450 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2455 MPLIST_DO (markers, ic_info->markers)
2456 if (MPLIST_INTEGER (markers) > from)
2457 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2458 if (ic->cursor_pos >= from)
2459 ic->cursor_pos += ins;
2463 MPLIST_DO (markers, ic_info->markers)
2465 if (MPLIST_INTEGER (markers) >= to)
2466 MPLIST_VAL (markers)
2467 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2468 else if (MPLIST_INTEGER (markers) > from)
2469 MPLIST_VAL (markers) = (void *) from;
2471 if (ic->cursor_pos >= to)
2472 ic->cursor_pos += ins - (to - from);
2473 else if (ic->cursor_pos > from)
2474 ic->cursor_pos = from;
2480 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2482 int nchars = mt ? mtext_nchars (mt) : 1;
2486 mtext_ins (ic->preedit, pos, mt);
2487 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2491 mtext_ins_char (ic->preedit, pos, c, 1);
2493 MDEBUG_PRINT1 ("('%c')", c);
2495 MDEBUG_PRINT1 ("(U+%04X)", c);
2497 adjust_markers (ic, pos, pos, nchars);
2498 ic->preedit_changed = 1;
2503 preedit_delete (MInputContext *ic, int from, int to)
2505 mtext_del (ic->preedit, from, to);
2506 adjust_markers (ic, from, to, 0);
2507 ic->preedit_changed = 1;
2511 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2515 mtext_del (ic->preedit, from, to);
2518 mtext_ins (ic->preedit, from, mt);
2519 ins = mtext_nchars (mt);
2523 mtext_ins_char (ic->preedit, from, c, 1);
2526 adjust_markers (ic, from, to, ins);
2527 ic->preedit_changed = 1;
2532 preedit_commit (MInputContext *ic, int need_prefix)
2534 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2535 int preedit_len = mtext_nchars (ic->preedit);
2537 if (preedit_len > 0)
2541 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2542 Mcandidate_list, NULL, 0);
2543 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2544 Mcandidate_index, NULL, 0);
2545 mtext_cat (ic->produced, ic->preedit);
2551 MDEBUG_PRINT1 ("\n [IM] [%s]",
2552 MSYMBOL_NAME (ic_info->state->name));
2553 MDEBUG_PRINT (" (commit");
2554 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2555 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2559 mtext_reset (ic->preedit);
2560 mtext_reset (ic_info->preedit_saved);
2561 MPLIST_DO (p, ic_info->markers)
2563 ic->cursor_pos = ic_info->state_pos = 0;
2564 ic->preedit_changed = 1;
2565 ic_info->commit_key_head = ic_info->key_head;
2567 if (ic->candidate_list)
2569 M17N_OBJECT_UNREF (ic->candidate_list);
2570 ic->candidate_list = NULL;
2571 ic->candidate_index = 0;
2572 ic->candidate_from = ic->candidate_to = 0;
2573 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2574 if (ic->candidate_show)
2576 ic->candidate_show = 0;
2577 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2583 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2585 int code = marker_code (sym, 0);
2587 if (mt && (code == '[' || code == ']'))
2591 if (code == '[' && current > 0)
2593 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2597 else if (code == ']' && current < mtext_nchars (mt))
2599 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2605 return (code == '<' ? 0
2606 : code == '>' ? limit
2607 : code == '-' ? current - 1
2608 : code == '+' ? current + 1
2609 : code == '=' ? current
2610 : code - '0' > limit ? limit
2614 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2618 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2620 int from = mtext_property_start (prop);
2621 int to = mtext_property_end (prop);
2623 MPlist *candidate_list = mtext_property_value (prop);
2624 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2626 int ingroup_index = idx - start;
2629 candidate_list = mplist_copy (candidate_list);
2630 if (MPLIST_MTEXT_P (group))
2632 mt = MPLIST_MTEXT (group);
2633 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2641 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2642 i++, plist = MPLIST_NEXT (plist));
2643 mt = MPLIST_MTEXT (plist);
2644 preedit_replace (ic, from, to, mt, 0);
2645 to = from + mtext_nchars (mt);
2647 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2648 M17N_OBJECT_UNREF (candidate_list);
2649 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2650 ic->cursor_pos = to;
2654 get_select_charset (MInputContextInfo * ic_info)
2656 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2659 if (! MPLIST_VAL (plist))
2661 sym = MPLIST_SYMBOL (plist);
2664 return MCHARSET (sym);
2668 adjust_candidates (MPlist *plist, MCharset *charset)
2672 /* plist ::= MTEXT ... | PLIST ... */
2673 plist = mplist_copy (plist);
2674 if (MPLIST_MTEXT_P (plist))
2677 while (! MPLIST_TAIL_P (pl))
2679 /* pl ::= MTEXT ... */
2680 MText *mt = MPLIST_MTEXT (pl);
2684 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2686 c = mtext_ref_char (mt, i);
2687 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2691 mt = mtext_dup (mt);
2692 mplist_set (pl, Mtext, mt);
2693 M17N_OBJECT_UNREF (mt);
2696 mtext_del (mt, i, i + 1);
2699 if (mtext_len (mt) > 0)
2700 pl = MPLIST_NEXT (pl);
2704 M17N_OBJECT_UNREF (mt);
2708 else /* MPLIST_PLIST_P (plist) */
2711 while (! MPLIST_TAIL_P (pl))
2713 /* pl ::= (MTEXT ...) ... */
2714 MPlist *p = MPLIST_PLIST (pl);
2716 /* p ::= MTEXT ... */
2720 while (! MPLIST_TAIL_P (p0))
2722 MText *mt = MPLIST_MTEXT (p0);
2725 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2727 c = mtext_ref_char (mt, i);
2728 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2733 p0 = MPLIST_NEXT (p0);
2740 p = mplist_copy (p);
2741 mplist_set (pl, Mplist, p);
2742 M17N_OBJECT_UNREF (p);
2746 p0 = MPLIST_NEXT (p0);
2749 M17N_OBJECT_UNREF (mt);
2752 if (! MPLIST_TAIL_P (p))
2753 pl = MPLIST_NEXT (pl);
2757 M17N_OBJECT_UNREF (p);
2761 if (MPLIST_TAIL_P (plist))
2763 M17N_OBJECT_UNREF (plist);
2770 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2772 MCharset *charset = get_select_charset (ic_info);
2777 plist = resolve_variable (ic_info, Mcandidates_group_size);
2778 column = MPLIST_INTEGER (plist);
2780 plist = MPLIST_PLIST (args);
2782 plist = adjust_candidates (plist, charset);
2784 if (plist && column > 0)
2786 if (MPLIST_MTEXT_P (plist))
2788 MText *mt = MPLIST_MTEXT (plist);
2789 MPlist *next = MPLIST_NEXT (plist);
2791 if (MPLIST_TAIL_P (next))
2792 M17N_OBJECT_REF (mt);
2795 mt = mtext_dup (mt);
2796 while (! MPLIST_TAIL_P (next))
2798 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2799 next = MPLIST_NEXT (next);
2803 M17N_OBJECT_UNREF (plist);
2805 len = mtext_nchars (mt);
2807 mplist_add (plist, Mtext, mt);
2810 for (i = 0; i < len; i += column)
2812 int to = (i + column < len ? i + column : len);
2813 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2815 mplist_add (plist, Mtext, sub);
2816 M17N_OBJECT_UNREF (sub);
2819 M17N_OBJECT_UNREF (mt);
2821 else if (! MPLIST_TAIL_P (plist))
2823 MPlist *tail = plist;
2824 MPlist *new = mplist ();
2825 MPlist *this = mplist ();
2828 MPLIST_DO (tail, tail)
2830 MPlist *p = MPLIST_PLIST (tail);
2834 MText *mt = MPLIST_MTEXT (p);
2836 if (count == column)
2838 mplist_add (new, Mplist, this);
2839 M17N_OBJECT_UNREF (this);
2843 mplist_add (this, Mtext, mt);
2847 mplist_add (new, Mplist, this);
2848 M17N_OBJECT_UNREF (this);
2849 mplist_set (plist, Mnil, NULL);
2850 MPLIST_DO (tail, new)
2852 MPlist *elt = MPLIST_PLIST (tail);
2854 mplist_add (plist, Mplist, elt);
2856 M17N_OBJECT_UNREF (new);
2865 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2867 MPlist *action = NULL;
2871 if (MPLIST_SYMBOL_P (action_list))
2873 MSymbol var = MPLIST_SYMBOL (action_list);
2876 MPLIST_DO (p, ic_info->vars)
2877 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2879 if (MPLIST_TAIL_P (p))
2881 action = MPLIST_NEXT (MPLIST_PLIST (p));
2882 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2885 if (MPLIST_PLIST_P (action_list))
2887 action = MPLIST_PLIST (action_list);
2888 if (MPLIST_SYMBOL_P (action))
2890 name = MPLIST_SYMBOL (action);
2891 args = MPLIST_NEXT (action);
2893 && MPLIST_PLIST_P (args))
2894 mplist_set (action, Msymbol, M_candidates);
2896 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2899 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2900 mplist_push (action, Msymbol, M_candidates);
2901 mplist_set (action_list, Mplist, action);
2902 M17N_OBJECT_UNREF (action);
2905 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2908 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2909 mplist_push (action, Msymbol, Minsert);
2910 mplist_set (action_list, Mplist, action);
2911 M17N_OBJECT_UNREF (action);
2916 /* Perform list of actions in ACTION_LIST for the current input
2917 context IC. If unhandle action was not performed, return 0.
2918 Otherwise, return -1. */
2921 take_action_list (MInputContext *ic, MPlist *action_list)
2923 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2924 MPlist *candidate_list = ic->candidate_list;
2925 int candidate_index = ic->candidate_index;
2926 int candidate_show = ic->candidate_show;
2927 MTextProperty *prop;
2929 MPLIST_DO (action_list, action_list)
2931 MPlist *action = regularize_action (action_list, ic_info);
2937 name = MPLIST_SYMBOL (action);
2938 args = MPLIST_NEXT (action);
2940 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2941 if (name == Minsert)
2943 if (MPLIST_SYMBOL_P (args))
2945 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2946 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2949 if (MPLIST_MTEXT_P (args))
2950 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2951 else /* MPLIST_INTEGER_P (args)) */
2952 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2954 else if (name == M_candidates)
2956 MPlist *plist = get_candidate_list (ic_info, args);
2959 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2961 if (MPLIST_MTEXT_P (plist))
2963 preedit_insert (ic, ic->cursor_pos, NULL,
2964 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2967 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2971 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2973 preedit_insert (ic, ic->cursor_pos, mt, 0);
2974 len = mtext_nchars (mt);
2976 plist = mplist_copy (plist);
2977 mtext_put_prop (ic->preedit,
2978 ic->cursor_pos - len, ic->cursor_pos,
2979 Mcandidate_list, plist);
2980 M17N_OBJECT_UNREF (plist);
2981 mtext_put_prop (ic->preedit,
2982 ic->cursor_pos - len, ic->cursor_pos,
2983 Mcandidate_index, (void *) 0);
2985 else if (name == Mselect)
2988 int code, idx, gindex;
2989 int pos = ic->cursor_pos;
2991 int idx_decided = 0;
2994 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2997 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2998 group = find_candidates_group (mtext_property_value (prop), idx,
2999 &start, &end, &gindex);
3000 if (MPLIST_SYMBOL_P (args))
3002 code = marker_code (MPLIST_SYMBOL (args), 0);
3005 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3006 if (! MPLIST_INTEGER_P (args))
3008 idx = start + MPLIST_INTEGER (args);
3009 if (idx < start || idx >= end)
3017 if (code != '[' && code != ']')
3022 ? new_index (NULL, ic->candidate_index - start,
3023 end - start - 1, MPLIST_SYMBOL (args),
3025 : MPLIST_INTEGER (args)));
3028 find_candidates_group (mtext_property_value (prop), -1,
3033 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3038 int ingroup_index = idx - start;
3041 group = mtext_property_value (prop);
3042 len = mplist_length (group);
3055 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3056 idx += (MPLIST_MTEXT_P (group)
3057 ? mtext_nchars (MPLIST_MTEXT (group))
3058 : mplist_length (MPLIST_PLIST (group)));
3059 len = (MPLIST_MTEXT_P (group)
3060 ? mtext_nchars (MPLIST_MTEXT (group))
3061 : mplist_length (MPLIST_PLIST (group)));
3062 if (ingroup_index >= len)
3063 ingroup_index = len - 1;
3064 idx += ingroup_index;
3066 update_candidate (ic, prop, idx);
3067 MDEBUG_PRINT1 ("(%d)", idx);
3069 else if (name == Mshow)
3070 ic->candidate_show = 1;
3071 else if (name == Mhide)
3072 ic->candidate_show = 0;
3073 else if (name == Mdelete)
3075 int len = mtext_nchars (ic->preedit);
3079 if (MPLIST_SYMBOL_P (args)
3080 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3082 to = ic->cursor_pos + pos;
3085 delete_surrounding_text (ic, to);
3090 delete_surrounding_text (ic, to - len);
3096 to = (MPLIST_SYMBOL_P (args)
3097 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3099 : MPLIST_INTEGER (args));
3105 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3106 if (to < ic->cursor_pos)
3107 preedit_delete (ic, to, ic->cursor_pos);
3108 else if (to > ic->cursor_pos)
3109 preedit_delete (ic, ic->cursor_pos, to);
3111 else if (name == Mmove)
3113 int len = mtext_nchars (ic->preedit);
3115 = (MPLIST_SYMBOL_P (args)
3116 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3118 : MPLIST_INTEGER (args));
3124 if (pos != ic->cursor_pos)
3126 ic->cursor_pos = pos;
3127 ic->preedit_changed = 1;
3129 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3131 else if (name == Mmark)
3133 int code = marker_code (MPLIST_SYMBOL (args), 0);
3137 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3138 (void *) ic->cursor_pos);
3139 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3142 else if (name == Mpushback)
3144 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3148 if (MPLIST_SYMBOL_P (args))
3150 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3151 if (MPLIST_INTEGER_P (args))
3152 num = MPLIST_INTEGER (args);
3157 num = MPLIST_INTEGER (args);
3160 ic_info->key_head -= num;
3162 ic_info->key_head = 0;
3164 ic_info->key_head = - num;
3165 if (ic_info->key_head > ic_info->used)
3166 ic_info->key_head = ic_info->used;
3168 else if (MPLIST_MTEXT_P (args))
3170 MText *mt = MPLIST_MTEXT (args);
3171 int i, len = mtext_nchars (mt);
3174 ic_info->key_head--;
3175 for (i = 0; i < len; i++)
3177 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3178 if (ic_info->key_head + i < ic_info->used)
3179 ic_info->keys[ic_info->key_head + i] = key;
3181 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3186 MPlist *plist = MPLIST_PLIST (args), *pl;
3190 ic_info->key_head--;
3192 MPLIST_DO (pl, plist)
3194 key = MPLIST_SYMBOL (pl);
3195 if (ic_info->key_head < ic_info->used)
3196 ic_info->keys[ic_info->key_head + i] = key;
3198 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3203 else if (name == Mpop)
3205 if (ic_info->key_head < ic_info->used)
3206 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3208 else if (name == Mcall)
3210 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3211 MIMExternalFunc func = NULL;
3212 MSymbol module, func_name;
3213 MPlist *func_args, *val;
3216 module = MPLIST_SYMBOL (args);
3217 args = MPLIST_NEXT (args);
3218 func_name = MPLIST_SYMBOL (args);
3220 if (im_info->externals)
3222 MIMExternalModule *external
3223 = (MIMExternalModule *) mplist_get (im_info->externals,
3226 func = ((MIMExternalFunc)
3227 mplist_get_func (external->func_list, func_name));
3231 func_args = mplist ();
3232 mplist_add (func_args, Mt, ic);
3233 MPLIST_DO (args, MPLIST_NEXT (args))
3237 if (MPLIST_KEY (args) == Msymbol
3238 && MPLIST_KEY (args) != Mnil
3239 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3241 code = new_index (ic, ic->cursor_pos,
3242 mtext_nchars (ic->preedit),
3243 MPLIST_SYMBOL (args), ic->preedit);
3244 mplist_add (func_args, Minteger, (void *) code);
3247 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3249 val = (func) (func_args);
3250 M17N_OBJECT_UNREF (func_args);
3251 if (val && ! MPLIST_TAIL_P (val))
3252 ret = take_action_list (ic, val);
3253 M17N_OBJECT_UNREF (val);
3257 else if (name == Mshift)
3259 shift_state (ic, MPLIST_SYMBOL (args));
3261 else if (name == Mundo)
3263 int intarg = (MPLIST_TAIL_P (args)
3265 : integer_value (ic, args, NULL, 0));
3267 mtext_reset (ic->preedit);
3268 mtext_reset (ic_info->preedit_saved);
3269 mtext_reset (ic->produced);
3270 M17N_OBJECT_UNREF (ic_info->vars);
3271 ic_info->vars = mplist_copy (ic_info->vars_saved);
3272 ic->cursor_pos = ic_info->state_pos = 0;
3273 ic_info->state_key_head = ic_info->key_head
3274 = ic_info->commit_key_head = 0;
3276 shift_state (ic, Mnil);
3279 if (MPLIST_TAIL_P (args))
3284 ic_info->used += intarg;
3287 ic_info->used = intarg;
3290 else if (name == Mset || name == Madd || name == Msub
3291 || name == Mmul || name == Mdiv)
3293 MSymbol sym = MPLIST_SYMBOL (args);
3298 val1 = integer_value (ic, args, &value, 0);
3299 args = MPLIST_NEXT (args);
3300 val2 = resolve_expression (ic, args);
3302 val1 = val2, op = "=";
3303 else if (name == Madd)
3304 val1 += val2, op = "+=";
3305 else if (name == Msub)
3306 val1 -= val2, op = "-=";
3307 else if (name == Mmul)
3308 val1 *= val2, op = "*=";
3310 val1 /= val2, op = "/=";
3311 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3312 MSYMBOL_NAME (sym), op, val1, val1);
3314 mplist_set (value, Minteger, (void *) val1);
3316 else if (name == Mequal || name == Mless || name == Mgreater
3317 || name == Mless_equal || name == Mgreater_equal)
3320 MPlist *actions1, *actions2;
3323 val1 = resolve_expression (ic, args);
3324 args = MPLIST_NEXT (args);
3325 val2 = resolve_expression (ic, args);
3326 args = MPLIST_NEXT (args);
3327 actions1 = MPLIST_PLIST (args);
3328 args = MPLIST_NEXT (args);
3329 if (MPLIST_TAIL_P (args))
3332 actions2 = MPLIST_PLIST (args);
3333 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3334 if (name == Mequal ? val1 == val2
3335 : name == Mless ? val1 < val2
3336 : name == Mgreater ? val1 > val2
3337 : name == Mless_equal ? val1 <= val2
3340 MDEBUG_PRINT ("ok");
3341 ret = take_action_list (ic, actions1);
3345 MDEBUG_PRINT ("no");
3347 ret = take_action_list (ic, actions2);
3352 else if (name == Mcond)
3356 MPLIST_DO (args, args)
3361 if (! MPLIST_PLIST (args))
3363 cond = MPLIST_PLIST (args);
3364 if (resolve_expression (ic, cond) != 0)
3366 MDEBUG_PRINT1 ("(%dth)", idx);
3367 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3373 else if (name == Mcommit)
3375 preedit_commit (ic, 0);
3377 else if (name == Munhandle)
3379 preedit_commit (ic, 0);
3384 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3388 && (actions = mplist_get (im_info->macros, name)))
3390 if (take_action_list (ic, actions) < 0)
3396 if (ic->candidate_list)
3398 M17N_OBJECT_UNREF (ic->candidate_list);
3399 ic->candidate_list = NULL;
3401 if (ic->cursor_pos > 0
3402 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3405 ic->candidate_list = mtext_property_value (prop);
3406 M17N_OBJECT_REF (ic->candidate_list);
3408 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3410 ic->candidate_from = mtext_property_start (prop);
3411 ic->candidate_to = mtext_property_end (prop);
3414 if (candidate_list != ic->candidate_list)
3415 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3416 if (candidate_index != ic->candidate_index)
3417 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3418 if (candidate_show != ic->candidate_show)
3419 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3424 /* Handle the input key KEY in the current state and map specified in
3425 the input context IC. If KEY is handled correctly, return 0.
3426 Otherwise, return -1. */
3429 handle_key (MInputContext *ic)
3431 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3432 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3433 MIMMap *map = ic_info->map;
3434 MIMMap *submap = NULL;
3435 MSymbol key = ic_info->keys[ic_info->key_head];
3436 MSymbol alias = Mnil;
3439 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3440 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3444 submap = mplist_get (map->submaps, key);
3447 && (alias = msymbol_get (alias, M_key_alias))
3449 submap = mplist_get (map->submaps, alias);
3454 if (! alias || alias == key)
3455 MDEBUG_PRINT (" submap-found");
3457 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3458 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3459 ic->preedit_changed = 1;
3460 ic->cursor_pos = ic_info->state_pos;
3461 ic_info->key_head++;
3462 ic_info->map = map = submap;
3463 if (map->map_actions)
3465 MDEBUG_PRINT (" map-actions:");
3466 if (take_action_list (ic, map->map_actions) < 0)
3468 MDEBUG_PRINT ("\n");
3472 else if (map->submaps)
3474 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3476 MSymbol key = ic_info->keys[i];
3477 char *name = msymbol_name (key);
3479 if (! name[0] || ! name[1])
3480 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3484 /* If this is the terminal map or we have shifted to another
3485 state, perform branch actions (if any). */
3486 if (! map->submaps || map != ic_info->map)
3488 if (map->branch_actions)
3490 MDEBUG_PRINT (" branch-actions:");
3491 if (take_action_list (ic, map->branch_actions) < 0)
3493 MDEBUG_PRINT ("\n");
3497 /* If MAP is still not the root map, shift to the current
3499 if (ic_info->map != ic_info->state->map)
3500 shift_state (ic, ic_info->state->name);
3505 /* MAP can not handle KEY. */
3507 /* Perform branch actions if any. */
3508 if (map->branch_actions)
3510 MDEBUG_PRINT (" branch-actions:");
3511 if (take_action_list (ic, map->branch_actions) < 0)
3513 MDEBUG_PRINT ("\n");
3518 if (map == ic_info->map)
3520 /* The above branch actions didn't change the state. */
3522 /* If MAP is the root map of the initial state, and there
3523 still exist an unhandled key, it means that the current
3524 input method can not handle it. */
3525 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3526 && ic_info->key_head < ic_info->used)
3528 MDEBUG_PRINT (" unhandled\n");
3532 if (map != ic_info->state->map)
3534 /* MAP is not the root map. Shift to the root map of the
3536 shift_state (ic, ic_info->state->name);
3538 else if (! map->branch_actions)
3540 /* MAP is the root map without any default branch
3541 actions. Shift to the initial state. */
3542 shift_state (ic, Mnil);
3546 MDEBUG_PRINT ("\n");
3550 /* Initialize IC->ic_info. */
3553 init_ic_info (MInputContext *ic)
3555 MInputMethodInfo *im_info = ic->im->info;
3556 MInputContextInfo *ic_info = ic->info;
3559 MLIST_INIT1 (ic_info, keys, 8);;
3561 ic_info->markers = mplist ();
3563 ic_info->vars = mplist ();
3564 if (im_info->configured_vars)
3565 MPLIST_DO (plist, im_info->configured_vars)
3567 MPlist *pl = MPLIST_PLIST (plist);
3568 MSymbol name = MPLIST_SYMBOL (pl);
3570 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3571 if (MPLIST_KEY (pl) != Mt)
3573 MPlist *p = mplist ();
3575 mplist_push (ic_info->vars, Mplist, p);
3576 M17N_OBJECT_UNREF (p);
3577 mplist_add (p, Msymbol, name);
3578 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3581 ic_info->vars_saved = mplist_copy (ic_info->vars);
3583 if (im_info->externals)
3585 MPlist *func_args = mplist (), *plist;
3587 mplist_add (func_args, Mt, ic);
3588 MPLIST_DO (plist, im_info->externals)
3590 MIMExternalModule *external = MPLIST_VAL (plist);
3591 MIMExternalFunc func
3592 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3597 M17N_OBJECT_UNREF (func_args);
3600 ic_info->preedit_saved = mtext ();
3601 ic_info->tick = im_info->tick;
3604 /* Finalize IC->ic_info. */
3607 fini_ic_info (MInputContext *ic)
3609 MInputMethodInfo *im_info = ic->im->info;
3610 MInputContextInfo *ic_info = ic->info;
3612 if (im_info->externals)
3614 MPlist *func_args = mplist (), *plist;
3616 mplist_add (func_args, Mt, ic);
3617 MPLIST_DO (plist, im_info->externals)
3619 MIMExternalModule *external = MPLIST_VAL (plist);
3620 MIMExternalFunc func
3621 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3626 M17N_OBJECT_UNREF (func_args);
3629 MLIST_FREE1 (ic_info, keys);
3630 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3631 M17N_OBJECT_UNREF (ic_info->markers);
3632 M17N_OBJECT_UNREF (ic_info->vars);
3633 M17N_OBJECT_UNREF (ic_info->vars_saved);
3634 M17N_OBJECT_UNREF (ic_info->preceding_text);
3635 M17N_OBJECT_UNREF (ic_info->following_text);
3637 memset (ic_info, 0, sizeof (MInputContextInfo));
3641 re_init_ic (MInputContext *ic, int reload)
3643 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3644 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3645 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3647 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3648 preedit_changed = mtext_nchars (ic->preedit) > 0;
3649 cursor_pos_changed = ic->cursor_pos > 0;
3650 candidates_changed = 0;
3651 if (ic->candidate_list)
3653 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3654 M17N_OBJECT_UNREF (ic->candidate_list);
3655 ic->candidate_list = NULL;
3657 if (ic->candidate_show)
3659 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3660 ic->candidate_show = 0;
3662 if (ic->candidate_index > 0)
3664 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3665 ic->candidate_index = 0;
3666 ic->candidate_from = ic->candidate_to = 0;
3668 if (mtext_nchars (ic->produced) > 0)
3669 mtext_reset (ic->produced);
3670 if (mtext_nchars (ic->preedit) > 0)
3671 mtext_reset (ic->preedit);
3673 M17N_OBJECT_UNREF (ic->plist);
3674 ic->plist = mplist ();
3678 reload_im_info (im_info);
3679 if (! im_info->states)
3681 struct MIMState *state;
3683 M17N_OBJECT (state, free_state, MERROR_IM);
3684 state->name = msymbol ("init");
3685 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3686 MSTRUCT_CALLOC (state->map, MERROR_IM);
3687 im_info->states = mplist ();
3688 mplist_add (im_info->states, state->name, state);
3691 shift_state (ic, Mnil);
3693 ic->status_changed = status_changed;
3694 ic->preedit_changed = preedit_changed;
3695 ic->cursor_pos_changed = cursor_pos_changed;
3696 ic->candidates_changed = candidates_changed;
3700 reset_ic (MInputContext *ic, MSymbol ignore)
3702 MDEBUG_PRINT ("\n [IM] reset\n");
3707 open_im (MInputMethod *im)
3709 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3711 if (! im_info || ! im_info->states)
3712 MERROR (MERROR_IM, -1);
3719 close_im (MInputMethod *im)
3725 create_ic (MInputContext *ic)
3727 MInputContextInfo *ic_info;
3729 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3732 shift_state (ic, Mnil);
3737 destroy_ic (MInputContext *ic)
3744 check_reload (MInputContext *ic, MSymbol key)
3746 MInputMethodInfo *im_info = ic->im->info;
3747 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3751 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3755 MPLIST_DO (plist, plist)
3757 MSymbol this_key, alias;
3759 if (MPLIST_MTEXT_P (plist))
3761 MText *mt = MPLIST_MTEXT (plist);
3762 int c = mtext_ref_char (mt, 0);
3766 this_key = one_char_symbol[c];
3770 MPlist *pl = MPLIST_PLIST (plist);
3772 this_key = MPLIST_SYMBOL (pl);
3776 && (alias = msymbol_get (alias, M_key_alias))
3777 && alias != this_key);
3781 if (MPLIST_TAIL_P (plist))
3784 MDEBUG_PRINT ("\n [IM] reload");
3790 /** Handle the input key KEY in the current state and map of IC->info.
3791 If KEY is handled but no text is produced, return 0, otherwise
3797 filter (MInputContext *ic, MSymbol key, void *arg)
3799 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3800 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3803 if (check_reload (ic, key))
3806 if (! ic_info->state)
3808 ic_info->key_unhandled = 1;
3811 mtext_reset (ic->produced);
3812 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3813 M17N_OBJECT_UNREF (ic_info->preceding_text);
3814 M17N_OBJECT_UNREF (ic_info->following_text);
3815 ic_info->preceding_text = ic_info->following_text = NULL;
3816 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3817 ic_info->key_unhandled = 0;
3820 if (handle_key (ic) < 0)
3822 /* KEY was not handled. Delete it from the current key sequence. */
3823 if (ic_info->used > 0)
3825 memmove (ic_info->keys, ic_info->keys + 1,
3826 sizeof (int) * (ic_info->used - 1));
3828 if (ic_info->state_key_head > 0)
3829 ic_info->state_key_head--;
3830 if (ic_info->commit_key_head > 0)
3831 ic_info->commit_key_head--;
3833 /* This forces returning 1. */
3834 ic_info->key_unhandled = 1;
3840 reset_ic (ic, Mnil);
3841 ic_info->key_unhandled = 1;
3844 /* Break the loop if all keys were handled. */
3845 } while (ic_info->key_head < ic_info->used);
3847 /* If the current map is the root of the initial state, we should
3848 produce any preedit text in ic->produced. */
3849 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3850 preedit_commit (ic, 1);
3852 if (mtext_nchars (ic->produced) > 0)
3856 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3857 MSYMBOL_NAME (ic_info->state->name));
3858 for (i = 0; i < mtext_nchars (ic->produced); i++)
3859 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3863 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3864 Mlanguage, ic->im->language);
3866 if (ic_info->commit_key_head > 0)
3868 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3869 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3870 ic_info->used -= ic_info->commit_key_head;
3871 ic_info->key_head -= ic_info->commit_key_head;
3872 ic_info->state_key_head -= ic_info->commit_key_head;
3873 ic_info->commit_key_head = 0;
3875 if (ic_info->key_unhandled)
3878 ic_info->key_head = ic_info->state_key_head
3879 = ic_info->commit_key_head = 0;
3882 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3886 /** Return 1 if the last event or key was not handled, otherwise
3889 There is no need of looking up because ic->produced should already
3890 contain the produced text (if any).
3895 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3897 mtext_cat (mt, ic->produced);
3898 mtext_reset (ic->produced);
3899 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3903 /* Input method command handler. */
3905 /* List of all (global and local) commands.
3906 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3907 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3908 Global commands are stored as (t (t COMMAND ...)) */
3911 /* Input method variable handler. */
3914 /* Support functions for mdebug_dump_im. */
3917 dump_im_map (MPlist *map_list, int indent)
3920 MSymbol key = MPLIST_KEY (map_list);
3921 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3923 prefix = (char *) alloca (indent + 1);
3924 memset (prefix, 32, indent);
3925 prefix[indent] = '\0';
3927 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3928 if (map->map_actions)
3929 mdebug_dump_plist (map->map_actions, indent + 2);
3932 MPLIST_DO (map_list, map->submaps)
3934 fprintf (stderr, "\n%s ", prefix);
3935 dump_im_map (map_list, indent + 2);
3938 if (map->branch_actions)
3940 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3941 mdebug_dump_plist (map->branch_actions, indent + 4);
3942 fprintf (stderr, ")");
3944 fprintf (stderr, ")");
3949 dump_im_state (MIMState *state, int indent)
3954 prefix = (char *) alloca (indent + 1);
3955 memset (prefix, 32, indent);
3956 prefix[indent] = '\0';
3958 fprintf (stderr, "(%s", msymbol_name (state->name));
3959 if (state->map->submaps)
3961 MPLIST_DO (map_list, state->map->submaps)
3963 fprintf (stderr, "\n%s ", prefix);
3964 dump_im_map (map_list, indent + 2);
3967 fprintf (stderr, ")");
3975 Minput_driver = msymbol ("input-driver");
3977 Minput_preedit_start = msymbol ("input-preedit-start");
3978 Minput_preedit_done = msymbol ("input-preedit-done");
3979 Minput_preedit_draw = msymbol ("input-preedit-draw");
3980 Minput_status_start = msymbol ("input-status-start");
3981 Minput_status_done = msymbol ("input-status-done");
3982 Minput_status_draw = msymbol ("input-status-draw");
3983 Minput_candidates_start = msymbol ("input-candidates-start");
3984 Minput_candidates_done = msymbol ("input-candidates-done");
3985 Minput_candidates_draw = msymbol ("input-candidates-draw");
3986 Minput_set_spot = msymbol ("input-set-spot");
3987 Minput_focus_move = msymbol ("input-focus-move");
3988 Minput_focus_in = msymbol ("input-focus-in");
3989 Minput_focus_out = msymbol ("input-focus-out");
3990 Minput_toggle = msymbol ("input-toggle");
3991 Minput_reset = msymbol ("input-reset");
3992 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3993 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3994 Mcustomized = msymbol ("customized");
3995 Mconfigured = msymbol ("configured");
3996 Minherited = msymbol ("inherited");
3998 minput_default_driver.open_im = open_im;
3999 minput_default_driver.close_im = close_im;
4000 minput_default_driver.create_ic = create_ic;
4001 minput_default_driver.destroy_ic = destroy_ic;
4002 minput_default_driver.filter = filter;
4003 minput_default_driver.lookup = lookup;
4004 minput_default_driver.callback_list = mplist ();
4005 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4006 M17N_FUNC (reset_ic));
4007 minput_driver = &minput_default_driver;
4009 fully_initialized = 0;
4016 if (fully_initialized)
4018 free_im_list (im_info_list);
4020 free_im_list (im_custom_list);
4022 free_im_list (im_config_list);
4023 M17N_OBJECT_UNREF (load_im_info_keys);
4026 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4027 M17N_OBJECT_UNREF (minput_driver->callback_list);
4032 minput__char_to_key (int c)
4034 if (c < 0 || c >= 0x100)
4037 return one_char_symbol[c];
4041 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4046 /*** @addtogroup m17nInputMethod */
4051 @name Variables: Predefined symbols for callback commands.
4053 These are the predefined symbols that are used as the @c COMMAND
4054 argument of callback functions of an input method driver (see
4055 #MInputDriver::callback_list).
4057 Most of them do not require extra argument nor return any value;
4058 exceptions are these:
4060 Minput_get_surrounding_text: When a callback function assigned for
4061 this command is called, the first element of #MInputContext::plist
4062 has key #Minteger and the value specifies which portion of the
4063 surrounding text should be retrieved. If the value is positive,
4064 it specifies the number of characters following the current cursor
4065 position. If the value is negative, the absolute value specifies
4066 the number of characters preceding the current cursor position.
4067 If the value is zero, it means that the caller just wants to know
4068 if the surrounding text is currently supported or not.
4070 If the surrounding text is currently supported, the callback
4071 function must set the key of this element to #Mtext and the value
4072 to the retrieved M-text. The length of the M-text may be shorter
4073 than the requested number of characters, if the available text is
4074 not that long. The length can be zero in the worst case. Or, the
4075 length may be longer if an application thinks it is more efficient
4076 to return that length.
4078 If the surrounding text is not currently supported, the callback
4079 function should return without changing the first element of
4080 #MInputContext::plist.
4082 Minput_delete_surrounding_text: When a callback function assigned
4083 for this command is called, the first element of
4084 #MInputContext::plist has key #Minteger and the value specifies
4085 which portion of the surrounding text should be deleted in the
4086 same way as the case of Minput_get_surrounding_text. The callback
4087 function must delete the specified text. It should not alter
4088 #MInputContext::plist. */
4090 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4092 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4093 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4095 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4097 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4098 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4099 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4100 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4101 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4102 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4103 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4105 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4106 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4107 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4108 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4109 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4111 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4112 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4114 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4115 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4116 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4117 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4118 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4119 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4123 MSymbol Minput_preedit_start;
4124 MSymbol Minput_preedit_done;
4125 MSymbol Minput_preedit_draw;
4126 MSymbol Minput_status_start;
4127 MSymbol Minput_status_done;
4128 MSymbol Minput_status_draw;
4129 MSymbol Minput_candidates_start;
4130 MSymbol Minput_candidates_done;
4131 MSymbol Minput_candidates_draw;
4132 MSymbol Minput_set_spot;
4133 MSymbol Minput_toggle;
4134 MSymbol Minput_reset;
4135 MSymbol Minput_get_surrounding_text;
4136 MSymbol Minput_delete_surrounding_text;
4142 @name Variables: Predefined symbols for special input events.
4144 These are the predefined symbols that are used as the @c KEY
4145 argument of minput_filter (). */
4147 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4149 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4154 MSymbol Minput_focus_out;
4155 MSymbol Minput_focus_in;
4156 MSymbol Minput_focus_move;
4162 @name Variables: Predefined symbols used in input method information.
4164 These are the predefined symbols describing status of input method
4165 command and variable, and are used in a return value of
4166 minput_get_command () and minput_get_variable (). */
4168 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4170 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4171 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4175 MSymbol Mcustomized;
4176 MSymbol Mconfigured;
4182 @brief The default driver for internal input methods.
4184 The variable #minput_default_driver is the default driver for
4185 internal input methods.
4187 The member MInputDriver::open_im () searches the m17n database for
4188 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4189 $NAME\> and loads it.
4191 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4192 programmers responsibility to set it to a plist of proper callback
4193 functions. Otherwise, no feedback information (e.g. preedit text)
4194 can be shown to users.
4196 The macro M17N_INIT () sets the variable #minput_driver to the
4197 pointer to this driver so that all internal input methods use it.
4199 Therefore, unless @c minput_driver is set differently, the driver
4200 dependent arguments $ARG of the functions whose name begins with
4201 "minput_" are all ignored. */
4203 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4205 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4207 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4208 \< #Minput_method, $LANGUAGE, $NAME\>
4209 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4211 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4212 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4213 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4214 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4216 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4217 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4219 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4220 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4222 MInputDriver minput_default_driver;
4226 @brief The driver for internal input methods.
4228 The variable #minput_driver is a pointer to the input method
4229 driver that is used by internal input methods. The macro
4230 M17N_INIT () initializes it to a pointer to #minput_default_driver
4231 if <m17n<EM></EM>.h> is included. */
4233 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4235 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4236 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4237 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4238 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4240 MInputDriver *minput_driver;
4242 MSymbol Minput_driver;
4257 @brief Open an input method.
4259 The minput_open_im () function opens an input method whose
4260 language and name match $LANGUAGE and $NAME, and returns a pointer
4261 to the input method object newly allocated.
4263 This function at first decides a driver for the input method as
4266 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4267 #minput_driver is used.
4269 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4270 driver pointed to by the property value is used to open the input
4271 method. If $NAME has no such a property, @c NULL is returned.
4273 Then, the member MInputDriver::open_im () of the driver is
4276 $ARG is set in the member @c arg of the structure MInputMethod so
4277 that the driver can refer to it. */
4279 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4281 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4282 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4284 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4286 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4287 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4289 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4290 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4291 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4293 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4295 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4297 @latexonly \IPAlabel{minput_open} @endlatexonly
4302 minput_open_im (MSymbol language, MSymbol name, void *arg)
4305 MInputDriver *driver;
4309 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4310 msymbol_name (language), msymbol_name (name));
4312 driver = minput_driver;
4315 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4317 MERROR (MERROR_IM, NULL);
4320 MSTRUCT_CALLOC (im, MERROR_IM);
4321 im->language = language;
4324 im->driver = *driver;
4325 if ((*im->driver.open_im) (im) < 0)
4327 MDEBUG_PRINT (" failed\n");
4331 MDEBUG_PRINT (" ok\n");
4338 @brief Close an input method.
4340 The minput_close_im () function closes the input method $IM, which
4341 must have been created by minput_open_im (). */
4344 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4346 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4347 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4350 minput_close_im (MInputMethod *im)
4352 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4353 msymbol_name (im->name), msymbol_name (im->language));
4354 (*im->driver.close_im) (im);
4356 MDEBUG_PRINT (" done\n");
4362 @brief Create an input context.
4364 The minput_create_ic () function creates an input context object
4365 associated with input method $IM, and calls callback functions
4366 corresponding to #Minput_preedit_start, #Minput_status_start, and
4367 #Minput_status_draw in this order.
4370 If an input context is successfully created, minput_create_ic ()
4371 returns a pointer to it. Otherwise it returns @c NULL. */
4374 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4376 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4377 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4378 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4379 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4382 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4383 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4387 minput_create_ic (MInputMethod *im, void *arg)
4391 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4392 msymbol_name (im->name), msymbol_name (im->language));
4393 MSTRUCT_CALLOC (ic, MERROR_IM);
4396 ic->preedit = mtext ();
4397 ic->candidate_list = NULL;
4398 ic->produced = mtext ();
4399 ic->spot.x = ic->spot.y = 0;
4401 ic->plist = mplist ();
4402 if ((*im->driver.create_ic) (ic) < 0)
4404 MDEBUG_PRINT (" failed\n");
4405 M17N_OBJECT_UNREF (ic->preedit);
4406 M17N_OBJECT_UNREF (ic->produced);
4407 M17N_OBJECT_UNREF (ic->plist);
4412 if (im->driver.callback_list)
4414 minput_callback (ic, Minput_preedit_start);
4415 minput_callback (ic, Minput_status_start);
4416 minput_callback (ic, Minput_status_draw);
4419 MDEBUG_PRINT (" ok\n");
4426 @brief Destroy an input context.
4428 The minput_destroy_ic () function destroys the input context $IC,
4429 which must have been created by minput_create_ic (). It calls
4430 callback functions corresponding to #Minput_preedit_done,
4431 #Minput_status_done, and #Minput_candidates_done in this order. */
4434 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4436 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4437 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4438 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4439 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4440 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4444 minput_destroy_ic (MInputContext *ic)
4446 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4447 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4448 if (ic->im->driver.callback_list)
4450 minput_callback (ic, Minput_preedit_done);
4451 minput_callback (ic, Minput_status_done);
4452 minput_callback (ic, Minput_candidates_done);
4454 (*ic->im->driver.destroy_ic) (ic);
4455 M17N_OBJECT_UNREF (ic->preedit);
4456 M17N_OBJECT_UNREF (ic->produced);
4457 M17N_OBJECT_UNREF (ic->plist);
4458 MDEBUG_PRINT (" done\n");
4465 @brief Filter an input key.
4467 The minput_filter () function filters input key $KEY according to
4468 input context $IC, and calls callback functions corresponding to
4469 #Minput_preedit_draw, #Minput_status_draw, and
4470 #Minput_candidates_draw if the preedit text, the status, and the
4471 current candidate are changed respectively.
4473 To make the input method commit the current preedit text (if any)
4474 and shift to the initial state, call this function with #Mnil as
4477 To inform the input method about the focus-out event, call this
4478 function with #Minput_focus_out as $KEY.
4480 To inform the input method about the focus-in event, call this
4481 function with #Minput_focus_in as $KEY.
4483 To inform the input method about the focus-move event (i.e. input
4484 spot change within the same input context), call this function
4485 with #Minput_focus_move as $KEY.
4488 If $KEY is filtered out, this function returns 1. In that case,
4489 the caller should discard the key. Otherwise, it returns 0, and
4490 the caller should handle the key, for instance, by calling the
4491 function minput_lookup () with the same key. */
4494 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4496 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4497 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4498 #Minput_preedit_draw, #Minput_status_draw,
4499 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4502 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4503 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4504 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4505 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4507 @latexonly \IPAlabel{minput_filter} @endlatexonly
4511 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4518 if (ic->im->driver.callback_list
4519 && mtext_nchars (ic->preedit) > 0)
4520 minput_callback (ic, Minput_preedit_draw);
4522 ret = (*ic->im->driver.filter) (ic, key, arg);
4524 if (ic->im->driver.callback_list)
4526 if (ic->preedit_changed)
4527 minput_callback (ic, Minput_preedit_draw);
4528 if (ic->status_changed)
4529 minput_callback (ic, Minput_status_draw);
4530 if (ic->candidates_changed)
4531 minput_callback (ic, Minput_candidates_draw);
4540 @brief Look up a text produced in the input context.
4542 The minput_lookup () function looks up a text in the input context
4543 $IC. $KEY must be identical to the one that was used in the previous call of
4546 If a text was produced by the input method, it is concatenated
4549 This function calls #MInputDriver::lookup .
4552 If $KEY was correctly handled by the input method, this function
4553 returns 0. Otherwise, it returns -1, even though some text
4554 might be produced in $MT. */
4557 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4559 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4560 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4562 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4565 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4568 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4569 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4570 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4572 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4575 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4577 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4582 @brief Set the spot of the input context.
4584 The minput_set_spot () function sets the spot of input context $IC
4585 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4586 The semantics of these values depends on the input method driver.
4588 For instance, a driver designed to work in a CUI environment may
4589 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4590 $DESCENT . A driver designed to work in a window system may
4591 interpret $X and $Y as the pixel offsets relative to the origin of the
4592 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4593 descent pixels of the line at ($X . $Y ).
4595 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4597 $MT and $POS are the M-text and the character position at the spot.
4598 $MT may be @c NULL, in which case, the input method cannot get
4599 information about the text around the spot. */
4602 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4604 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4605 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4606 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4608 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4609 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4610 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4611 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4612 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4613 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4615 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4617 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4618 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4622 minput_set_spot (MInputContext *ic, int x, int y,
4623 int ascent, int descent, int fontsize,
4628 ic->spot.ascent = ascent;
4629 ic->spot.descent = descent;
4630 ic->spot.fontsize = fontsize;
4633 if (ic->im->driver.callback_list)
4634 minput_callback (ic, Minput_set_spot);
4639 @brief Toggle input method.
4641 The minput_toggle () function toggles the input method associated
4642 with input context $IC. */
4644 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4646 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4647 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4651 minput_toggle (MInputContext *ic)
4653 if (ic->im->driver.callback_list)
4654 minput_callback (ic, Minput_toggle);
4655 ic->active = ! ic->active;
4661 @brief Reset an input context.
4663 The minput_reset_ic () function resets input context $IC by
4664 calling a callback function corresponding to #Minput_reset. It
4665 resets the status of $IC to its initial one. As the
4666 current preedit text is deleted without commitment, if necessary,
4667 call minput_filter () with the arg @r key #Mnil to force the input
4668 method to commit the preedit in advance. */
4671 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4673 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4674 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4675 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4676 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4677 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4678 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4681 minput_reset_ic (MInputContext *ic)
4683 if (ic->im->driver.callback_list)
4684 minput_callback (ic, Minput_reset);
4690 @brief Get title and icon filename of an input method.
4692 The minput_get_title_icon () function returns a plist containing a
4693 title and icon filename (if any) of an input method specified by
4694 $LANGUAGE and $NAME.
4696 The first element of the plist has key #Mtext and the value is an
4697 M-text of the title for identifying the input method. The second
4698 element (if any) has key #Mtext and the value is an M-text of the
4699 icon image (absolute) filename for the same purpose.
4702 If there exists a specified input method and it defines an title,
4703 a plist is returned. Otherwise, NULL is returned. The caller
4704 must free the plist by m17n_object_unref (). */
4706 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4708 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4709 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4712 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4713 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4714 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4717 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4718 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4719 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4722 minput_get_title_icon (MSymbol language, MSymbol name)
4724 MInputMethodInfo *im_info;
4731 im_info = get_im_info (language, name, Mnil, Mtitle);
4732 if (! im_info || !im_info->title)
4734 mt = mtext_get_prop (im_info->title, 0, Mtext);
4736 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4739 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4742 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4743 (char *) MSYMBOL_NAME (name));
4744 file = mdatabase__find_file (buf);
4745 if (! file && language == Mt)
4747 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4748 file = mdatabase__find_file (buf);
4753 mplist_add (plist, Mtext, im_info->title);
4756 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4758 mplist_add (plist, Mtext, mt);
4759 M17N_OBJECT_UNREF (mt);
4767 @brief Get description text of an input method.
4769 The minput_get_description () function returns an M-text that
4770 describes the input method specified by $LANGUAGE and $NAME.
4773 If the specified input method has a description text, a pointer to
4774 #MText is returned. The caller has to free it by m17n_object_unref ().
4775 If the input method does not have a description text, @c NULL is
4778 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4780 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4781 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4783 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4784 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4785 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4786 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4789 minput_get_description (MSymbol language, MSymbol name)
4791 MInputMethodInfo *im_info;
4799 extra = language, language = Mt;
4801 im_info = get_im_info (language, name, extra, Mdescription);
4802 if (! im_info || ! im_info->description)
4804 M17N_OBJECT_REF (im_info->description);
4805 return im_info->description;
4811 @brief Get information about input method command(s).
4813 The minput_get_command () function returns information about
4814 the command $COMMAND of the input method specified by $LANGUAGE and
4815 $NAME. An input method command is a pseudo key event to which one
4816 or more actual input key sequences are assigned.
4818 There are two kinds of commands, global and local. A global
4819 command has a global definition, and the description and the key
4820 assignment may be inherited by a local command. Each input method
4821 defines a local command which has a local key assignment. It may
4822 also declare a local command that inherits the definition of a
4823 global command of the same name.
4825 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4826 information about a global command. Otherwise information about a
4827 local command is returned.
4829 If $COMMAND is #Mnil, information about all commands is returned.
4831 The return value is a @e well-formed plist (@ref m17nPlist) of this
4834 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4836 @c NAME is a symbol representing the command name.
4838 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4839 command has no description.
4841 @c STATUS is a symbol representing how the key assignment is decided.
4842 The value is #Mnil (the default key assignment), #Mcustomized (the
4843 key assignment is customized by per-user customization file), or
4844 #Mconfigured (the key assignment is set by the call of
4845 minput_config_command ()). For a local command only, it may also
4846 be #Minherited (the key assignment is inherited from the
4847 corresponding global command).
4849 @c KEYSEQ is a plist of one or more symbols representing a key
4850 sequence assigned to the command. If there's no KEYSEQ, the
4851 command is currently disabled (i.e. no key sequence can trigger
4852 actions of the command).
4854 If $COMMAND is not #Mnil, the first element of the returned plist
4855 contains the information about $COMMAND.
4859 If the requested information was found, a pointer to a non-empty
4860 plist is returned. As the plist is kept in the library, the
4861 caller must not modify nor free it.
4863 Otherwise (the specified input method or the specified command
4864 does not exist), @c NULL is returned. */
4866 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4868 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4869 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4870 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4871 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4873 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4874 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4875 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4876 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4877 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4879 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4880 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4883 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4885 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4888 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4890 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4892 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4895 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4896 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4897 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4898 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4899 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4900 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4903 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4904 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4905 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4906 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4908 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4909 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4913 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4914 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4917 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4922 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4924 /* Return a description of the command COMMAND of the input method
4925 specified by LANGUAGE and NAME. */
4926 MPlist *cmd = minput_get_command (langauge, name, command);
4931 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4932 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4933 return (mplist_key (plist) == Mtext
4934 ? (MText *) mplist_value (plist)
4940 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4942 MInputMethodInfo *im_info;
4946 im_info = get_im_info (language, name, Mnil, Mcommand);
4948 || ! im_info->configured_cmds
4949 || MPLIST_TAIL_P (im_info->configured_cmds))
4951 if (command == Mnil)
4952 return im_info->configured_cmds;
4953 return mplist__assq (im_info->configured_cmds, command);
4959 @brief Configure the key sequence of an input method command.
4961 The minput_config_command () function assigns a list of key
4962 sequences $KEYSEQLIST to the command $COMMAND of the input method
4963 specified by $LANGUAGE and $NAME.
4965 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4966 sequences, and each key sequence must be a plist of symbols.
4968 If $KEYSEQLIST is an empty plist, any configuration and
4969 customization of the command are cancelled, and default key
4970 sequences become effective.
4972 If $KEYSEQLIST is NULL, the configuration of the command is
4973 canceled, and the original key sequences (what saved in per-user
4974 customization file, or the default one) become effective.
4976 In the latter two cases, $COMMAND can be #Mnil to make all the
4977 commands of the input method the target of the operation.
4979 If $NAME is #Mnil, this function configures the key assignment of a
4980 global command, not that of a specific input method.
4982 The configuration takes effect for input methods opened or
4983 re-opened later in the current session. In order to make the
4984 configuration take effect for the future session, it must be saved
4985 in a per-user customization file by the function
4986 minput_save_config ().
4989 If the operation was successful, this function returns 0,
4990 otherwise returns -1. The operation fails in these cases:
4992 <li>$KEYSEQLIST is not in a valid form.
4993 <li>$COMMAND is not available for the input method.
4994 <li>$LANGUAGE and $NAME do not specify an existing input method.
4998 minput_get_commands (), minput_save_config ().
5001 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5003 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5004 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5005 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5007 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5008 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5010 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5011 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5013 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5014 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5015 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5017 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5018 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5020 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5021 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5023 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5024 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5025 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5026 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5030 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5032 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5033 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5034 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5038 minput_get_commands (), minput_save_config ().
5042 /* Add "C-x u" to the "start" command of Unicode input method. */
5044 MSymbol start_command = msymbol ("start");
5045 MSymbol unicode = msymbol ("unicode");
5046 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5048 /* At first get the current key-sequence assignment. */
5049 cmd = minput_get_command (Mt, unicode, start_command);
5052 /* The input method does not have the command "start". Here
5053 should come some error handling code. */
5055 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5056 Extract the part (KEY-SEQUENCE ...). */
5057 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5058 /* Copy it because we should not modify it directly. */
5059 key_seq_list = mplist_copy (plist);
5061 key_seq = mplist ();
5062 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5063 mplist_add (key_seq, Msymbol, msymbol ("u"));
5064 mplist_add (key_seq_list, Mplist, key_seq);
5065 m17n_object_unref (key_seq);
5067 minput_config_command (Mt, unicode, start_command, key_seq_list);
5068 m17n_object_unref (key_seq_list);
5073 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5076 MInputMethodInfo *im_info, *config;
5081 im_info = get_im_info (language, name, Mnil, Mcommand);
5083 MERROR (MERROR_IM, -1);
5084 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5086 || ! mplist__assq (im_info->configured_cmds, command)))
5087 MERROR (MERROR_IM, -1);
5088 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5090 MPLIST_DO (plist, keyseqlist)
5091 if (! check_command_keyseq (plist))
5092 MERROR (MERROR_IM, -1);
5095 config = get_config_info (im_info);
5098 if (! im_config_list)
5099 im_config_list = mplist ();
5100 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5101 config->cmds = mplist ();
5102 config->vars = mplist ();
5105 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5106 /* Nothing to do. */
5109 if (command == Mnil)
5113 /* Cancal the configuration. */
5114 if (MPLIST_TAIL_P (config->cmds))
5116 mplist_set (config->cmds, Mnil, NULL);
5120 /* Cancal the customization. */
5121 MInputMethodInfo *custom = get_custom_info (im_info);
5123 if (MPLIST_TAIL_P (config->cmds)
5124 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5125 /* Nothing to do. */
5127 mplist_set (config->cmds, Mnil, NULL);
5128 MPLIST_DO (plist, custom->cmds)
5130 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5132 mplist_add (plist, Msymbol, command);
5133 mplist_push (config->cmds, Mplist, plist);
5134 M17N_OBJECT_UNREF (plist);
5140 plist = mplist__assq (config->cmds, command);
5143 /* Cancel the configuration. */
5146 mplist__pop_unref (plist);
5148 else if (MPLIST_TAIL_P (keyseqlist))
5150 /* Cancel the customization. */
5151 MInputMethodInfo *custom = get_custom_info (im_info);
5152 int no_custom = (! custom || ! custom->cmds
5153 || ! mplist__assq (custom->cmds, command));
5159 mplist_add (config->cmds, Mplist, plist);
5160 M17N_OBJECT_UNREF (plist);
5161 plist = mplist_add (plist, Msymbol, command);
5166 mplist__pop_unref (plist);
5169 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5170 plist = MPLIST_NEXT (plist);
5171 mplist_set (plist, Mnil, NULL);
5181 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5182 if (! MPLIST_TAIL_P (plist))
5183 mplist_set (plist, Mnil, NULL);
5188 mplist_add (config->cmds, Mplist, plist);
5189 M17N_OBJECT_UNREF (plist);
5190 plist = mplist_add (plist, Msymbol, command);
5191 plist = MPLIST_NEXT (plist);
5193 MPLIST_DO (keyseqlist, keyseqlist)
5195 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5196 plist = mplist_add (plist, Mplist, pl);
5197 M17N_OBJECT_UNREF (pl);
5201 config_all_commands (im_info);
5202 im_info->tick = time (NULL);
5209 @brief Get information about input method variable(s).
5211 The minput_get_variable () function returns information about
5212 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5213 An input method variable controls behavior of an input method.
5215 There are two kinds of variables, global and local. A global
5216 variable has a global definition, and the description and the value
5217 may be inherited by a local variable. Each input method defines a
5218 local variable which has local value. It may also declare a
5219 local variable that inherits definition of a global variable of
5222 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5223 variable is returned. Otherwise information about a local variable
5226 If $VARIABLE is #Mnil, information about all variables is
5229 The return value is a @e well-formed plist (@ref m17nPlist) of this
5232 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5234 @c NAME is a symbol representing the variable name.
5236 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5237 variable has no description.
5239 @c STATUS is a symbol representing how the value is decided. The
5240 value is #Mnil (the default value), #Mcustomized (the value is
5241 customized by per-user customization file), or #Mconfigured (the
5242 value is set by the call of minput_config_variable ()). For a
5243 local variable only, it may also be #Minherited (the value is
5244 inherited from the corresponding global variable).
5246 @c VALUE is the initial value of the variable. If the key of this
5247 element is #Mt, the variable has no initial value. Otherwise, the
5248 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5251 @c VALID-VALUEs (if any) specify which values the variable can have.
5252 They have the same type (i.e. having the same key) as @c VALUE except
5253 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5254 may be a plist of two integers specifying the range of possible
5257 If there no @c VALID-VALUE, the variable can have any value as long
5258 as the type is the same as @c VALUE.
5260 If $VARIABLE is not #Mnil, the first element of the returned plist
5261 contains the information about $VARIABLE.
5265 If the requested information was found, a pointer to a non-empty
5266 plist is returned. As the plist is kept in the library, the
5267 caller must not modify nor free it.
5269 Otherwise (the specified input method or the specified variable
5270 does not exist), @c NULL is returned. */
5272 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5274 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5275 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5276 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5278 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5279 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5280 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5281 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5284 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5285 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5287 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5289 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5291 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5294 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5296 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5299 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5300 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5301 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5302 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5303 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5304 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5306 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5307 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5308 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5310 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5311 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5312 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5313 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5315 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5318 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5319 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5323 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5324 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5327 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5331 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5333 MInputMethodInfo *im_info;
5337 im_info = get_im_info (language, name, Mnil, Mvariable);
5338 if (! im_info || ! im_info->configured_vars)
5340 if (variable == Mnil)
5341 return im_info->configured_vars;
5342 return mplist__assq (im_info->configured_vars, variable);
5348 @brief Configure the value of an input method variable.
5350 The minput_config_variable () function assigns $VALUE to the
5351 variable $VARIABLE of the input method specified by $LANGUAGE and
5354 If $VALUE is a non-empty plist, it must be a plist of one element
5355 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5356 the corresponding type. That value is assigned to the variable.
5358 If $VALUE is an empty plist, any configuration and customization
5359 of the variable are canceled, and the default value is assigned to
5362 If $VALUE is NULL, the configuration of the variable is canceled,
5363 and the original value (what saved in per-user customization file,
5364 or the default value) is assigned to the variable.
5366 In the latter two cases, $VARIABLE can be #Mnil to make all the
5367 variables of the input method the target of the operation.
5369 If $NAME is #Mnil, this function configures the value of global
5370 variable, not that of a specific input method.
5372 The configuration takes effect for input methods opened or
5373 re-opened later in the current session. To make the configuration
5374 take effect for the future session, it must be saved in a per-user
5375 customization file by the function minput_save_config ().
5379 If the operation was successful, this function returns 0,
5380 otherwise returns -1. The operation fails in these cases:
5382 <li>$VALUE is not in a valid form, the type does not match the
5383 definition, or the value is our of range.
5384 <li>$VARIABLE is not available for the input method.
5385 <li>$LANGUAGE and $NAME do not specify an existing input method.
5389 minput_get_variable (), minput_save_config (). */
5391 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5393 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5394 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5396 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5397 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5398 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5400 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5401 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5403 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5404 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5406 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5407 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5409 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5410 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5412 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5413 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5414 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5415 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5419 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5421 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5422 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5423 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5427 minput_get_commands (), minput_save_config ().
5430 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5433 MInputMethodInfo *im_info, *config;
5438 im_info = get_im_info (language, name, Mnil, Mvariable);
5440 MERROR (MERROR_IM, -1);
5441 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5443 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5444 MERROR (MERROR_IM, -1);
5446 if (value && ! MPLIST_TAIL_P (value))
5448 plist = MPLIST_PLIST (plist);
5449 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5450 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5451 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5452 if (MPLIST_KEY (plist) != Mt
5453 && ! check_variable_value (value, plist))
5454 MERROR (MERROR_IM, -1);
5457 config = get_config_info (im_info);
5460 if (! im_config_list)
5461 im_config_list = mplist ();
5462 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5463 config->cmds = mplist ();
5464 config->vars = mplist ();
5467 if (! value && MPLIST_TAIL_P (config->vars))
5468 /* Nothing to do. */
5471 if (variable == Mnil)
5475 /* Cancel the configuration. */
5476 if (MPLIST_TAIL_P (config->vars))
5478 mplist_set (config->vars, Mnil, NULL);
5482 /* Cancel the customization. */
5483 MInputMethodInfo *custom = get_custom_info (im_info);
5485 if (MPLIST_TAIL_P (config->vars)
5486 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5487 /* Nothing to do. */
5489 mplist_set (config->vars, Mnil, NULL);
5490 MPLIST_DO (plist, custom->vars)
5492 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5494 mplist_add (plist, Msymbol, variable);
5495 mplist_push (config->vars, Mplist, plist);
5496 M17N_OBJECT_UNREF (plist);
5502 plist = mplist__assq (config->vars, variable);
5505 /* Cancel the configuration. */
5508 mplist__pop_unref (plist);
5510 else if (MPLIST_TAIL_P (value))
5512 /* Cancel the customization. */
5513 MInputMethodInfo *custom = get_custom_info (im_info);
5514 int no_custom = (! custom || ! custom->vars
5515 || ! mplist__assq (custom->vars, variable));
5521 mplist_add (config->vars, Mplist, plist);
5522 M17N_OBJECT_UNREF (plist);
5523 plist = mplist_add (plist, Msymbol, variable);
5528 mplist__pop_unref (plist);
5531 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5532 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5533 mplist_set (plist, Mnil ,NULL);
5541 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5542 if (! MPLIST_TAIL_P (plist))
5543 mplist_set (plist, Mnil, NULL);
5548 mplist_add (config->vars, Mplist, plist);
5549 M17N_OBJECT_UNREF (plist);
5550 plist = mplist_add (plist, Msymbol, variable);
5551 plist = MPLIST_NEXT (plist);
5553 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5556 config_all_variables (im_info);
5557 im_info->tick = time (NULL);
5564 @brief Get the name of per-user customization file.
5566 The minput_config_file () function returns the absolute path name
5567 of per-user customization file into which minput_save_config ()
5568 save configurations. It is usually @c "config.mic" under the
5569 directory @c ".m17n.d" of user's home directory. It is not assured
5570 that the file of the returned name exists nor is
5571 readable/writable. If minput_save_config () fails and returns -1,
5572 an application program might check the file, make it
5573 writable (if possible), and try minput_save_config () again.
5577 This function returns a string. As the string is kept in the
5578 library, the caller must not modify nor free it.
5581 minput_save_config ()
5584 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5586 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5587 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5588 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5589 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5590 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5591 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5592 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5597 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5598 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5601 minput_save_config ()
5605 minput_config_file ()
5609 return mdatabase__file (im_custom_mdb);
5615 @brief Save configurations in per-user customization file.
5617 The minput_save_config () function saves the configurations done
5618 so far in the current session into the per-user customization
5623 If the operation was successful, 1 is returned. If the per-user
5624 customization file is currently locked, 0 is returned. In that
5625 case, the caller may wait for a while and try again. If the
5626 configuration file is not writable, -1 is returned. In that case,
5627 the caller may check the name of the file by calling
5628 minput_config_file (), make it writable if possible, and try
5632 minput_config_file () */
5634 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5636 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5637 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5641 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5642 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5643 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5644 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5648 minput_config_file () */
5651 minput_save_config (void)
5653 MPlist *data, *tail, *plist, *p, *elt;
5657 ret = mdatabase__lock (im_custom_mdb);
5660 if (! im_config_list)
5662 update_custom_info ();
5663 if (! im_custom_list)
5664 im_custom_list = mplist ();
5666 /* At first, reflect configuration in customization. */
5667 MPLIST_DO (plist, im_config_list)
5669 MPlist *pl = MPLIST_PLIST (plist);
5670 MSymbol language, name, extra, command, variable;
5671 MInputMethodInfo *custom, *config;
5673 language = MPLIST_SYMBOL (pl);
5674 pl = MPLIST_NEXT (pl);
5675 name = MPLIST_SYMBOL (pl);
5676 pl = MPLIST_NEXT (pl);
5677 extra = MPLIST_SYMBOL (pl);
5678 pl = MPLIST_NEXT (pl);
5679 config = MPLIST_VAL (pl);
5680 custom = get_custom_info (config);
5682 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5684 MPLIST_DO (pl, config->cmds)
5686 elt = MPLIST_PLIST (pl);
5687 command = MPLIST_SYMBOL (elt);
5689 p = mplist__assq (custom->cmds, command);
5691 custom->cmds = mplist (), p = NULL;
5692 elt = MPLIST_NEXT (elt);
5695 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5696 mplist_set (p, Mnil, NULL);
5701 mplist_add (custom->cmds, Mplist, p);
5702 M17N_OBJECT_UNREF (p);
5703 mplist_add (p, Msymbol, command);
5704 p = mplist_add (p, Msymbol, Mnil);
5705 p = MPLIST_NEXT (p);
5707 mplist__conc (p, elt);
5710 MPLIST_DO (pl, config->vars)
5712 elt = MPLIST_PLIST (pl);
5713 variable = MPLIST_SYMBOL (elt);
5715 p = mplist__assq (custom->vars, variable);
5717 custom->vars = mplist (), p = NULL;
5718 elt = MPLIST_NEXT (elt);
5721 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5722 mplist_set (p, Mnil, NULL);
5727 mplist_add (custom->vars, Mplist, p);
5728 M17N_OBJECT_UNREF (p);
5729 mplist_add (p, Msymbol, variable);
5730 p = mplist_add (p, Msymbol, Mnil);
5731 p = MPLIST_NEXT (p);
5733 mplist__conc (p, elt);
5736 free_im_list (im_config_list);
5737 im_config_list = NULL;
5739 /* Next, reflect customization to the actual plist to be written. */
5740 data = tail = mplist ();
5741 MPLIST_DO (plist, im_custom_list)
5743 MPlist *pl = MPLIST_PLIST (plist);
5744 MSymbol language, name, extra;
5745 MInputMethodInfo *custom, *im_info;
5747 language = MPLIST_SYMBOL (pl);
5748 pl = MPLIST_NEXT (pl);
5749 name = MPLIST_SYMBOL (pl);
5750 pl = MPLIST_NEXT (pl);
5751 extra = MPLIST_SYMBOL (pl);
5752 pl = MPLIST_NEXT (pl);
5753 custom = MPLIST_VAL (pl);
5754 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5755 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5757 im_info = lookup_im_info (im_info_list, language, name, extra);
5761 config_all_commands (im_info);
5763 config_all_variables (im_info);
5767 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5769 MPLIST_DO (p, custom->cmds)
5770 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5772 if (! MPLIST_TAIL_P (p))
5776 mplist_add (elt, Mplist, pl);
5777 M17N_OBJECT_UNREF (pl);
5778 pl = mplist_add (pl, Msymbol, Mcommand);
5779 MPLIST_DO (p, custom->cmds)
5780 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5781 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5784 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5786 MPLIST_DO (p, custom->vars)
5787 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5789 if (! MPLIST_TAIL_P (p))
5794 mplist_add (elt, Mplist, pl);
5795 M17N_OBJECT_UNREF (pl);
5796 pl = mplist_add (pl, Msymbol, Mvariable);
5797 MPLIST_DO (p, custom->vars)
5798 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5799 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5805 mplist_push (elt, Mplist, pl);
5806 M17N_OBJECT_UNREF (pl);
5807 pl = mplist_add (pl, Msymbol, Minput_method);
5808 pl = mplist_add (pl, Msymbol, language);
5809 pl = mplist_add (pl, Msymbol, name);
5811 pl = mplist_add (pl, Msymbol, extra);
5812 tail = mplist_add (tail, Mplist, elt);
5813 M17N_OBJECT_UNREF (elt);
5817 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5818 ret = mdatabase__save (im_custom_mdb, data);
5819 mdatabase__unlock (im_custom_mdb);
5820 M17N_OBJECT_UNREF (data);
5821 return (ret < 0 ? -1 : 1);
5828 @name Obsolete functions
5831 @name Obsolete ¤Ê´Ø¿ô
5837 @brief Get a list of variables of an input method (obsolete).
5839 This function is obsolete. Use minput_get_variable () instead.
5841 The minput_get_variables () function returns a plist (#MPlist) of
5842 variables used to control the behavior of the input method
5843 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5844 (@ref m17nPlist) of the following format:
5847 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5848 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5852 @c VARNAME is a symbol representing the variable name.
5854 @c DOC-MTEXT is an M-text describing the variable.
5856 @c DEFAULT-VALUE is the default value of the variable. It is a
5857 symbol, integer, or M-text.
5859 @c VALUEs (if any) specifies the possible values of the variable.
5860 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5861 @c TO), where @c FROM and @c TO specifies a range of possible
5864 For instance, suppose an input method has the variables:
5866 @li name:intvar, description:"value is an integer",
5867 initial value:0, value-range:0..3,10,20
5869 @li name:symvar, description:"value is a symbol",
5870 initial value:nil, value-range:a, b, c, nil
5872 @li name:txtvar, description:"value is an M-text",
5873 initial value:empty text, no value-range (i.e. any text)
5875 Then, the returned plist is as follows.
5878 (intvar ("value is an integer" 0 (0 3) 10 20)
5879 symvar ("value is a symbol" nil a b c nil)
5880 txtvar ("value is an M-text" ""))
5884 If the input method uses any variables, a pointer to #MPlist is
5885 returned. As the plist is kept in the library, the caller must not
5886 modify nor free it. If the input method does not use any
5887 variable, @c NULL is returned. */
5889 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5891 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5892 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5893 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5897 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5898 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5902 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5904 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5906 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5909 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5910 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5911 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5913 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5915 @li name:intvar, ÀâÌÀ:"value is an integer",
5916 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5918 @li name:symvar, ÀâÌÀ:"value is a symbol",
5919 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5921 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5922 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5924 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5927 (intvar ("value is an integer" 0 (0 3) 10 20)
5928 symvar ("value is a symbol" nil a b c nil)
5929 txtvar ("value is an M-text" ""))
5933 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5934 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5935 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5938 minput_get_variables (MSymbol language, MSymbol name)
5940 MInputMethodInfo *im_info;
5945 im_info = get_im_info (language, name, Mnil, Mvariable);
5946 if (! im_info || ! im_info->configured_vars)
5949 M17N_OBJECT_UNREF (im_info->bc_vars);
5950 im_info->bc_vars = mplist ();
5951 MPLIST_DO (vars, im_info->configured_vars)
5953 MPlist *plist = MPLIST_PLIST (vars);
5954 MPlist *elt = mplist ();
5956 mplist_push (im_info->bc_vars, Mplist, elt);
5957 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5958 elt = MPLIST_NEXT (elt);
5959 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5960 M17N_OBJECT_UNREF (elt);
5962 return im_info->bc_vars;
5968 @brief Set the initial value of an input method variable.
5970 The minput_set_variable () function sets the initial value of
5971 input method variable $VARIABLE to $VALUE for the input method
5972 specified by $LANGUAGE and $NAME.
5974 By default, the initial value is 0.
5976 This setting gets effective in a newly opened input method.
5979 If the operation was successful, 0 is returned. Otherwise -1 is
5980 returned, and #merror_code is set to #MERROR_IM. */
5982 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5984 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5985 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5986 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5988 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5990 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5993 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5994 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5997 minput_set_variable (MSymbol language, MSymbol name,
5998 MSymbol variable, void *value)
6001 MInputMethodInfo *im_info;
6006 if (variable == Mnil)
6007 MERROR (MERROR_IM, -1);
6008 plist = minput_get_variable (language, name, variable);
6009 plist = MPLIST_PLIST (plist);
6010 plist = MPLIST_NEXT (plist);
6012 mplist_add (pl, MPLIST_KEY (plist), value);
6013 ret = minput_config_variable (language, name, variable, pl);
6014 M17N_OBJECT_UNREF (pl);
6017 im_info = get_im_info (language, name, Mnil, Mvariable);
6026 @brief Get information about input method commands.
6028 The minput_get_commands () function returns information about
6029 input method commands of the input method specified by $LANGUAGE
6030 and $NAME. An input method command is a pseudo key event to which
6031 one or more actual input key sequences are assigned.
6033 There are two kinds of commands, global and local. Global
6034 commands are used by multiple input methods for the same purpose,
6035 and have global key assignments. Local commands are used only by
6036 a specific input method, and have only local key assignments.
6038 Each input method may locally change key assignments for global
6039 commands. The global key assignment for a global command is
6040 effective only when the current input method does not have local
6041 key assignments for that command.
6043 If $NAME is #Mnil, information about global commands is returned.
6044 In this case $LANGUAGE is ignored.
6046 If $NAME is not #Mnil, information about those commands that have
6047 local key assignments in the input method specified by $LANGUAGE
6048 and $NAME is returned.
6051 If no input method commands are found, this function returns @c NULL.
6053 Otherwise, a pointer to a plist is returned. The key of each
6054 element in the plist is a symbol representing a command, and the
6055 value is a plist of the form COMMAND-INFO described below.
6057 The first element of COMMAND-INFO has the key #Mtext, and the
6058 value is an M-text describing the command.
6060 If there are no more elements, that means no key sequences are
6061 assigned to the command. Otherwise, each of the remaining
6062 elements has the key #Mplist, and the value is a plist whose keys are
6063 #Msymbol and values are symbols representing input keys, which are
6064 currently assigned to the command.
6066 As the returned plist is kept in the library, the caller must not
6067 modify nor free it. */
6069 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6071 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6072 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6073 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6074 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6076 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6077 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6078 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6079 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6081 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6082 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6083 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6086 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6087 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6089 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6090 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6094 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6096 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6097 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6098 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6100 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6101 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6102 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6105 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6106 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6107 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6108 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6109 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6111 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6112 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6115 minput_get_commands (MSymbol language, MSymbol name)
6117 MInputMethodInfo *im_info;
6122 im_info = get_im_info (language, name, Mnil, Mcommand);
6123 if (! im_info || ! im_info->configured_vars)
6125 M17N_OBJECT_UNREF (im_info->bc_cmds);
6126 im_info->bc_cmds = mplist ();
6127 MPLIST_DO (cmds, im_info->configured_cmds)
6129 MPlist *plist = MPLIST_PLIST (cmds);
6130 MPlist *elt = mplist ();
6132 mplist_push (im_info->bc_cmds, Mplist, elt);
6133 mplist_add (elt, MPLIST_SYMBOL (plist),
6134 mplist_copy (MPLIST_NEXT (plist)));
6135 M17N_OBJECT_UNREF (elt);
6137 return im_info->bc_cmds;
6143 @brief Assign a key sequence to an input method command (obsolete).
6145 This function is obsolete. Use minput_config_command () instead.
6147 The minput_assign_command_keys () function assigns input key
6148 sequence $KEYSEQ to input method command $COMMAND for the input
6149 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6150 key sequence is assigned globally no matter what $LANGUAGE is.
6151 Otherwise the key sequence is assigned locally.
6153 Each element of $KEYSEQ must have the key $Msymbol and the value
6154 must be a symbol representing an input key.
6156 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6157 globally or locally.
6159 This assignment gets effective in a newly opened input method.
6162 If the operation was successful, 0 is returned. Otherwise -1 is
6163 returned, and #merror_code is set to #MERROR_IM. */
6165 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6167 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6168 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6169 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6170 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6171 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6173 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6174 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6176 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6177 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6179 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6182 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6183 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6186 minput_assign_command_keys (MSymbol language, MSymbol name,
6187 MSymbol command, MPlist *keyseq)
6193 if (command == Mnil)
6194 MERROR (MERROR_IM, -1);
6199 if (! check_command_keyseq (keyseq))
6200 MERROR (MERROR_IM, -1);
6202 mplist_add (plist, Mplist, keyseq);
6207 ret = minput_config_command (language, name, command, keyseq);
6208 M17N_OBJECT_UNREF (keyseq);
6215 @brief Call a callback function
6217 The minput_callback () functions calls a callback function
6218 $COMMAND assigned for the input context $IC. The caller must set
6219 specific elements in $IC->plist if the callback function requires.
6222 If there exists a specified callback function, 0 is returned.
6223 Otherwise -1 is returned. By side effects, $IC->plist may be
6227 minput_callback (MInputContext *ic, MSymbol command)
6229 MInputCallbackFunc func;
6231 if (! ic->im->driver.callback_list)
6233 func = ((MInputCallbackFunc)
6234 mplist_get_func (ic->im->driver.callback_list, command));
6237 (func) (ic, command);
6244 /*** @addtogroup m17nDebug */
6250 @brief Dump an input method.
6252 The mdebug_dump_im () function prints the input method $IM in a
6253 human readable way to the stderr. $INDENT specifies how many
6254 columns to indent the lines but the first one.
6257 This function returns $IM. */
6259 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6261 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6262 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6265 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6268 mdebug_dump_im (MInputMethod *im, int indent)
6270 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6273 prefix = (char *) alloca (indent + 1);
6274 memset (prefix, 32, indent);
6275 prefix[indent] = '\0';
6277 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6278 msymbol_name (im->name));
6279 mdebug_dump_mtext (im_info->title, 0, 0);
6280 if (im->name != Mnil)
6284 MPLIST_DO (state, im_info->states)
6286 fprintf (stderr, "\n%s ", prefix);
6287 dump_im_state (MPLIST_VAL (state), indent + 2);
6290 fprintf (stderr, ")");