1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 @anchor 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 #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 #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> ³°ÉôÆþÎϥ᥽¥Ã¥É @anchor foreign-input-method
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï #Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 #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 /** Symbols to load an input method data. */
171 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
173 /** Symbols for actions. */
174 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
175 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
176 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
177 static MSymbol Mless_equal, Mgreater_equal;
178 static MSymbol Mcond;
179 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
181 /** Special action symbol. */
182 static MSymbol Mat_reload;
184 static MSymbol M_candidates;
186 static MSymbol Mcandidate_list, Mcandidate_index;
188 static MSymbol Minit, Mfini;
190 /** Symbols for variables. */
191 static MSymbol Mcandidates_group_size, Mcandidates_charset;
193 /** Symbols for key events. */
194 static MSymbol one_char_symbol[256];
196 static MSymbol M_key_alias;
198 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
200 static MSymbol M_gettext;
202 /** Structure to hold a map. */
206 /** List of actions to take when we reach the map. In a root map,
207 the actions are executed only when there is no more key. */
210 /** List of deeper maps. If NULL, this is a terminal map. */
213 /** List of actions to take when we leave the map successfully. In
214 a root map, the actions are executed only when none of submaps
215 handle the current key. */
216 MPlist *branch_actions;
219 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
225 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
232 /** Name of the state. */
235 /** Title of the state, or NULL. */
238 /** Key translation map of the state. Built by merging all maps of
243 #define CUSTOM_FILE "config.mic"
245 static MPlist *load_im_info_keys;
247 /* List of input method information. The format is:
248 (LANGUAGE NAME t:IM_INFO ... ... ...) */
249 static MPlist *im_info_list;
251 /* Database for user's customization file. */
252 static MDatabase *im_custom_mdb;
254 /* List of input method information loaded from im_custom_mdb. The
255 format is the same as im_info_list. */
256 static MPlist *im_custom_list;
258 /* List of input method information configured by
259 minput_config_command and minput_config_variable. The format is
260 the same as im_info_list. */
261 static MPlist *im_config_list;
263 /* Global input method information. It points into the element of
264 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
266 static MInputMethodInfo *global_info;
268 static int update_global_info (void);
269 static int update_custom_info (void);
270 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
277 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
278 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
279 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
280 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
281 char buf[6], buf2[32], buf3[2];
283 /* Maximum case: '\215', C-M-m, C-M-M, M-Return, C-A-m, C-A-M, A-Return
284 plus one for cyclic alias. */
287 M_key_alias = msymbol (" key-alias");
291 /* Aliases for 0x00-0x1F */
295 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
299 alias[j++] = msymbol (buf3);
300 alias[j++] = one_char_symbol[i] = msymbol (buf);
301 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
305 /* Ex: `Escape' == `C-[' */
306 alias[j++] = msymbol (key_names[i]);
308 if (buf[2] >= 'A' && buf[2] <= 'Z')
310 /* Ex: `C-a' == `C-A' */
312 alias[j++] = msymbol (buf);
316 /* Establish cyclic alias chain. */
319 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
322 /* Aliases for 0x20-0x7E */
324 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
326 one_char_symbol[i] = msymbol (buf + 2);
327 if (i >= 'A' && i <= 'Z')
329 /* Ex: `A' == `S-A' == `S-a'. */
330 alias[0] = alias[3] = one_char_symbol[i];
331 alias[1] = msymbol (buf);
333 alias[2] = msymbol (buf);
335 for (j = 0; j < 3; j++)
336 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
340 /* Aliases for 0x7F */
342 alias[0] = alias[3] = msymbol (buf3);
343 alias[1] = one_char_symbol[127] = msymbol ("Delete");
344 alias[2] = msymbol ("C-?");
345 for (j = 0; j < 3; j++)
346 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
348 /* Aliases for 0x80-0x9F */
350 /* buf[1] = '-'; -- already done */
354 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
358 alias[j++] = msymbol (buf3);
359 /* `C-M-a' == `C-A-a' */
361 alias[j++] = one_char_symbol[i] = msymbol (buf);
363 alias[j++] = msymbol (buf);
364 if (key_names[i - 128])
366 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
368 strcpy (buf2 + 2, key_names[i - 128]);
369 alias[j++] = msymbol (buf2);
371 alias[j++] = msymbol (buf2);
373 if (buf[4] >= 'A' && buf[4] <= 'Z')
375 /* Ex: `C-M-a' == `C-M-A'. */
378 alias[j++] = msymbol (buf);
380 alias[j++] = msymbol (buf);
384 /* Establish cyclic alias chain. */
387 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
390 /* Aliases for 0xA0-0xFF */
391 for (i = 160, buf[4] = ' '; i < 255; i++, buf[4]++)
395 alias[j++] = msymbol (buf3);
397 alias[j++] = one_char_symbol[i] = msymbol (buf + 2);
399 alias[j++] = msymbol (buf + 2);
402 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
405 buf3[0] = (char) 255;
406 alias[0] = alias[3] = msymbol (buf3);
407 alias[1] = one_char_symbol[255] = msymbol ("M-Delete");
408 alias[2] = msymbol ("A-Delete");
409 for (j = 0; j < 3; j++)
410 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
412 /* Aliases for keys that can't be mapped to one-char-symbol
414 /* buf is already set to "C-?-". */
415 for (i = ' '; i <= '~'; i++)
429 alias[0] = alias[2] = msymbol (buf);
431 alias[1] = msymbol (buf);
432 for (j = 0; j < 2; j++)
433 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
436 Minput_method = msymbol ("input-method");
437 Mtitle = msymbol ("title");
438 Mmacro = msymbol ("macro");
439 Mmodule = msymbol ("module");
440 Mmap = msymbol ("map");
441 Mstate = msymbol ("state");
442 Minclude = msymbol ("include");
443 Minsert = msymbol ("insert");
444 M_candidates = msymbol (" candidates");
445 Mdelete = msymbol ("delete");
446 Mmove = msymbol ("move");
447 Mmark = msymbol ("mark");
448 Mpushback = msymbol ("pushback");
449 Mpop = msymbol ("pop");
450 Mundo = msymbol ("undo");
451 Mcall = msymbol ("call");
452 Mshift = msymbol ("shift");
453 Mselect = msymbol ("select");
454 Mshow = msymbol ("show");
455 Mhide = msymbol ("hide");
456 Mcommit = msymbol ("commit");
457 Munhandle = msymbol ("unhandle");
458 Mset = msymbol ("set");
459 Madd = msymbol ("add");
460 Msub = msymbol ("sub");
461 Mmul = msymbol ("mul");
462 Mdiv = msymbol ("div");
463 Mequal = msymbol ("=");
464 Mless = msymbol ("<");
465 Mgreater = msymbol (">");
466 Mless_equal = msymbol ("<=");
467 Mgreater_equal = msymbol (">=");
468 Mcond = msymbol ("cond");
469 Mplus = msymbol ("+");
470 Mminus = msymbol ("-");
471 Mstar = msymbol ("*");
472 Mslash = msymbol ("/");
473 Mand = msymbol ("&");
475 Mnot = msymbol ("!");
477 Mat_reload = msymbol ("-reload");
479 Mcandidates_group_size = msymbol ("candidates-group-size");
480 Mcandidates_charset = msymbol ("candidates-charset");
482 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
483 Mcandidate_index = msymbol (" candidate-index");
485 Minit = msymbol ("init");
486 Mfini = msymbol ("fini");
488 Mdescription = msymbol ("description");
489 Mcommand = msymbol ("command");
490 Mvariable = msymbol ("variable");
491 Mglobal = msymbol ("global");
492 Mconfig = msymbol ("config");
493 M_gettext = msymbol ("_");
495 load_im_info_keys = mplist ();
496 mplist_add (load_im_info_keys, Mstate, Mnil);
497 mplist_push (load_im_info_keys, Mmap, Mnil);
499 im_info_list = mplist ();
500 im_config_list = im_custom_list = NULL;
501 im_custom_mdb = NULL;
502 update_custom_info ();
504 update_global_info ();
506 fully_initialized = 1;
509 #define MINPUT__INIT() \
511 if (! fully_initialized) \
512 fully_initialize (); \
517 marker_code (MSymbol sym, int surrounding)
523 name = MSYMBOL_NAME (sym);
524 return (name[0] != '@' ? -1
525 : (((name[1] >= '0' && name[1] <= '9')
526 || name[1] == '<' || name[1] == '>' || name[1] == '='
527 || name[1] == '[' || name[1] == ']'
529 && name[2] == '\0') ? name[1]
530 : (name[1] != '+' && name[1] != '-') ? -1
531 : (name[2] == '\0' || surrounding) ? name[1]
536 /* Return a plist containing an integer value of VAR. The plist must
540 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
542 MPlist *plist = mplist__assq (ic_info->vars, var);
546 plist = MPLIST_PLIST (plist);
547 return MPLIST_NEXT (plist);
551 mplist_push (ic_info->vars, Mplist, plist);
552 M17N_OBJECT_UNREF (plist);
553 plist = mplist_add (plist, Msymbol, var);
554 plist = mplist_add (plist, Minteger, (void *) 0);
559 get_surrounding_text (MInputContext *ic, int len)
563 mplist_push (ic->plist, Minteger, (void *) len);
564 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
565 && MPLIST_MTEXT_P (ic->plist))
566 mt = MPLIST_MTEXT (ic->plist);
567 mplist_pop (ic->plist);
572 delete_surrounding_text (MInputContext *ic, int pos)
574 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
576 mplist_push (ic->plist, Minteger, (void *) pos);
577 minput_callback (ic, Minput_delete_surrounding_text);
578 mplist_pop (ic->plist);
581 M17N_OBJECT_UNREF (ic_info->preceding_text);
582 ic_info->preceding_text = NULL;
586 M17N_OBJECT_UNREF (ic_info->following_text);
587 ic_info->following_text = NULL;
592 get_preceding_char (MInputContext *ic, int pos)
594 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
598 if (pos && ic_info->preceding_text)
600 len = mtext_nchars (ic_info->preceding_text);
602 return mtext_ref_char (ic_info->preceding_text, len - pos);
604 mt = get_surrounding_text (ic, - pos);
607 len = mtext_nchars (mt);
608 if (ic_info->preceding_text)
610 if (mtext_nchars (ic_info->preceding_text) < len)
612 M17N_OBJECT_UNREF (ic_info->preceding_text);
613 ic_info->preceding_text = mt;
616 M17N_OBJECT_UNREF (mt);
619 ic_info->preceding_text = mt;
622 return mtext_ref_char (ic_info->preceding_text, len - pos);
626 get_following_char (MInputContext *ic, int pos)
628 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
632 if (ic_info->following_text)
634 len = mtext_nchars (ic_info->following_text);
636 return mtext_ref_char (ic_info->following_text, pos);
638 mt = get_surrounding_text (ic, pos + 1);
641 len = mtext_nchars (mt);
642 if (ic_info->following_text)
644 if (mtext_nchars (ic_info->following_text) < len)
646 M17N_OBJECT_UNREF (ic_info->following_text);
647 ic_info->following_text = mt;
650 M17N_OBJECT_UNREF (mt);
653 ic_info->following_text = mt;
656 return mtext_ref_char (ic_info->following_text, pos);
660 surrounding_pos (MSymbol sym, int *pos)
666 name = MSYMBOL_NAME (sym);
668 && (name[1] == '-' ? (name[2] >= '1' && name[2] <= '9')
669 : name[1] == '+' ? (name[2] >= '0' && name[2] <= '9')
672 *pos = name[1] == '-' ? - atoi (name + 2) : atoi (name + 2);
679 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
681 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
683 MText *preedit = ic->preedit;
684 int len = mtext_nchars (preedit);
686 if (MPLIST_INTEGER_P (arg))
687 return MPLIST_INTEGER (arg);
689 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
692 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
694 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
697 return ic_info->key_head;
698 if ((code == '-' || code == '+'))
700 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
704 pos = atoi (name + 1);
705 if (pos == 0 && code == '-')
706 return get_preceding_char (ic, 0);
707 pos = ic->cursor_pos + pos;
710 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
711 return mtext_ref_char (ic->produced,
712 mtext_len (ic->produced) + pos);
713 return get_preceding_char (ic, - pos);
716 return get_following_char (ic, pos - len);
719 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
721 else if (code >= '0' && code <= '9')
723 else if (code == '=')
724 pos = ic->cursor_pos;
725 else if (code == '[')
726 pos = ic->cursor_pos - 1;
727 else if (code == ']')
728 pos = ic->cursor_pos + 1;
729 else if (code == '<')
731 else if (code == '>')
733 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
737 parse_expression (MPlist *plist)
741 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
743 if (! MPLIST_PLIST_P (plist))
745 plist = MPLIST_PLIST (plist);
746 op = MPLIST_SYMBOL (plist);
747 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
748 && op != Mand && op != Mor && op != Mnot
749 && op != Mless && op != Mgreater && op != Mequal
750 && op != Mless_equal && op != Mgreater_equal)
751 MERROR (MERROR_IM, -1);
752 MPLIST_DO (plist, MPLIST_NEXT (plist))
753 if (parse_expression (plist) < 0)
759 resolve_expression (MInputContext *ic, MPlist *plist)
764 if (MPLIST_INTEGER_P (plist))
765 return MPLIST_INTEGER (plist);
766 if (MPLIST_SYMBOL_P (plist))
767 return integer_value (ic, plist, 1);
768 if (! MPLIST_PLIST_P (plist))
770 plist = MPLIST_PLIST (plist);
771 if (! MPLIST_SYMBOL_P (plist))
773 op = MPLIST_SYMBOL (plist);
774 plist = MPLIST_NEXT (plist);
775 val = resolve_expression (ic, plist);
777 MPLIST_DO (plist, MPLIST_NEXT (plist))
778 val += resolve_expression (ic, plist);
779 else if (op == Mminus)
780 MPLIST_DO (plist, MPLIST_NEXT (plist))
781 val -= resolve_expression (ic, plist);
782 else if (op == Mstar)
783 MPLIST_DO (plist, MPLIST_NEXT (plist))
784 val *= resolve_expression (ic, plist);
785 else if (op == Mslash)
786 MPLIST_DO (plist, MPLIST_NEXT (plist))
787 val /= resolve_expression (ic, plist);
789 MPLIST_DO (plist, MPLIST_NEXT (plist))
790 val &= resolve_expression (ic, plist);
792 MPLIST_DO (plist, MPLIST_NEXT (plist))
793 val |= resolve_expression (ic, plist);
796 else if (op == Mless)
797 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
798 else if (op == Mequal)
799 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
800 else if (op == Mgreater)
801 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
802 else if (op == Mless_equal)
803 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
804 else if (op == Mgreater_equal)
805 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
809 /* Parse PLIST as an action list. PLIST should have this form:
810 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
811 Return 0 if successfully parsed, otherwise return -1. */
814 parse_action_list (MPlist *plist, MPlist *macros)
816 MPLIST_DO (plist, plist)
818 if (MPLIST_MTEXT_P (plist))
820 /* This is a short form of (insert MTEXT). */
821 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
822 MERROR (MERROR_IM, -1); */
824 else if (MPLIST_PLIST_P (plist)
825 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
826 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
830 /* This is a short form of (insert (GROUPS *)). */
831 MPLIST_DO (pl, MPLIST_PLIST (plist))
833 if (MPLIST_PLIST_P (pl))
837 MPLIST_DO (elt, MPLIST_PLIST (pl))
838 if (! MPLIST_MTEXT_P (elt)
839 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
840 MERROR (MERROR_IM, -1);
844 if (! MPLIST_MTEXT_P (pl)
845 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
846 MERROR (MERROR_IM, -1);
850 else if (MPLIST_INTEGER_P (plist))
852 int c = MPLIST_INTEGER (plist);
854 if (c < 0 || c > MCHAR_MAX)
855 MERROR (MERROR_IM, -1);
857 else if (MPLIST_PLIST_P (plist)
858 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
860 MPlist *pl = MPLIST_PLIST (plist);
861 MSymbol action_name = MPLIST_SYMBOL (pl);
863 pl = MPLIST_NEXT (pl);
865 if (action_name == M_candidates)
867 /* This is an already regularised action. */
870 if (action_name == Minsert)
872 if (MPLIST_MTEXT_P (pl))
874 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
875 MERROR (MERROR_IM, -1);
877 else if (MPLIST_INTEGER_P (pl))
879 int c = MPLIST_INTEGER (pl);
881 if (c < 0 || c > MCHAR_MAX)
882 MERROR (MERROR_IM, -1);
884 else if (MPLIST_PLIST_P (pl))
886 MPLIST_DO (pl, MPLIST_PLIST (pl))
888 if (MPLIST_PLIST_P (pl))
892 MPLIST_DO (elt, MPLIST_PLIST (pl))
893 if (! MPLIST_MTEXT_P (elt)
894 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
895 MERROR (MERROR_IM, -1);
899 if (! MPLIST_MTEXT_P (pl)
900 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
901 MERROR (MERROR_IM, -1);
905 else if (! MPLIST_SYMBOL_P (pl))
906 MERROR (MERROR_IM, -1);
908 else if (action_name == Mselect
909 || action_name == Mdelete
910 || action_name == Mmove)
912 if (parse_expression (pl) < 0)
915 else if (action_name == Mmark
916 || action_name == Mcall
917 || action_name == Mshift)
919 if (! MPLIST_SYMBOL_P (pl))
920 MERROR (MERROR_IM, -1);
922 else if (action_name == Mundo)
924 if (! MPLIST_TAIL_P (pl))
926 if (! MPLIST_SYMBOL_P (pl)
927 && ! MPLIST_INTEGER_P (pl))
928 MERROR (MERROR_IM, -1);
931 else if (action_name == Mpushback)
933 if (MPLIST_MTEXT_P (pl))
935 MText *mt = MPLIST_MTEXT (pl);
937 if (mtext_nchars (mt) != mtext_nbytes (mt))
938 MERROR (MERROR_IM, -1);
940 else if (MPLIST_PLIST_P (pl))
944 MPLIST_DO (p, MPLIST_PLIST (pl))
945 if (! MPLIST_SYMBOL_P (p))
946 MERROR (MERROR_IM, -1);
948 else if (! MPLIST_INTEGER_P (pl))
949 MERROR (MERROR_IM, -1);
951 else if (action_name == Mset || action_name == Madd
952 || action_name == Msub || action_name == Mmul
953 || action_name == Mdiv)
955 if (! MPLIST_SYMBOL_P (pl))
956 MERROR (MERROR_IM, -1);
957 if (parse_expression (MPLIST_NEXT (pl)) < 0)
960 else if (action_name == Mequal || action_name == Mless
961 || action_name == Mgreater || action_name == Mless_equal
962 || action_name == Mgreater_equal)
964 if (parse_expression (pl) < 0
965 || parse_expression (MPLIST_NEXT (pl)) < 0)
967 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
968 if (! MPLIST_PLIST_P (pl))
969 MERROR (MERROR_IM, -1);
970 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
971 MERROR (MERROR_IM, -1);
972 pl = MPLIST_NEXT (pl);
973 if (MPLIST_PLIST_P (pl)
974 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
975 MERROR (MERROR_IM, -1);
977 else if (action_name == Mshow || action_name == Mhide
978 || action_name == Mcommit || action_name == Munhandle
979 || action_name == Mpop)
981 else if (action_name == Mcond)
984 if (! MPLIST_PLIST_P (pl))
985 MERROR (MERROR_IM, -1);
987 else if (! macros || ! mplist_get (macros, action_name))
988 MERROR (MERROR_IM, -1);
990 else if (! MPLIST_SYMBOL_P (plist))
991 MERROR (MERROR_IM, -1);
998 resolve_command (MPlist *cmds, MSymbol command)
1002 if (! cmds || ! (plist = mplist__assq (cmds, command)))
1004 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
1005 plist = MPLIST_NEXT (plist);
1006 plist = MPLIST_NEXT (plist);
1007 plist = MPLIST_NEXT (plist);
1011 /* Load a translation into MAP from PLIST.
1012 PLIST has this form:
1013 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
1016 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
1017 MPlist *branch_actions, MPlist *macros)
1022 if (MPLIST_MTEXT_P (keylist))
1024 MText *mt = MPLIST_MTEXT (keylist);
1026 len = mtext_nchars (mt);
1027 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
1029 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1030 for (i = 0; i < len; i++)
1031 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1037 if (MFAILP (MPLIST_PLIST_P (keylist)))
1039 elt = MPLIST_PLIST (keylist);
1040 len = MPLIST_LENGTH (elt);
1041 if (MFAILP (len > 0))
1043 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1044 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1046 if (MPLIST_INTEGER_P (elt))
1048 int c = MPLIST_INTEGER (elt);
1050 if (MFAILP (c >= 0 && c < 0x100))
1052 keyseq[i] = one_char_symbol[c];
1056 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1058 keyseq[i] = MPLIST_SYMBOL (elt);
1063 for (i = 0; i < len; i++)
1065 MIMMap *deeper = NULL;
1068 deeper = mplist_get (map->submaps, keyseq[i]);
1070 map->submaps = mplist ();
1073 /* Fixme: It is better to make all deeper maps at once. */
1074 MSTRUCT_CALLOC (deeper, MERROR_IM);
1075 mplist_put (map->submaps, keyseq[i], deeper);
1080 /* We reach a terminal map. */
1081 if (map->map_actions
1082 || map->branch_actions)
1083 /* This map is already defined. We avoid overriding it. */
1086 if (! MPLIST_TAIL_P (map_actions))
1088 if (parse_action_list (map_actions, macros) < 0)
1089 MERROR (MERROR_IM, -1);
1090 map->map_actions = map_actions;
1094 map->branch_actions = branch_actions;
1095 M17N_OBJECT_REF (branch_actions);
1101 /* Load a branch from PLIST into MAP. PLIST has this form:
1102 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1105 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1108 MPlist *branch_actions;
1110 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1112 map_name = MPLIST_SYMBOL (plist);
1113 plist = MPLIST_NEXT (plist);
1114 if (MPLIST_TAIL_P (plist))
1115 branch_actions = NULL;
1116 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1119 branch_actions = plist;
1120 if (map_name == Mnil)
1122 map->branch_actions = branch_actions;
1124 M17N_OBJECT_REF (branch_actions);
1126 else if (map_name == Mt)
1128 map->map_actions = branch_actions;
1130 M17N_OBJECT_REF (branch_actions);
1132 else if (im_info->maps)
1134 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1135 if (! plist && im_info->configured_vars)
1137 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1139 if (p && MPLIST_PLIST_P (p))
1141 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1142 if (MPLIST_SYMBOL_P (p))
1143 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1148 MPLIST_DO (plist, plist)
1150 MPlist *keylist, *map_actions;
1152 if (! MPLIST_PLIST_P (plist))
1153 MERROR (MERROR_IM, -1);
1154 keylist = MPLIST_PLIST (plist);
1155 map_actions = MPLIST_NEXT (keylist);
1156 if (MPLIST_SYMBOL_P (keylist))
1158 MSymbol command = MPLIST_SYMBOL (keylist);
1161 if (MFAILP (command != Mat_reload))
1163 pl = resolve_command (im_info->configured_cmds, command);
1167 load_translation (map, pl, map_actions, branch_actions,
1171 load_translation (map, keylist, map_actions, branch_actions,
1180 /* Load a macro from PLIST into IM_INFO->macros.
1181 PLIST has this form:
1182 PLIST ::= ( MACRO-NAME ACTION * )
1183 IM_INFO->macros is a plist of macro names vs action list. */
1186 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1191 if (! MPLIST_SYMBOL_P (plist))
1192 MERROR (MERROR_IM, -1);
1193 name = MPLIST_SYMBOL (plist);
1194 plist = MPLIST_NEXT (plist);
1195 if (MFAILP (! MPLIST_TAIL_P (plist)))
1196 MERROR (MERROR_IM, -1);
1197 pl = mplist_get (im_info->macros, name);
1198 M17N_OBJECT_UNREF (pl);
1199 mplist_put (im_info->macros, name, plist);
1200 M17N_OBJECT_REF (plist);
1204 /* Load an external module from PLIST, and return a pointer to
1207 PLIST has this form:
1208 PLIST ::= ( MODULE-NAME FUNCTION * )
1209 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *).
1211 On error, return NULL. */
1213 static MIMExternalModule *
1214 load_external_module (MPlist *plist)
1219 MIMExternalModule *external;
1223 if (MPLIST_MTEXT_P (plist))
1224 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1225 else if (MPLIST_SYMBOL_P (plist))
1226 module = MPLIST_SYMBOL (plist);
1227 module_file = alloca (strlen (M17N_MODULE_DIR) + 1
1228 + strlen (MSYMBOL_NAME (module))
1229 + strlen (DLOPEN_SHLIB_EXT) + 1);
1230 sprintf (module_file, "%s/%s%s",
1231 M17N_MODULE_DIR, MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1233 handle = dlopen (module_file, RTLD_NOW);
1234 if (MFAILP (handle))
1236 func_list = mplist ();
1237 MPLIST_DO (plist, MPLIST_NEXT (plist))
1239 if (! MPLIST_SYMBOL_P (plist))
1240 MERROR_GOTO (MERROR_IM, err_label);
1241 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1244 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1247 MSTRUCT_MALLOC (external, MERROR_IM);
1248 external->name = module;
1249 external->handle = handle;
1250 external->func_list = func_list;
1254 M17N_OBJECT_UNREF (func_list);
1260 unload_external_module (MIMExternalModule *external)
1262 dlclose (external->handle);
1263 M17N_OBJECT_UNREF (external->func_list);
1268 free_map (MIMMap *map, int top)
1273 M17N_OBJECT_UNREF (map->map_actions);
1276 MPLIST_DO (plist, map->submaps)
1277 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1278 M17N_OBJECT_UNREF (map->submaps);
1280 M17N_OBJECT_UNREF (map->branch_actions);
1285 free_state (void *object)
1287 MIMState *state = object;
1289 M17N_OBJECT_UNREF (state->title);
1291 free_map (state->map, 1);
1295 /** Load a state from PLIST into a newly allocated state object.
1296 PLIST has this form:
1297 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1298 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1299 Return the state object. */
1302 load_state (MInputMethodInfo *im_info, MPlist *plist)
1306 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1308 M17N_OBJECT (state, free_state, MERROR_IM);
1309 state->name = MPLIST_SYMBOL (plist);
1310 plist = MPLIST_NEXT (plist);
1311 if (MPLIST_MTEXT_P (plist))
1313 state->title = MPLIST_MTEXT (plist);
1314 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1315 Mlanguage, im_info->language);
1316 M17N_OBJECT_REF (state->title);
1317 plist = MPLIST_NEXT (plist);
1319 MSTRUCT_CALLOC (state->map, MERROR_IM);
1320 MPLIST_DO (plist, plist)
1322 if (MFAILP (MPLIST_PLIST_P (plist)))
1324 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1329 /* Return a newly created IM_INFO for an input method specified by
1330 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1332 static MInputMethodInfo *
1333 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1336 MInputMethodInfo *im_info;
1339 if (name == Mnil && extra == Mnil)
1340 language = Mt, extra = Mglobal;
1341 MSTRUCT_CALLOC (im_info, MERROR_IM);
1343 im_info->language = language;
1344 im_info->name = name;
1345 im_info->extra = extra;
1348 mplist_add (plist, Mplist, elt);
1349 M17N_OBJECT_UNREF (elt);
1350 elt = mplist_add (elt, Msymbol, language);
1351 elt = mplist_add (elt, Msymbol, name);
1352 elt = mplist_add (elt, Msymbol, extra);
1353 mplist_add (elt, Mt, im_info);
1359 fini_im_info (MInputMethodInfo *im_info)
1363 M17N_OBJECT_UNREF (im_info->cmds);
1364 M17N_OBJECT_UNREF (im_info->configured_cmds);
1365 M17N_OBJECT_UNREF (im_info->bc_cmds);
1366 M17N_OBJECT_UNREF (im_info->vars);
1367 M17N_OBJECT_UNREF (im_info->configured_vars);
1368 M17N_OBJECT_UNREF (im_info->bc_vars);
1369 M17N_OBJECT_UNREF (im_info->description);
1370 M17N_OBJECT_UNREF (im_info->title);
1371 if (im_info->states)
1373 MPLIST_DO (plist, im_info->states)
1375 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1377 M17N_OBJECT_UNREF (state);
1379 M17N_OBJECT_UNREF (im_info->states);
1382 if (im_info->macros)
1384 MPLIST_DO (plist, im_info->macros)
1385 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1386 M17N_OBJECT_UNREF (im_info->macros);
1389 if (im_info->externals)
1391 MPLIST_DO (plist, im_info->externals)
1393 unload_external_module (MPLIST_VAL (plist));
1394 MPLIST_KEY (plist) = Mt;
1396 M17N_OBJECT_UNREF (im_info->externals);
1400 MPLIST_DO (plist, im_info->maps)
1402 MPlist *p = MPLIST_PLIST (plist);
1404 M17N_OBJECT_UNREF (p);
1406 M17N_OBJECT_UNREF (im_info->maps);
1413 free_im_info (MInputMethodInfo *im_info)
1415 fini_im_info (im_info);
1420 free_im_list (MPlist *plist)
1424 MPLIST_DO (pl, plist)
1426 MInputMethodInfo *im_info;
1428 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1429 im_info = MPLIST_VAL (elt);
1430 free_im_info (im_info);
1432 M17N_OBJECT_UNREF (plist);
1435 static MInputMethodInfo *
1436 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1438 if (name == Mnil && extra == Mnil)
1439 language = Mt, extra = Mglobal;
1440 while ((plist = mplist__assq (plist, language)))
1442 MPlist *elt = MPLIST_PLIST (plist);
1444 plist = MPLIST_NEXT (plist);
1445 elt = MPLIST_NEXT (elt);
1446 if (MPLIST_SYMBOL (elt) != name)
1448 elt = MPLIST_NEXT (elt);
1449 if (MPLIST_SYMBOL (elt) != extra)
1451 elt = MPLIST_NEXT (elt);
1452 return MPLIST_VAL (elt);
1457 static void load_im_info (MPlist *, MInputMethodInfo *);
1459 #define get_custom_info(im_info) \
1461 ? lookup_im_info (im_custom_list, (im_info)->language, \
1462 (im_info)->name, (im_info)->extra) \
1465 #define get_config_info(im_info) \
1467 ? lookup_im_info (im_config_list, (im_info)->language, \
1468 (im_info)->name, (im_info)->extra) \
1472 update_custom_info (void)
1478 if (mdatabase__check (im_custom_mdb) > 0)
1483 MDatabaseInfo *custom_dir_info;
1484 char custom_path[PATH_MAX + 1];
1486 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1487 if (! custom_dir_info->filename
1488 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1490 strcpy (custom_path, custom_dir_info->filename);
1491 strcat (custom_path, CUSTOM_FILE);
1492 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1498 free_im_list (im_custom_list);
1499 im_custom_list = NULL;
1501 plist = mdatabase_load (im_custom_mdb);
1504 im_custom_list = mplist ();
1506 MPLIST_DO (pl, plist)
1508 MSymbol language, name, extra;
1509 MInputMethodInfo *im_info;
1510 MPlist *im_data, *p;
1512 if (! MPLIST_PLIST_P (pl))
1514 p = MPLIST_PLIST (pl);
1515 im_data = MPLIST_NEXT (p);
1516 if (! MPLIST_PLIST_P (p))
1518 p = MPLIST_PLIST (p);
1519 if (! MPLIST_SYMBOL_P (p)
1520 || MPLIST_SYMBOL (p) != Minput_method)
1522 p = MPLIST_NEXT (p);
1523 if (! MPLIST_SYMBOL_P (p))
1525 language = MPLIST_SYMBOL (p);
1526 p = MPLIST_NEXT (p);
1527 if (! MPLIST_SYMBOL_P (p))
1529 name = MPLIST_SYMBOL (p);
1530 p = MPLIST_NEXT (p);
1531 if (MPLIST_TAIL_P (p))
1533 else if (MPLIST_SYMBOL_P (p))
1534 extra = MPLIST_SYMBOL (p);
1535 if (language == Mnil || (name == Mnil && extra == Mnil))
1537 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1538 load_im_info (im_data, im_info);
1540 M17N_OBJECT_UNREF (plist);
1545 update_global_info (void)
1551 int ret = mdatabase__check (global_info->mdb);
1555 fini_im_info (global_info);
1559 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1563 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1565 if (! global_info->mdb
1566 || ! (plist = mdatabase_load (global_info->mdb)))
1569 load_im_info (plist, global_info);
1570 M17N_OBJECT_UNREF (plist);
1575 /* Return an IM_INFO for the input method specified by LANGUAGE, NAME,
1576 and EXTRA. KEY, if not Mnil, tells which kind of information about
1577 the input method is necessary, and the returned IM_INFO may contain
1578 only that information. */
1580 static MInputMethodInfo *
1581 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1584 MInputMethodInfo *im_info;
1587 if (name == Mnil && extra == Mnil)
1588 language = Mt, extra = Mglobal;
1589 im_info = lookup_im_info (im_info_list, language, name, extra);
1592 if (key == Mnil ? im_info->states != NULL
1593 : key == Mcommand ? im_info->cmds != NULL
1594 : key == Mvariable ? im_info->vars != NULL
1595 : key == Mtitle ? im_info->title != NULL
1596 : key == Mdescription ? im_info->description != NULL
1598 /* IM_INFO already contains required information. */
1600 /* We have not yet loaded required information. */
1604 mdb = mdatabase_find (Minput_method, language, name, extra);
1607 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1612 plist = mdatabase_load (im_info->mdb);
1616 mplist_push (load_im_info_keys, key, Mt);
1617 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1618 mplist_pop (load_im_info_keys);
1622 MERROR (MERROR_IM, im_info);
1623 update_global_info ();
1624 load_im_info (plist, im_info);
1625 M17N_OBJECT_UNREF (plist);
1628 if (! im_info->cmds)
1629 im_info->cmds = mplist ();
1630 if (! im_info->vars)
1631 im_info->vars = mplist ();
1632 if (! im_info->states)
1633 im_info->states = mplist ();
1635 if (! im_info->title
1636 && (key == Mnil || key == Mtitle))
1637 im_info->title = (name == Mnil ? mtext ()
1638 : mtext_from_data (MSYMBOL_NAME (name),
1639 MSYMBOL_NAMELEN (name),
1640 MTEXT_FORMAT_US_ASCII));
1644 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1645 If updated, but got unloadable, return -1. Otherwise, update
1646 contents of IM_INFO from the new database, and return 1. */
1649 reload_im_info (MInputMethodInfo *im_info)
1654 update_custom_info ();
1655 update_global_info ();
1656 check = mdatabase__check (im_info->mdb);
1659 plist = mdatabase_load (im_info->mdb);
1662 fini_im_info (im_info);
1663 load_im_info (plist, im_info);
1664 M17N_OBJECT_UNREF (plist);
1665 if (! im_info->cmds)
1666 im_info->cmds = mplist ();
1667 if (! im_info->vars)
1668 im_info->vars = mplist ();
1669 if (! im_info->title)
1671 MSymbol name = im_info->name;
1673 im_info->title = (name == Mnil ? mtext ()
1674 : mtext_from_data (MSYMBOL_NAME (name),
1675 MSYMBOL_NAMELEN (name),
1676 MTEXT_FORMAT_US_ASCII));
1681 static MInputMethodInfo *
1682 get_im_info_by_tags (MPlist *plist)
1687 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1688 i++, plist = MPLIST_NEXT (plist))
1689 tag[i] = MPLIST_SYMBOL (plist);
1694 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1699 check_description (MPlist *plist)
1703 if (MPLIST_MTEXT_P (plist))
1705 if (MPLIST_PLIST_P (plist))
1707 MPlist *pl = MPLIST_PLIST (plist);
1709 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1711 pl =MPLIST_NEXT (pl);
1712 if (MFAILP (MPLIST_MTEXT_P (pl)))
1714 mt = MPLIST_MTEXT (pl);
1715 M17N_OBJECT_REF (mt);
1718 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1720 if (translated == (char *) MTEXT_DATA (mt))
1721 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1722 if (translated != (char *) MTEXT_DATA (mt))
1724 M17N_OBJECT_UNREF (mt);
1725 mt = mtext__from_data (translated, strlen (translated),
1726 MTEXT_FORMAT_UTF_8, 1);
1730 mplist_set (plist, Mtext, mt);
1731 M17N_OBJECT_UNREF (mt);
1734 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1740 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1744 check_command_keyseq (MPlist *keyseq)
1746 if (MPLIST_PLIST_P (keyseq))
1748 MPlist *p = MPLIST_PLIST (keyseq);
1751 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1755 if (MPLIST_MTEXT_P (keyseq))
1757 MText *mt = MPLIST_MTEXT (keyseq);
1760 for (i = 0; i < mtext_nchars (mt); i++)
1761 if (mtext_ref_char (mt, i) >= 256)
1768 /* Load command defitions from PLIST into IM_INFO->cmds.
1770 PLIST is well-formed and has this form;
1771 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1772 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1773 M-text or a plist of symbols.
1775 The returned list has the same form, but for each element...
1777 (1) If DESCRIPTION and the rest are omitted, the element is not
1778 stored in the returned list.
1780 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1781 description in global_info->cmds (if any). */
1784 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1788 im_info->cmds = tail = mplist ();
1790 MPLIST_DO (plist, MPLIST_NEXT (plist))
1792 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1795 if (MFAILP (MPLIST_PLIST_P (plist)))
1797 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1798 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1800 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1801 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1803 if (MFAILP (im_info != global_info))
1804 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1808 if (! check_description (p))
1809 mplist_set (p, Msymbol, Mnil);
1810 p = MPLIST_NEXT (p);
1811 while (! MPLIST_TAIL_P (p))
1813 if (MFAILP (check_command_keyseq (p)))
1814 mplist__pop_unref (p);
1816 p = MPLIST_NEXT (p);
1819 tail = mplist_add (tail, Mplist, pl);
1824 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1825 MPlist *config_cmds)
1827 MPlist *global = NULL, *custom = NULL, *config = NULL;
1828 MSymbol name = MPLIST_SYMBOL (plist);
1830 MPlist *description, *keyseq;
1832 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1833 global = MPLIST_NEXT (MPLIST_PLIST (global));
1835 plist = MPLIST_NEXT (plist);
1836 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1838 description = plist;
1839 plist = MPLIST_NEXT (plist);
1843 description = global;
1844 if (! MPLIST_TAIL_P (plist))
1845 plist = MPLIST_NEXT (plist);
1847 if (MPLIST_TAIL_P (plist) && global)
1849 keyseq = MPLIST_NEXT (global);
1850 status = Minherited;
1858 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1860 status = Mconfigured;
1861 config = MPLIST_NEXT (MPLIST_PLIST (config));
1862 if (! MPLIST_TAIL_P (config))
1865 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1867 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1869 if (MPLIST_TAIL_P (this_keyseq))
1870 mplist__pop_unref (custom);
1873 status = Mcustomized;
1874 keyseq = this_keyseq;
1879 mplist_add (plist, Msymbol, name);
1881 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1883 mplist_add (plist, Msymbol, Mnil);
1884 mplist_add (plist, Msymbol, status);
1885 mplist__conc (plist, keyseq);
1890 config_all_commands (MInputMethodInfo *im_info)
1892 MPlist *global_cmds, *custom_cmds, *config_cmds;
1893 MInputMethodInfo *temp;
1894 MPlist *tail, *plist;
1896 M17N_OBJECT_UNREF (im_info->configured_cmds);
1898 if (MPLIST_TAIL_P (im_info->cmds)
1902 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1903 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1904 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1906 im_info->configured_cmds = tail = mplist ();
1907 MPLIST_DO (plist, im_info->cmds)
1909 MPlist *pl = config_command (MPLIST_PLIST (plist),
1910 global_cmds, custom_cmds, config_cmds);
1913 tail = mplist_add (tail, Mplist, pl);
1914 M17N_OBJECT_UNREF (pl);
1919 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1920 valid, return 0 if not. */
1923 check_variable_value (MPlist *val, MPlist *global)
1925 MSymbol type = MPLIST_KEY (val);
1926 MPlist *valids = MPLIST_NEXT (val);
1928 if (type != Minteger && type != Mtext && type != Msymbol)
1932 if (MPLIST_KEY (global) != Mt
1933 && MPLIST_KEY (global) != MPLIST_KEY (val))
1935 if (MPLIST_TAIL_P (valids))
1936 valids = MPLIST_NEXT (global);
1938 if (MPLIST_TAIL_P (valids))
1941 if (type == Minteger)
1943 int n = MPLIST_INTEGER (val);
1945 MPLIST_DO (valids, valids)
1947 if (MPLIST_INTEGER_P (valids))
1949 if (n == MPLIST_INTEGER (valids))
1952 else if (MPLIST_PLIST_P (valids))
1954 MPlist *p = MPLIST_PLIST (valids);
1955 int min_bound, max_bound;
1957 if (! MPLIST_INTEGER_P (p))
1958 MERROR (MERROR_IM, 0);
1959 min_bound = MPLIST_INTEGER (p);
1960 p = MPLIST_NEXT (p);
1961 if (! MPLIST_INTEGER_P (p))
1962 MERROR (MERROR_IM, 0);
1963 max_bound = MPLIST_INTEGER (p);
1964 if (n >= min_bound && n <= max_bound)
1969 else if (type == Msymbol)
1971 MSymbol sym = MPLIST_SYMBOL (val);
1973 MPLIST_DO (valids, valids)
1975 if (! MPLIST_SYMBOL_P (valids))
1976 MERROR (MERROR_IM, 0);
1977 if (sym == MPLIST_SYMBOL (valids))
1983 MText *mt = MPLIST_MTEXT (val);
1985 MPLIST_DO (valids, valids)
1987 if (! MPLIST_MTEXT_P (valids))
1988 MERROR (MERROR_IM, 0);
1989 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1994 return (! MPLIST_TAIL_P (valids));
1997 /* Load variable defitions from PLIST into IM_INFO->vars.
1999 PLIST is well-formed and has this form;
2000 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
2002 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
2004 The returned list has the same form, but for each element...
2006 (1) If DESCRIPTION and the rest are omitted, the element is not
2007 stored in the returned list.
2009 (2) If DESCRIPTION is nil, it is complemented by the corresponding
2010 description in global_info->vars (if any). */
2013 load_variables (MInputMethodInfo *im_info, MPlist *plist)
2015 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
2016 ? global_info->vars : NULL);
2019 im_info->vars = tail = mplist ();
2020 MPLIST_DO (plist, MPLIST_NEXT (plist))
2024 if (MFAILP (MPLIST_PLIST_P (plist)))
2026 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
2027 if (MFAILP (MPLIST_SYMBOL_P (pl)))
2029 if (im_info == global_info)
2031 /* Loading a global variable. */
2032 p = MPLIST_NEXT (pl);
2033 if (MPLIST_TAIL_P (p))
2034 mplist_add (p, Msymbol, Mnil);
2037 if (! check_description (p))
2038 mplist_set (p, Msymbol, Mnil);
2039 p = MPLIST_NEXT (p);
2040 if (MFAILP (! MPLIST_TAIL_P (p)
2041 && check_variable_value (p, NULL)))
2042 mplist_set (p, Mt, NULL);
2045 else if (im_info->mdb)
2047 /* Loading a local variable. */
2048 MSymbol name = MPLIST_SYMBOL (pl);
2049 MPlist *global = NULL;
2052 && (p = mplist__assq (global_vars, name)))
2054 /* P ::= ((NAME DESC ...) ...) */
2055 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2056 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2057 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2060 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2061 if (! MPLIST_TAIL_P (p))
2063 if (! check_description (p))
2064 mplist_set (p, Msymbol, Mnil);
2065 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2066 if (MFAILP (! MPLIST_TAIL_P (p)))
2067 mplist_set (p, Mt, NULL);
2070 MPlist *valid_values = MPLIST_NEXT (p);
2072 if (! MPLIST_TAIL_P (valid_values)
2073 ? MFAILP (check_variable_value (p, NULL))
2074 : global && MFAILP (check_variable_value (p, global)))
2075 mplist_set (p, Mt, NULL);
2081 /* Loading a variable customization. */
2082 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2083 if (MFAILP (! MPLIST_TAIL_P (p)))
2085 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2086 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2087 || MPLIST_MTEXT_P (p)))
2090 tail = mplist_add (tail, Mplist, pl);
2095 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2096 MPlist *config_vars)
2098 MPlist *global = NULL, *custom = NULL, *config = NULL;
2099 MSymbol name = MPLIST_SYMBOL (plist);
2101 MPlist *description = NULL, *value, *valids;
2105 global = mplist__assq (global_vars, name);
2107 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2110 plist = MPLIST_NEXT (plist);
2111 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2112 description = plist;
2114 description = global;
2116 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2118 if (MPLIST_TAIL_P (plist))
2120 /* Inherit from global (if any). */
2124 if (MPLIST_KEY (value) == Mt)
2126 valids = MPLIST_NEXT (global);
2127 status = Minherited;
2139 value = plist = MPLIST_NEXT (plist);
2140 valids = MPLIST_NEXT (value);
2141 if (MPLIST_KEY (value) == Mt)
2143 if (! MPLIST_TAIL_P (valids))
2146 valids = MPLIST_NEXT (global);
2150 if (config_vars && (config = mplist__assq (config_vars, name)))
2152 status = Mconfigured;
2153 config = MPLIST_NEXT (MPLIST_PLIST (config));
2154 if (! MPLIST_TAIL_P (config))
2157 if (MFAILP (check_variable_value (value, global ? global : plist)))
2161 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2163 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2165 if (MPLIST_TAIL_P (this_value))
2166 mplist__pop_unref (custom);
2170 if (MFAILP (check_variable_value (value, global ? global : plist)))
2172 status = Mcustomized;
2177 mplist_add (plist, Msymbol, name);
2179 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2181 mplist_add (plist, Msymbol, Mnil);
2182 mplist_add (plist, Msymbol, status);
2184 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2186 mplist_add (plist, Mt, NULL);
2187 if (valids && ! MPLIST_TAIL_P (valids))
2188 mplist__conc (plist, valids);
2192 /* Return a configured variable definition list based on
2193 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2194 get it from global_info->vars. */
2197 config_all_variables (MInputMethodInfo *im_info)
2199 MPlist *global_vars, *custom_vars, *config_vars;
2200 MInputMethodInfo *temp;
2201 MPlist *tail, *plist;
2203 M17N_OBJECT_UNREF (im_info->configured_vars);
2205 if (MPLIST_TAIL_P (im_info->vars)
2209 global_vars = im_info != global_info ? global_info->vars : NULL;
2210 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2211 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2213 im_info->configured_vars = tail = mplist ();
2214 MPLIST_DO (plist, im_info->vars)
2216 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2217 global_vars, custom_vars, config_vars);
2220 tail = mplist_add (tail, Mplist, pl);
2221 M17N_OBJECT_UNREF (pl);
2226 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2227 CONFIG contains configuration information of the input method. */
2230 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2234 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2236 load_commands (im_info, MPLIST_PLIST (pl));
2237 config_all_commands (im_info);
2238 pl = mplist_pop (pl);
2239 M17N_OBJECT_UNREF (pl);
2242 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2244 load_variables (im_info, MPLIST_PLIST (pl));
2245 config_all_variables (im_info);
2246 pl = mplist_pop (pl);
2247 M17N_OBJECT_UNREF (pl);
2250 MPLIST_DO (plist, plist)
2251 if (MPLIST_PLIST_P (plist))
2253 MPlist *elt = MPLIST_PLIST (plist);
2256 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2258 key = MPLIST_SYMBOL (elt);
2263 elt = MPLIST_NEXT (elt);
2264 if (MFAILP (MPLIST_MTEXT_P (elt)))
2266 im_info->title = MPLIST_MTEXT (elt);
2267 M17N_OBJECT_REF (im_info->title);
2269 else if (key == Mmap)
2271 pl = mplist__from_alist (MPLIST_NEXT (elt));
2274 if (! im_info->maps)
2278 mplist__conc (im_info->maps, pl);
2279 M17N_OBJECT_UNREF (pl);
2282 else if (key == Mmacro)
2284 if (! im_info->macros)
2285 im_info->macros = mplist ();
2286 MPLIST_DO (elt, MPLIST_NEXT (elt))
2288 if (MFAILP (MPLIST_PLIST_P (elt)))
2290 load_macros (im_info, MPLIST_PLIST (elt));
2293 else if (key == Mmodule)
2295 if (! im_info->externals)
2296 im_info->externals = mplist ();
2297 MPLIST_DO (elt, MPLIST_NEXT (elt))
2299 MIMExternalModule *external;
2301 if (MFAILP (MPLIST_PLIST_P (elt)))
2303 external = load_external_module (MPLIST_PLIST (elt));
2305 mplist_add (im_info->externals, external->name, external);
2308 else if (key == Mstate)
2310 MPLIST_DO (elt, MPLIST_NEXT (elt))
2314 if (MFAILP (MPLIST_PLIST_P (elt)))
2316 pl = MPLIST_PLIST (elt);
2317 if (! im_info->states)
2318 im_info->states = mplist ();
2319 state = load_state (im_info, MPLIST_PLIST (elt));
2322 mplist_put (im_info->states, state->name, state);
2325 else if (key == Minclude)
2327 /* elt ::= include (tag1 tag2 ...) key item ... */
2329 MInputMethodInfo *temp;
2331 elt = MPLIST_NEXT (elt);
2332 if (MFAILP (MPLIST_PLIST_P (elt)))
2334 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2337 elt = MPLIST_NEXT (elt);
2338 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2340 key = MPLIST_SYMBOL (elt);
2341 elt = MPLIST_NEXT (elt);
2344 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2346 if (! im_info->maps)
2347 im_info->maps = mplist ();
2348 MPLIST_DO (pl, temp->maps)
2350 p = MPLIST_VAL (pl);
2351 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2352 M17N_OBJECT_REF (p);
2355 else if (key == Mmacro)
2357 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2359 if (! im_info->macros)
2360 im_info->macros = mplist ();
2361 MPLIST_DO (pl, temp->macros)
2363 p = MPLIST_VAL (pl);
2364 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2365 M17N_OBJECT_REF (p);
2368 else if (key == Mstate)
2370 if (! temp->states || MPLIST_TAIL_P (temp->states))
2372 if (! im_info->states)
2373 im_info->states = mplist ();
2374 MPLIST_DO (pl, temp->states)
2376 MIMState *state = MPLIST_VAL (pl);
2378 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2379 M17N_OBJECT_REF (state);
2383 else if (key == Mdescription)
2385 if (im_info->description)
2387 elt = MPLIST_NEXT (elt);
2388 if (! check_description (elt))
2390 im_info->description = MPLIST_MTEXT (elt);
2391 M17N_OBJECT_REF (im_info->description);
2394 if (im_info->macros)
2396 MPLIST_DO (pl, im_info->macros)
2397 parse_action_list (MPLIST_PLIST (pl), im_info->macros);
2400 im_info->tick = time (NULL);
2405 static int take_action_list (MInputContext *ic, MPlist *action_list);
2406 static void preedit_commit (MInputContext *ic, int need_prefix);
2408 /* Shift to the state of name STATE_NAME. If STATE_NAME is `t', shift
2409 to the previous state (if any). If STATE_NAME is `nil', shift to
2410 the initial state. */
2413 shift_state (MInputContext *ic, MSymbol state_name)
2415 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2416 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2417 MIMState *orig_state = ic_info->state, *state;
2419 /* Find a state to shift to. If not found, shift to the initial
2421 if (state_name == Mt)
2423 if (! ic_info->prev_state)
2425 state = ic_info->prev_state;
2427 else if (state_name == Mnil)
2429 state = (MIMState *) MPLIST_VAL (im_info->states);
2433 state = (MIMState *) mplist_get (im_info->states, state_name);
2435 state = (MIMState *) MPLIST_VAL (im_info->states);
2441 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2442 MSYMBOL_NAME (orig_state->name),
2443 MSYMBOL_NAME (state->name));
2445 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2448 /* Enter the new state. */
2449 ic_info->state = state;
2450 ic_info->map = state->map;
2451 ic_info->state_key_head = ic_info->key_head;
2452 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2454 /* We have shifted to the initial state. */
2455 preedit_commit (ic, 0);
2456 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2457 ic_info->state_pos = ic->cursor_pos;
2458 if (state != orig_state || state_name == Mnil)
2460 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2462 /* Shifted to the initial state. */
2463 ic_info->prev_state = NULL;
2464 M17N_OBJECT_UNREF (ic_info->vars_saved);
2465 ic_info->vars_saved = mplist_copy (ic_info->vars);
2468 ic_info->prev_state = orig_state;
2471 ic->status = state->title;
2473 ic->status = im_info->title;
2474 ic->status_changed = 1;
2475 ic_info->state_hook = ic_info->map->map_actions;
2479 /* Find a candidate group that contains a candidate number INDEX from
2480 PLIST. Set START_INDEX to the first candidate number of the group,
2481 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2482 candidate group number if they are non-NULL. If INDEX is -1, find
2483 the last candidate group. */
2486 find_candidates_group (MPlist *plist, int index,
2487 int *start_index, int *end_index, int *group_index)
2489 int i = 0, gidx = 0, len;
2491 MPLIST_DO (plist, plist)
2493 if (MPLIST_MTEXT_P (plist))
2494 len = mtext_nchars (MPLIST_MTEXT (plist));
2496 len = mplist_length (MPLIST_PLIST (plist));
2497 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2503 *end_index = i + len;
2505 *group_index = gidx;
2514 /* Adjust markers for the change of preedit text.
2515 If FROM == TO, the change is insertion of INS chars.
2516 If FROM < TO and INS == 0, the change is deletion of the range.
2517 If FROM < TO and INS > 0, the change is replacement. */
2520 adjust_markers (MInputContext *ic, int from, int to, int ins)
2522 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2527 MPLIST_DO (markers, ic_info->markers)
2528 if (MPLIST_INTEGER (markers) > from)
2529 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2530 if (ic->cursor_pos >= from)
2531 ic->cursor_pos += ins;
2535 MPLIST_DO (markers, ic_info->markers)
2537 if (MPLIST_INTEGER (markers) >= to)
2538 MPLIST_VAL (markers)
2539 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2540 else if (MPLIST_INTEGER (markers) > from)
2541 MPLIST_VAL (markers) = (void *) from;
2543 if (ic->cursor_pos >= to)
2544 ic->cursor_pos += ins - (to - from);
2545 else if (ic->cursor_pos > from)
2546 ic->cursor_pos = from;
2552 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2554 int nchars = mt ? mtext_nchars (mt) : 1;
2558 mtext_ins (ic->preedit, pos, mt);
2559 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2563 mtext_ins_char (ic->preedit, pos, c, 1);
2565 MDEBUG_PRINT1 ("('%c')", c);
2567 MDEBUG_PRINT1 ("(U+%04X)", c);
2569 adjust_markers (ic, pos, pos, nchars);
2570 ic->preedit_changed = 1;
2575 preedit_delete (MInputContext *ic, int from, int to)
2577 mtext_del (ic->preedit, from, to);
2578 adjust_markers (ic, from, to, 0);
2579 ic->preedit_changed = 1;
2583 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2587 mtext_del (ic->preedit, from, to);
2590 mtext_ins (ic->preedit, from, mt);
2591 ins = mtext_nchars (mt);
2595 mtext_ins_char (ic->preedit, from, c, 1);
2598 adjust_markers (ic, from, to, ins);
2599 ic->preedit_changed = 1;
2604 preedit_commit (MInputContext *ic, int need_prefix)
2606 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2607 int preedit_len = mtext_nchars (ic->preedit);
2609 if (preedit_len > 0)
2613 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2614 Mcandidate_list, NULL, 0);
2615 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2616 Mcandidate_index, NULL, 0);
2617 mtext_cat (ic->produced, ic->preedit);
2623 MDEBUG_PRINT1 ("\n [IM] [%s]",
2624 MSYMBOL_NAME (ic_info->state->name));
2625 MDEBUG_PRINT (" (commit");
2626 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2627 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2631 mtext_reset (ic->preedit);
2632 mtext_reset (ic_info->preedit_saved);
2633 MPLIST_DO (p, ic_info->markers)
2635 ic->cursor_pos = ic_info->state_pos = 0;
2636 ic->preedit_changed = 1;
2637 ic_info->commit_key_head = ic_info->key_head;
2639 if (ic->candidate_list)
2641 M17N_OBJECT_UNREF (ic->candidate_list);
2642 ic->candidate_list = NULL;
2643 ic->candidate_index = 0;
2644 ic->candidate_from = ic->candidate_to = 0;
2645 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2646 if (ic->candidate_show)
2648 ic->candidate_show = 0;
2649 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2655 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2657 int code = marker_code (sym, 0);
2659 if (mt && (code == '[' || code == ']'))
2663 if (code == '[' && current > 0)
2665 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2669 else if (code == ']' && current < mtext_nchars (mt))
2671 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2677 return (code == '<' ? 0
2678 : code == '>' ? limit
2679 : code == '-' ? current - 1
2680 : code == '+' ? current + 1
2681 : code == '=' ? current
2682 : code - '0' > limit ? limit
2686 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2690 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2692 int from = mtext_property_start (prop);
2693 int to = mtext_property_end (prop);
2695 MPlist *candidate_list = mtext_property_value (prop);
2696 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2698 int ingroup_index = idx - start;
2701 candidate_list = mplist_copy (candidate_list);
2702 if (MPLIST_MTEXT_P (group))
2704 mt = MPLIST_MTEXT (group);
2705 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2713 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2714 i++, plist = MPLIST_NEXT (plist));
2715 mt = MPLIST_MTEXT (plist);
2716 preedit_replace (ic, from, to, mt, 0);
2717 to = from + mtext_nchars (mt);
2719 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2720 M17N_OBJECT_UNREF (candidate_list);
2721 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2722 ic->cursor_pos = to;
2726 get_select_charset (MInputContextInfo * ic_info)
2728 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2731 if (! MPLIST_VAL (plist))
2733 sym = MPLIST_SYMBOL (plist);
2736 return MCHARSET (sym);
2739 /* The returned plist must be UNREFed. */
2742 adjust_candidates (MPlist *plist, MCharset *charset)
2746 /* plist ::= MTEXT ... | PLIST ... */
2747 plist = mplist_copy (plist);
2748 if (MPLIST_MTEXT_P (plist))
2751 while (! MPLIST_TAIL_P (pl))
2753 /* pl ::= MTEXT ... */
2754 MText *mt = MPLIST_MTEXT (pl);
2758 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2760 c = mtext_ref_char (mt, i);
2761 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2765 mt = mtext_dup (mt);
2766 mplist_set (pl, Mtext, mt);
2767 M17N_OBJECT_UNREF (mt);
2770 mtext_del (mt, i, i + 1);
2773 if (mtext_len (mt) > 0)
2774 pl = MPLIST_NEXT (pl);
2778 M17N_OBJECT_UNREF (mt);
2782 else /* MPLIST_PLIST_P (plist) */
2785 while (! MPLIST_TAIL_P (pl))
2787 /* pl ::= (MTEXT ...) ... */
2788 MPlist *p = MPLIST_PLIST (pl);
2790 /* p ::= MTEXT ... */
2794 while (! MPLIST_TAIL_P (p0))
2796 MText *mt = MPLIST_MTEXT (p0);
2799 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2801 c = mtext_ref_char (mt, i);
2802 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2807 p0 = MPLIST_NEXT (p0);
2814 p = mplist_copy (p);
2815 mplist_set (pl, Mplist, p);
2816 M17N_OBJECT_UNREF (p);
2820 p0 = MPLIST_NEXT (p0);
2823 M17N_OBJECT_UNREF (mt);
2826 if (! MPLIST_TAIL_P (p))
2827 pl = MPLIST_NEXT (pl);
2831 M17N_OBJECT_UNREF (p);
2835 if (MPLIST_TAIL_P (plist))
2837 M17N_OBJECT_UNREF (plist);
2843 /* The returned Plist must be UNREFed. */
2846 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2848 MCharset *charset = get_select_charset (ic_info);
2853 plist = resolve_variable (ic_info, Mcandidates_group_size);
2854 column = MPLIST_INTEGER (plist);
2856 plist = MPLIST_PLIST (args);
2861 plist = adjust_candidates (plist, charset);
2866 M17N_OBJECT_REF (plist);
2871 if (MPLIST_MTEXT_P (plist))
2873 MText *mt = MPLIST_MTEXT (plist);
2874 MPlist *next = MPLIST_NEXT (plist);
2876 if (MPLIST_TAIL_P (next))
2877 M17N_OBJECT_REF (mt);
2880 mt = mtext_dup (mt);
2881 while (! MPLIST_TAIL_P (next))
2883 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2884 next = MPLIST_NEXT (next);
2887 M17N_OBJECT_UNREF (plist);
2889 len = mtext_nchars (mt);
2891 mplist_add (plist, Mtext, mt);
2894 for (i = 0; i < len; i += column)
2896 int to = (i + column < len ? i + column : len);
2897 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2899 mplist_add (plist, Mtext, sub);
2900 M17N_OBJECT_UNREF (sub);
2903 M17N_OBJECT_UNREF (mt);
2905 else if (MPLIST_PLIST_P (plist))
2907 MPlist *tail = plist;
2908 MPlist *new = mplist ();
2909 MPlist *this = mplist ();
2912 MPLIST_DO (tail, tail)
2914 MPlist *p = MPLIST_PLIST (tail);
2918 MText *mt = MPLIST_MTEXT (p);
2920 if (count == column)
2922 mplist_add (new, Mplist, this);
2923 M17N_OBJECT_UNREF (this);
2927 mplist_add (this, Mtext, mt);
2931 mplist_add (new, Mplist, this);
2932 M17N_OBJECT_UNREF (this);
2933 mplist_set (plist, Mnil, NULL);
2934 MPLIST_DO (tail, new)
2936 MPlist *elt = MPLIST_PLIST (tail);
2938 mplist_add (plist, Mplist, elt);
2940 M17N_OBJECT_UNREF (new);
2948 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2950 MPlist *action = NULL;
2954 if (MPLIST_SYMBOL_P (action_list))
2956 MSymbol var = MPLIST_SYMBOL (action_list);
2959 MPLIST_DO (p, ic_info->vars)
2960 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2962 if (MPLIST_TAIL_P (p))
2964 action = MPLIST_NEXT (MPLIST_PLIST (p));
2965 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2968 if (MPLIST_PLIST_P (action_list))
2970 action = MPLIST_PLIST (action_list);
2971 if (MPLIST_SYMBOL_P (action))
2973 name = MPLIST_SYMBOL (action);
2974 args = MPLIST_NEXT (action);
2976 && MPLIST_PLIST_P (args))
2977 mplist_set (action, Msymbol, M_candidates);
2979 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2982 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2983 mplist_push (action, Msymbol, M_candidates);
2984 mplist_set (action_list, Mplist, action);
2985 M17N_OBJECT_UNREF (action);
2988 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2991 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2992 mplist_push (action, Msymbol, Minsert);
2993 mplist_set (action_list, Mplist, action);
2994 M17N_OBJECT_UNREF (action);
2999 /* Perform list of actions in ACTION_LIST for the current input
3000 context IC. If unhandle action was not performed, return 0.
3001 Otherwise, return -1. */
3004 take_action_list (MInputContext *ic, MPlist *action_list)
3006 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3007 MPlist *candidate_list = ic->candidate_list;
3008 int candidate_index = ic->candidate_index;
3009 int candidate_show = ic->candidate_show;
3010 MTextProperty *prop;
3012 MPLIST_DO (action_list, action_list)
3014 MPlist *action = regularize_action (action_list, ic_info);
3020 name = MPLIST_SYMBOL (action);
3021 args = MPLIST_NEXT (action);
3023 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
3024 if (name == Minsert)
3026 if (MPLIST_SYMBOL_P (args))
3028 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3029 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3032 if (MPLIST_MTEXT_P (args))
3033 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3034 else /* MPLIST_INTEGER_P (args)) */
3035 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3037 else if (name == M_candidates)
3039 MPlist *plist = get_candidate_list (ic_info, args);
3045 if (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist))
3047 M17N_OBJECT_UNREF (plist);
3050 if (MPLIST_MTEXT_P (plist))
3052 preedit_insert (ic, ic->cursor_pos, NULL,
3053 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3058 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3060 preedit_insert (ic, ic->cursor_pos, mt, 0);
3061 len = mtext_nchars (mt);
3063 pl = mplist_copy (plist);
3064 M17N_OBJECT_UNREF (plist);
3065 mtext_put_prop (ic->preedit,
3066 ic->cursor_pos - len, ic->cursor_pos,
3067 Mcandidate_list, pl);
3068 M17N_OBJECT_UNREF (pl);
3069 mtext_put_prop (ic->preedit,
3070 ic->cursor_pos - len, ic->cursor_pos,
3071 Mcandidate_index, (void *) 0);
3073 else if (name == Mselect)
3076 int code, idx, gindex;
3077 int pos = ic->cursor_pos;
3079 int idx_decided = 0;
3082 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3085 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3086 group = find_candidates_group (mtext_property_value (prop), idx,
3087 &start, &end, &gindex);
3088 if (MPLIST_SYMBOL_P (args))
3090 code = marker_code (MPLIST_SYMBOL (args), 0);
3093 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3094 if (! MPLIST_INTEGER_P (args))
3096 idx = start + MPLIST_INTEGER (args);
3097 if (idx < start || idx >= end)
3105 if (code != '[' && code != ']')
3110 ? new_index (NULL, ic->candidate_index - start,
3111 end - start - 1, MPLIST_SYMBOL (args),
3113 : MPLIST_INTEGER (args)));
3116 find_candidates_group (mtext_property_value (prop), -1,
3121 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3126 int ingroup_index = idx - start;
3129 group = mtext_property_value (prop);
3130 len = mplist_length (group);
3143 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3144 idx += (MPLIST_MTEXT_P (group)
3145 ? mtext_nchars (MPLIST_MTEXT (group))
3146 : mplist_length (MPLIST_PLIST (group)));
3147 len = (MPLIST_MTEXT_P (group)
3148 ? mtext_nchars (MPLIST_MTEXT (group))
3149 : mplist_length (MPLIST_PLIST (group)));
3150 if (ingroup_index >= len)
3151 ingroup_index = len - 1;
3152 idx += ingroup_index;
3154 update_candidate (ic, prop, idx);
3155 MDEBUG_PRINT1 ("(%d)", idx);
3157 else if (name == Mshow)
3158 ic->candidate_show = 1;
3159 else if (name == Mhide)
3160 ic->candidate_show = 0;
3161 else if (name == Mdelete)
3163 int len = mtext_nchars (ic->preedit);
3167 if (MPLIST_SYMBOL_P (args)
3168 && surrounding_pos (MPLIST_SYMBOL (args), &pos))
3170 to = ic->cursor_pos + pos;
3173 delete_surrounding_text (ic, to);
3178 delete_surrounding_text (ic, to - len);
3184 to = (MPLIST_SYMBOL_P (args)
3185 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3187 : MPLIST_INTEGER (args));
3192 pos = to - ic->cursor_pos;
3194 MDEBUG_PRINT1 ("(%d)", pos);
3195 if (to < ic->cursor_pos)
3196 preedit_delete (ic, to, ic->cursor_pos);
3197 else if (to > ic->cursor_pos)
3198 preedit_delete (ic, ic->cursor_pos, to);
3200 else if (name == Mmove)
3202 int len = mtext_nchars (ic->preedit);
3204 = (MPLIST_SYMBOL_P (args)
3205 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3207 : MPLIST_INTEGER (args));
3213 if (pos != ic->cursor_pos)
3215 ic->cursor_pos = pos;
3216 ic->preedit_changed = 1;
3218 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3220 else if (name == Mmark)
3222 int code = marker_code (MPLIST_SYMBOL (args), 0);
3226 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3227 (void *) ic->cursor_pos);
3228 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3231 else if (name == Mpushback)
3233 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3237 if (MPLIST_SYMBOL_P (args))
3239 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3240 if (MPLIST_INTEGER_P (args))
3241 num = MPLIST_INTEGER (args);
3246 num = MPLIST_INTEGER (args);
3249 ic_info->key_head -= num;
3251 ic_info->key_head = 0;
3253 ic_info->key_head = - num;
3254 if (ic_info->key_head > ic_info->used)
3255 ic_info->key_head = ic_info->used;
3257 else if (MPLIST_MTEXT_P (args))
3259 MText *mt = MPLIST_MTEXT (args);
3260 int i, len = mtext_nchars (mt);
3263 ic_info->key_head--;
3264 for (i = 0; i < len; i++)
3266 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3267 if (ic_info->key_head + i < ic_info->used)
3268 ic_info->keys[ic_info->key_head + i] = key;
3270 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3275 MPlist *plist = MPLIST_PLIST (args), *pl;
3279 ic_info->key_head--;
3281 MPLIST_DO (pl, plist)
3283 key = MPLIST_SYMBOL (pl);
3284 if (ic_info->key_head < ic_info->used)
3285 ic_info->keys[ic_info->key_head + i] = key;
3287 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3292 else if (name == Mpop)
3294 if (ic_info->key_head < ic_info->used)
3295 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3297 else if (name == Mcall)
3299 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3300 MIMExternalFunc func = NULL;
3301 MSymbol module, func_name;
3302 MPlist *func_args, *val;
3305 module = MPLIST_SYMBOL (args);
3306 args = MPLIST_NEXT (args);
3307 func_name = MPLIST_SYMBOL (args);
3309 if (im_info->externals)
3311 MIMExternalModule *external
3312 = (MIMExternalModule *) mplist_get (im_info->externals,
3315 func = ((MIMExternalFunc)
3316 mplist_get_func (external->func_list, func_name));
3320 func_args = mplist ();
3321 mplist_add (func_args, Mt, ic);
3322 MPLIST_DO (args, MPLIST_NEXT (args))
3326 if (MPLIST_KEY (args) == Msymbol
3327 && MPLIST_KEY (args) != Mnil
3328 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3330 code = new_index (ic, ic->cursor_pos,
3331 mtext_nchars (ic->preedit),
3332 MPLIST_SYMBOL (args), ic->preedit);
3333 mplist_add (func_args, Minteger, (void *) code);
3336 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3338 val = (func) (func_args);
3339 M17N_OBJECT_UNREF (func_args);
3340 if (val && ! MPLIST_TAIL_P (val))
3341 ret = take_action_list (ic, val);
3342 M17N_OBJECT_UNREF (val);
3346 else if (name == Mshift)
3348 shift_state (ic, MPLIST_SYMBOL (args));
3350 else if (name == Mundo)
3352 int intarg = (MPLIST_TAIL_P (args)
3354 : integer_value (ic, args, 0));
3356 mtext_reset (ic->preedit);
3357 mtext_reset (ic_info->preedit_saved);
3358 mtext_reset (ic->produced);
3359 M17N_OBJECT_UNREF (ic_info->vars);
3360 ic_info->vars = mplist_copy (ic_info->vars_saved);
3361 ic->cursor_pos = ic_info->state_pos = 0;
3362 ic_info->state_key_head = ic_info->key_head
3363 = ic_info->commit_key_head = 0;
3365 shift_state (ic, Mnil);
3368 if (MPLIST_TAIL_P (args))
3373 ic_info->used += intarg;
3376 ic_info->used = intarg;
3379 else if (name == Mset || name == Madd || name == Msub
3380 || name == Mmul || name == Mdiv)
3382 MSymbol sym = MPLIST_SYMBOL (args);
3383 MPlist *value = resolve_variable (ic_info, sym);
3387 val1 = MPLIST_INTEGER (value);
3388 args = MPLIST_NEXT (args);
3389 val2 = resolve_expression (ic, args);
3391 val1 = val2, op = "=";
3392 else if (name == Madd)
3393 val1 += val2, op = "+=";
3394 else if (name == Msub)
3395 val1 -= val2, op = "-=";
3396 else if (name == Mmul)
3397 val1 *= val2, op = "*=";
3399 val1 /= val2, op = "/=";
3400 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3401 MSYMBOL_NAME (sym), op, val1, val1);
3402 mplist_set (value, Minteger, (void *) val1);
3404 else if (name == Mequal || name == Mless || name == Mgreater
3405 || name == Mless_equal || name == Mgreater_equal)
3408 MPlist *actions1, *actions2;
3411 val1 = resolve_expression (ic, args);
3412 args = MPLIST_NEXT (args);
3413 val2 = resolve_expression (ic, args);
3414 args = MPLIST_NEXT (args);
3415 actions1 = MPLIST_PLIST (args);
3416 args = MPLIST_NEXT (args);
3417 if (MPLIST_TAIL_P (args))
3420 actions2 = MPLIST_PLIST (args);
3421 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3422 if (name == Mequal ? val1 == val2
3423 : name == Mless ? val1 < val2
3424 : name == Mgreater ? val1 > val2
3425 : name == Mless_equal ? val1 <= val2
3428 MDEBUG_PRINT ("ok");
3429 ret = take_action_list (ic, actions1);
3433 MDEBUG_PRINT ("no");
3435 ret = take_action_list (ic, actions2);
3440 else if (name == Mcond)
3444 MPLIST_DO (args, args)
3449 if (! MPLIST_PLIST (args))
3451 cond = MPLIST_PLIST (args);
3452 if (resolve_expression (ic, cond) != 0)
3454 MDEBUG_PRINT1 ("(%dth)", idx);
3455 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3461 else if (name == Mcommit)
3463 preedit_commit (ic, 0);
3465 else if (name == Munhandle)
3467 preedit_commit (ic, 0);
3472 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3476 && (actions = mplist_get (im_info->macros, name)))
3478 if (take_action_list (ic, actions) < 0)
3484 if (ic->candidate_list)
3486 M17N_OBJECT_UNREF (ic->candidate_list);
3487 ic->candidate_list = NULL;
3489 if (ic->cursor_pos > 0
3490 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3493 ic->candidate_list = mtext_property_value (prop);
3494 M17N_OBJECT_REF (ic->candidate_list);
3496 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3498 ic->candidate_from = mtext_property_start (prop);
3499 ic->candidate_to = mtext_property_end (prop);
3502 if (candidate_list != ic->candidate_list)
3503 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3504 if (candidate_index != ic->candidate_index)
3505 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3506 if (candidate_show != ic->candidate_show)
3507 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3512 /* Handle the input key KEY in the current state and map specified in
3513 the input context IC. If KEY is handled correctly, return 0.
3514 Otherwise, return -1. */
3517 handle_key (MInputContext *ic)
3519 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3520 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3521 MIMMap *map = ic_info->map;
3522 MIMMap *submap = NULL;
3523 MSymbol key = ic_info->keys[ic_info->key_head];
3524 MSymbol alias = Mnil;
3527 if (ic_info->state_hook)
3529 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
3530 MSYMBOL_NAME (ic_info->state->name));
3531 take_action_list (ic, ic_info->state_hook);
3532 ic_info->state_hook = NULL;
3535 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3536 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3540 submap = mplist_get (map->submaps, key);
3543 && (alias = msymbol_get (alias, M_key_alias))
3545 submap = mplist_get (map->submaps, alias);
3550 if (! alias || alias == key)
3551 MDEBUG_PRINT (" submap-found");
3553 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3554 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3555 ic->preedit_changed = 1;
3556 ic->cursor_pos = ic_info->state_pos;
3557 ic_info->key_head++;
3558 ic_info->map = map = submap;
3559 if (map->map_actions)
3561 MDEBUG_PRINT (" map-actions:");
3562 if (take_action_list (ic, map->map_actions) < 0)
3564 MDEBUG_PRINT ("\n");
3568 else if (map->submaps)
3570 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3572 MSymbol key = ic_info->keys[i];
3573 char *name = msymbol_name (key);
3575 if (! name[0] || ! name[1])
3576 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3580 /* If this is the terminal map or we have shifted to another
3581 state, perform branch actions (if any). */
3582 if (! map->submaps || map != ic_info->map)
3584 if (map->branch_actions)
3586 MDEBUG_PRINT (" branch-actions:");
3587 if (take_action_list (ic, map->branch_actions) < 0)
3589 MDEBUG_PRINT ("\n");
3593 /* If MAP is still not the root map, shift to the current
3595 if (ic_info->map != ic_info->state->map)
3596 shift_state (ic, ic_info->state->name);
3601 /* MAP can not handle KEY. */
3603 /* Perform branch actions if any. */
3604 if (map->branch_actions)
3606 MDEBUG_PRINT (" branch-actions:");
3607 if (take_action_list (ic, map->branch_actions) < 0)
3609 MDEBUG_PRINT ("\n");
3614 if (map == ic_info->map)
3616 /* The above branch actions didn't change the state. */
3618 /* If MAP is the root map of the initial state, and there
3619 still exist an unhandled key, it means that the current
3620 input method can not handle it. */
3621 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3622 && ic_info->key_head < ic_info->used)
3624 MDEBUG_PRINT (" unhandled\n");
3625 ic_info->state_hook = map->map_actions;
3629 if (map != ic_info->state->map)
3631 /* MAP is not the root map. Shift to the root map of the
3633 shift_state (ic, ic_info->state->name);
3635 else if (! map->branch_actions)
3637 /* MAP is the root map without any default branch
3638 actions. Shift to the initial state. */
3639 shift_state (ic, Mnil);
3643 MDEBUG_PRINT ("\n");
3647 /* Initialize IC->ic_info. */
3650 init_ic_info (MInputContext *ic)
3652 MInputMethodInfo *im_info = ic->im->info;
3653 MInputContextInfo *ic_info = ic->info;
3656 MLIST_INIT1 (ic_info, keys, 8);;
3658 ic_info->markers = mplist ();
3660 ic_info->vars = mplist ();
3661 if (im_info->configured_vars)
3662 MPLIST_DO (plist, im_info->configured_vars)
3664 MPlist *pl = MPLIST_PLIST (plist);
3665 MSymbol name = MPLIST_SYMBOL (pl);
3667 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3668 if (MPLIST_KEY (pl) != Mt)
3670 MPlist *p = mplist ();
3672 mplist_push (ic_info->vars, Mplist, p);
3673 M17N_OBJECT_UNREF (p);
3674 mplist_add (p, Msymbol, name);
3675 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3678 ic_info->vars_saved = mplist_copy (ic_info->vars);
3680 if (im_info->externals)
3682 MPlist *func_args = mplist (), *plist;
3684 mplist_add (func_args, Mt, ic);
3685 MPLIST_DO (plist, im_info->externals)
3687 MIMExternalModule *external = MPLIST_VAL (plist);
3688 MIMExternalFunc func
3689 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3694 M17N_OBJECT_UNREF (func_args);
3697 ic_info->preedit_saved = mtext ();
3698 ic_info->tick = im_info->tick;
3701 /* Finalize IC->ic_info. */
3704 fini_ic_info (MInputContext *ic)
3706 MInputMethodInfo *im_info = ic->im->info;
3707 MInputContextInfo *ic_info = ic->info;
3709 if (im_info->externals)
3711 MPlist *func_args = mplist (), *plist;
3713 mplist_add (func_args, Mt, ic);
3714 MPLIST_DO (plist, im_info->externals)
3716 MIMExternalModule *external = MPLIST_VAL (plist);
3717 MIMExternalFunc func
3718 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3723 M17N_OBJECT_UNREF (func_args);
3726 MLIST_FREE1 (ic_info, keys);
3727 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3728 M17N_OBJECT_UNREF (ic_info->markers);
3729 M17N_OBJECT_UNREF (ic_info->vars);
3730 M17N_OBJECT_UNREF (ic_info->vars_saved);
3731 M17N_OBJECT_UNREF (ic_info->preceding_text);
3732 M17N_OBJECT_UNREF (ic_info->following_text);
3734 memset (ic_info, 0, sizeof (MInputContextInfo));
3738 re_init_ic (MInputContext *ic, int reload)
3740 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3741 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3742 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3744 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3745 preedit_changed = mtext_nchars (ic->preedit) > 0;
3746 cursor_pos_changed = ic->cursor_pos > 0;
3747 candidates_changed = 0;
3748 if (ic->candidate_list)
3750 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3751 M17N_OBJECT_UNREF (ic->candidate_list);
3752 ic->candidate_list = NULL;
3754 if (ic->candidate_show)
3756 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3757 ic->candidate_show = 0;
3759 if (ic->candidate_index > 0)
3761 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3762 ic->candidate_index = 0;
3763 ic->candidate_from = ic->candidate_to = 0;
3765 if (mtext_nchars (ic->produced) > 0)
3766 mtext_reset (ic->produced);
3767 if (mtext_nchars (ic->preedit) > 0)
3768 mtext_reset (ic->preedit);
3770 M17N_OBJECT_UNREF (ic->plist);
3771 ic->plist = mplist ();
3775 reload_im_info (im_info);
3776 if (! im_info->states)
3778 struct MIMState *state;
3780 M17N_OBJECT (state, free_state, MERROR_IM);
3781 state->name = msymbol ("init");
3782 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3783 MSTRUCT_CALLOC (state->map, MERROR_IM);
3784 im_info->states = mplist ();
3785 mplist_add (im_info->states, state->name, state);
3788 shift_state (ic, Mnil);
3790 ic->status_changed = status_changed;
3791 ic->preedit_changed = preedit_changed;
3792 ic->cursor_pos_changed = cursor_pos_changed;
3793 ic->candidates_changed = candidates_changed;
3797 reset_ic (MInputContext *ic, MSymbol ignore)
3799 MDEBUG_PRINT ("\n [IM] reset\n");
3804 open_im (MInputMethod *im)
3806 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3808 if (! im_info || ! im_info->states || MPLIST_LENGTH (im_info->states) == 0)
3809 MERROR (MERROR_IM, -1);
3816 close_im (MInputMethod *im)
3822 create_ic (MInputContext *ic)
3824 MInputContextInfo *ic_info;
3826 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3829 shift_state (ic, Mnil);
3834 destroy_ic (MInputContext *ic)
3841 check_reload (MInputContext *ic, MSymbol key)
3843 MInputMethodInfo *im_info = ic->im->info;
3844 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3848 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3852 MPLIST_DO (plist, plist)
3854 MSymbol this_key, alias;
3856 if (MPLIST_MTEXT_P (plist))
3858 MText *mt = MPLIST_MTEXT (plist);
3859 int c = mtext_ref_char (mt, 0);
3863 this_key = one_char_symbol[c];
3867 MPlist *pl = MPLIST_PLIST (plist);
3869 this_key = MPLIST_SYMBOL (pl);
3873 && (alias = msymbol_get (alias, M_key_alias))
3874 && alias != this_key);
3878 if (MPLIST_TAIL_P (plist))
3881 MDEBUG_PRINT ("\n [IM] reload");
3887 /** Handle the input key KEY in the current state and map of IC->info.
3888 If KEY is handled but no text is produced, return 0, otherwise
3894 filter (MInputContext *ic, MSymbol key, void *arg)
3896 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3897 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3900 if (check_reload (ic, key))
3903 if (! ic_info->state)
3905 ic_info->key_unhandled = 1;
3908 mtext_reset (ic->produced);
3909 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3910 M17N_OBJECT_UNREF (ic_info->preceding_text);
3911 M17N_OBJECT_UNREF (ic_info->following_text);
3912 ic_info->preceding_text = ic_info->following_text = NULL;
3913 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3914 ic_info->key_unhandled = 0;
3917 if (handle_key (ic) < 0)
3919 /* KEY was not handled. Delete it from the current key sequence. */
3920 if (ic_info->used > 0)
3922 memmove (ic_info->keys, ic_info->keys + 1,
3923 sizeof (int) * (ic_info->used - 1));
3925 if (ic_info->state_key_head > 0)
3926 ic_info->state_key_head--;
3927 if (ic_info->commit_key_head > 0)
3928 ic_info->commit_key_head--;
3930 /* This forces returning 1. */
3931 ic_info->key_unhandled = 1;
3937 reset_ic (ic, Mnil);
3938 ic_info->key_unhandled = 1;
3941 /* Break the loop if all keys were handled. */
3942 } while (ic_info->key_head < ic_info->used);
3944 /* If the current map is the root of the initial state, we should
3945 produce any preedit text in ic->produced. */
3946 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3947 preedit_commit (ic, 1);
3949 if (mtext_nchars (ic->produced) > 0)
3953 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3954 MSYMBOL_NAME (ic_info->state->name));
3955 for (i = 0; i < mtext_nchars (ic->produced); i++)
3956 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3960 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3961 Mlanguage, ic->im->language);
3963 if (ic_info->commit_key_head > 0)
3965 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3966 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3967 ic_info->used -= ic_info->commit_key_head;
3968 ic_info->key_head -= ic_info->commit_key_head;
3969 ic_info->state_key_head -= ic_info->commit_key_head;
3970 ic_info->commit_key_head = 0;
3972 if (ic_info->key_unhandled)
3975 ic_info->key_head = ic_info->state_key_head
3976 = ic_info->commit_key_head = 0;
3979 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3983 /** Return 1 if the last event or key was not handled, otherwise
3986 There is no need of looking up because ic->produced should already
3987 contain the produced text (if any).
3992 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3994 mtext_cat (mt, ic->produced);
3995 mtext_reset (ic->produced);
3996 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
4000 /* Input method command handler. */
4002 /* List of all (global and local) commands.
4003 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
4004 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
4005 Global commands are stored as (t (t COMMAND ...)) */
4008 /* Input method variable handler. */
4011 /* Support functions for mdebug_dump_im. */
4014 dump_im_map (MPlist *map_list, int indent)
4017 MSymbol key = MPLIST_KEY (map_list);
4018 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
4020 prefix = (char *) alloca (indent + 1);
4021 memset (prefix, 32, indent);
4022 prefix[indent] = '\0';
4024 fprintf (mdebug__output, "(\"%s\" ", msymbol_name (key));
4025 if (map->map_actions)
4026 mdebug_dump_plist (map->map_actions, indent + 2);
4029 MPLIST_DO (map_list, map->submaps)
4031 fprintf (mdebug__output, "\n%s ", prefix);
4032 dump_im_map (map_list, indent + 2);
4035 if (map->branch_actions)
4037 fprintf (mdebug__output, "\n%s (branch\n%s ", prefix, prefix);
4038 mdebug_dump_plist (map->branch_actions, indent + 4);
4039 fprintf (mdebug__output, ")");
4041 fprintf (mdebug__output, ")");
4046 dump_im_state (MIMState *state, int indent)
4051 prefix = (char *) alloca (indent + 1);
4052 memset (prefix, 32, indent);
4053 prefix[indent] = '\0';
4055 fprintf (mdebug__output, "(%s", msymbol_name (state->name));
4056 if (state->map->submaps)
4058 MPLIST_DO (map_list, state->map->submaps)
4060 fprintf (mdebug__output, "\n%s ", prefix);
4061 dump_im_map (map_list, indent + 2);
4064 fprintf (mdebug__output, ")");
4072 Minput_driver = msymbol ("input-driver");
4074 Minput_preedit_start = msymbol ("input-preedit-start");
4075 Minput_preedit_done = msymbol ("input-preedit-done");
4076 Minput_preedit_draw = msymbol ("input-preedit-draw");
4077 Minput_status_start = msymbol ("input-status-start");
4078 Minput_status_done = msymbol ("input-status-done");
4079 Minput_status_draw = msymbol ("input-status-draw");
4080 Minput_candidates_start = msymbol ("input-candidates-start");
4081 Minput_candidates_done = msymbol ("input-candidates-done");
4082 Minput_candidates_draw = msymbol ("input-candidates-draw");
4083 Minput_set_spot = msymbol ("input-set-spot");
4084 Minput_focus_move = msymbol ("input-focus-move");
4085 Minput_focus_in = msymbol ("input-focus-in");
4086 Minput_focus_out = msymbol ("input-focus-out");
4087 Minput_toggle = msymbol ("input-toggle");
4088 Minput_reset = msymbol ("input-reset");
4089 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4090 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4091 Mcustomized = msymbol ("customized");
4092 Mconfigured = msymbol ("configured");
4093 Minherited = msymbol ("inherited");
4095 minput_default_driver.open_im = open_im;
4096 minput_default_driver.close_im = close_im;
4097 minput_default_driver.create_ic = create_ic;
4098 minput_default_driver.destroy_ic = destroy_ic;
4099 minput_default_driver.filter = filter;
4100 minput_default_driver.lookup = lookup;
4101 minput_default_driver.callback_list = mplist ();
4102 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4103 M17N_FUNC (reset_ic));
4104 minput_driver = &minput_default_driver;
4106 fully_initialized = 0;
4113 if (fully_initialized)
4115 free_im_list (im_info_list);
4117 free_im_list (im_custom_list);
4119 free_im_list (im_config_list);
4120 M17N_OBJECT_UNREF (load_im_info_keys);
4123 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4124 M17N_OBJECT_UNREF (minput_driver->callback_list);
4129 minput__char_to_key (int c)
4131 if (c < 0 || c >= 0x100)
4134 return one_char_symbol[c];
4138 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4143 /*** @addtogroup m17nInputMethod */
4148 @brief Symbol whose name is "input-method".
4151 @brief "input-method" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
4153 MSymbol Minput_method;
4156 @name Variables: Predefined symbols for callback commands. */
4158 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4161 These are the predefined symbols that are used as the @c COMMAND
4162 argument of callback functions of an input method driver (see
4163 #MInputDriver::callback_list).
4165 Most of them do not require extra argument nor return any value;
4166 exceptions are these:
4168 @b Minput_get_surrounding_text: When a callback function assigned for
4169 this command is called, the first element of #MInputContext::plist
4170 has key #Minteger and the value specifies which portion of the
4171 surrounding text should be retrieved. If the value is positive,
4172 it specifies the number of characters following the current cursor
4173 position. If the value is negative, the absolute value specifies
4174 the number of characters preceding the current cursor position.
4175 If the value is zero, it means that the caller just wants to know
4176 if the surrounding text is currently supported or not.
4178 If the surrounding text is currently supported, the callback
4179 function must set the key of this element to #Mtext and the value
4180 to the retrieved M-text. The length of the M-text may be shorter
4181 than the requested number of characters, if the available text is
4182 not that long. The length can be zero in the worst case. Or, the
4183 length may be longer if an application thinks it is more efficient
4184 to return that length.
4186 If the surrounding text is not currently supported, the callback
4187 function should return without changing the first element of
4188 #MInputContext::plist.
4190 @b Minput_delete_surrounding_text: When a callback function assigned
4191 for this command is called, the first element of
4192 #MInputContext::plist has key #Minteger and the value specifies
4193 which portion of the surrounding text should be deleted in the
4194 same way as the case of Minput_get_surrounding_text. The callback
4195 function must delete the specified text. It should not alter
4196 #MInputContext::plist. */
4198 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4199 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4201 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4203 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4204 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4205 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4206 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4207 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4208 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4209 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4211 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4212 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4213 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4214 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4215 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4217 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4218 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4220 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4221 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4222 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4223 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4224 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4225 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4226 MSymbol Minput_preedit_start;
4227 MSymbol Minput_preedit_done;
4228 MSymbol Minput_preedit_draw;
4229 MSymbol Minput_status_start;
4230 MSymbol Minput_status_done;
4231 MSymbol Minput_status_draw;
4232 MSymbol Minput_candidates_start;
4233 MSymbol Minput_candidates_done;
4234 MSymbol Minput_candidates_draw;
4235 MSymbol Minput_set_spot;
4236 MSymbol Minput_toggle;
4237 MSymbol Minput_reset;
4238 MSymbol Minput_get_surrounding_text;
4239 MSymbol Minput_delete_surrounding_text;
4245 @name Variables: Predefined symbols for special input events.
4247 These are the predefined symbols that are used as the @c KEY
4248 argument of minput_filter (). */
4250 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4252 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4257 MSymbol Minput_focus_out;
4258 MSymbol Minput_focus_in;
4259 MSymbol Minput_focus_move;
4265 @name Variables: Predefined symbols used in input method information. */
4267 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4271 These are the predefined symbols describing status of input method
4272 command and variable, and are used in a return value of
4273 minput_get_command () and minput_get_variable (). */
4275 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4276 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4278 MSymbol Mcustomized;
4279 MSymbol Mconfigured;
4285 @brief The default driver for internal input methods.
4287 The variable #minput_default_driver is the default driver for
4288 internal input methods.
4290 The member MInputDriver::open_im () searches the m17n database for
4291 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4292 $NAME\> and loads it.
4294 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4295 programmers responsibility to set it to a plist of proper callback
4296 functions. Otherwise, no feedback information (e.g. preedit text)
4297 can be shown to users.
4299 The macro M17N_INIT () sets the variable #minput_driver to the
4300 pointer to this driver so that all internal input methods use it.
4302 Therefore, unless @c minput_driver is set differently, the driver
4303 dependent arguments $ARG of the functions whose name begins with
4304 "minput_" are all ignored. */
4306 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4308 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4310 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4311 \< #Minput_method, $LANGUAGE, $NAME\>
4312 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4314 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4315 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4316 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4317 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4319 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4320 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4322 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4323 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4325 MInputDriver minput_default_driver;
4329 @brief The driver for internal input methods.
4331 The variable #minput_driver is a pointer to the input method
4332 driver that is used by internal input methods. The macro
4333 M17N_INIT () initializes it to a pointer to #minput_default_driver
4334 if <m17n<EM></EM>.h> is included. */
4336 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4338 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4339 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4340 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4341 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4343 MInputDriver *minput_driver;
4347 The variable #Minput_driver is a symbol for a foreign input method.
4348 See @ref foreign-input-method "foreign input method" for the detail. */
4349 MSymbol Minput_driver;
4364 @brief Open an input method.
4366 The minput_open_im () function opens an input method whose
4367 language and name match $LANGUAGE and $NAME, and returns a pointer
4368 to the input method object newly allocated.
4370 This function at first decides a driver for the input method as
4373 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4374 #minput_driver is used.
4376 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4377 driver pointed to by the property value is used to open the input
4378 method. If $NAME has no such a property, @c NULL is returned.
4380 Then, the member MInputDriver::open_im () of the driver is
4383 $ARG is set in the member @c arg of the structure MInputMethod so
4384 that the driver can refer to it. */
4386 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4388 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4389 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4391 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4393 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4394 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4396 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4397 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4398 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4400 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4402 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4404 @latexonly \IPAlabel{minput_open} @endlatexonly
4409 minput_open_im (MSymbol language, MSymbol name, void *arg)
4412 MInputDriver *driver;
4416 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4417 msymbol_name (language), msymbol_name (name));
4421 MERROR (MERROR_IM, NULL);
4422 driver = minput_driver;
4426 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4428 MERROR (MERROR_IM, NULL);
4431 MSTRUCT_CALLOC (im, MERROR_IM);
4432 im->language = language;
4435 im->driver = *driver;
4436 if ((*im->driver.open_im) (im) < 0)
4438 MDEBUG_PRINT (" failed\n");
4442 MDEBUG_PRINT (" ok\n");
4449 @brief Close an input method.
4451 The minput_close_im () function closes the input method $IM, which
4452 must have been created by minput_open_im (). */
4455 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4457 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4458 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4461 minput_close_im (MInputMethod *im)
4463 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4464 msymbol_name (im->name), msymbol_name (im->language));
4465 (*im->driver.close_im) (im);
4467 MDEBUG_PRINT (" done\n");
4473 @brief Create an input context.
4475 The minput_create_ic () function creates an input context object
4476 associated with input method $IM, and calls callback functions
4477 corresponding to @b Minput_preedit_start, @b Minput_status_start, and
4478 @b Minput_status_draw in this order.
4481 If an input context is successfully created, minput_create_ic ()
4482 returns a pointer to it. Otherwise it returns @c NULL. */
4485 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4487 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4488 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4489 @b Minput_preedit_start, @b Minput_status_start, @b Minput_status_draw
4490 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4493 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4494 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4498 minput_create_ic (MInputMethod *im, void *arg)
4502 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4503 msymbol_name (im->name), msymbol_name (im->language));
4504 MSTRUCT_CALLOC (ic, MERROR_IM);
4507 ic->preedit = mtext ();
4508 ic->candidate_list = NULL;
4509 ic->produced = mtext ();
4510 ic->spot.x = ic->spot.y = 0;
4512 ic->plist = mplist ();
4513 if ((*im->driver.create_ic) (ic) < 0)
4515 MDEBUG_PRINT (" failed\n");
4516 M17N_OBJECT_UNREF (ic->preedit);
4517 M17N_OBJECT_UNREF (ic->produced);
4518 M17N_OBJECT_UNREF (ic->plist);
4523 if (im->driver.callback_list)
4525 minput_callback (ic, Minput_preedit_start);
4526 minput_callback (ic, Minput_status_start);
4527 minput_callback (ic, Minput_status_draw);
4530 MDEBUG_PRINT (" ok\n");
4537 @brief Destroy an input context.
4539 The minput_destroy_ic () function destroys the input context $IC,
4540 which must have been created by minput_create_ic (). It calls
4541 callback functions corresponding to @b Minput_preedit_done,
4542 @b Minput_status_done, and @b Minput_candidates_done in this order. */
4545 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4547 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4548 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4549 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4550 @b Minput_preedit_done, @b Minput_status_done, @b Minput_candidates_done
4551 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4555 minput_destroy_ic (MInputContext *ic)
4557 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4558 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4559 if (ic->im->driver.callback_list)
4561 minput_callback (ic, Minput_preedit_done);
4562 minput_callback (ic, Minput_status_done);
4563 minput_callback (ic, Minput_candidates_done);
4565 (*ic->im->driver.destroy_ic) (ic);
4566 M17N_OBJECT_UNREF (ic->preedit);
4567 M17N_OBJECT_UNREF (ic->produced);
4568 M17N_OBJECT_UNREF (ic->plist);
4569 MDEBUG_PRINT (" done\n");
4576 @brief Filter an input key.
4578 The minput_filter () function filters input key $KEY according to
4579 input context $IC, and calls callback functions corresponding to
4580 @b Minput_preedit_draw, @b Minput_status_draw, and
4581 @b Minput_candidates_draw if the preedit text, the status, and the
4582 current candidate are changed respectively.
4584 To make the input method commit the current preedit text (if any)
4585 and shift to the initial state, call this function with #Mnil as
4588 To inform the input method about the focus-out event, call this
4589 function with @b Minput_focus_out as $KEY.
4591 To inform the input method about the focus-in event, call this
4592 function with @b Minput_focus_in as $KEY.
4594 To inform the input method about the focus-move event (i.e. input
4595 spot change within the same input context), call this function
4596 with @b Minput_focus_move as $KEY.
4599 If $KEY is filtered out, this function returns 1. In that case,
4600 the caller should discard the key. Otherwise, it returns 0, and
4601 the caller should handle the key, for instance, by calling the
4602 function minput_lookup () with the same key. */
4605 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4607 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4608 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4609 @b Minput_preedit_draw, @b Minput_status_draw,
4610 @b Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4613 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4614 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4615 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4616 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4618 @latexonly \IPAlabel{minput_filter} @endlatexonly
4622 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4629 if (ic->im->driver.callback_list
4630 && mtext_nchars (ic->preedit) > 0)
4631 minput_callback (ic, Minput_preedit_draw);
4633 ret = (*ic->im->driver.filter) (ic, key, arg);
4635 if (ic->im->driver.callback_list)
4637 if (ic->preedit_changed)
4638 minput_callback (ic, Minput_preedit_draw);
4639 if (ic->status_changed)
4640 minput_callback (ic, Minput_status_draw);
4641 if (ic->candidates_changed)
4642 minput_callback (ic, Minput_candidates_draw);
4651 @brief Look up a text produced in the input context.
4653 The minput_lookup () function looks up a text in the input context
4654 $IC. $KEY must be identical to the one that was used in the previous call of
4657 If a text was produced by the input method, it is concatenated
4660 This function calls #MInputDriver::lookup .
4663 If $KEY was correctly handled by the input method, this function
4664 returns 0. Otherwise, it returns -1, even though some text
4665 might be produced in $MT. */
4668 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4670 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4671 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4673 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4676 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4679 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4680 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4681 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4683 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4686 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4688 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4693 @brief Set the spot of the input context.
4695 The minput_set_spot () function sets the spot of input context $IC
4696 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4697 The semantics of these values depends on the input method driver.
4699 For instance, a driver designed to work in a CUI environment may
4700 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4701 $DESCENT . A driver designed to work in a window system may
4702 interpret $X and $Y as the pixel offsets relative to the origin of the
4703 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4704 descent pixels of the line at ($X . $Y ).
4706 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4708 $MT and $POS are the M-text and the character position at the spot.
4709 $MT may be @c NULL, in which case, the input method cannot get
4710 information about the text around the spot. */
4713 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4715 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4716 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4717 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4719 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4720 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4721 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4722 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4723 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4724 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4726 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4728 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4729 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4733 minput_set_spot (MInputContext *ic, int x, int y,
4734 int ascent, int descent, int fontsize,
4739 ic->spot.ascent = ascent;
4740 ic->spot.descent = descent;
4741 ic->spot.fontsize = fontsize;
4744 if (ic->im->driver.callback_list)
4745 minput_callback (ic, Minput_set_spot);
4750 @brief Toggle input method.
4752 The minput_toggle () function toggles the input method associated
4753 with input context $IC. */
4755 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4757 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4758 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4762 minput_toggle (MInputContext *ic)
4764 if (ic->im->driver.callback_list)
4765 minput_callback (ic, Minput_toggle);
4766 ic->active = ! ic->active;
4772 @brief Reset an input context.
4774 The minput_reset_ic () function resets input context $IC by
4775 calling a callback function corresponding to @b Minput_reset. It
4776 resets the status of $IC to its initial one. As the
4777 current preedit text is deleted without commitment, if necessary,
4778 call minput_filter () with the arg @b key #Mnil to force the input
4779 method to commit the preedit in advance. */
4782 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4784 ´Ø¿ô minput_reset_ic () ¤Ï @b Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4785 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4786 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4787 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4788 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @b key #Mnil ¤Ç¸Æ¤ó¤Ç
4789 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4792 minput_reset_ic (MInputContext *ic)
4794 if (ic->im->driver.callback_list)
4795 minput_callback (ic, Minput_reset);
4801 @brief Get title and icon filename of an input method.
4803 The minput_get_title_icon () function returns a plist containing a
4804 title and icon filename (if any) of an input method specified by
4805 $LANGUAGE and $NAME.
4807 The first element of the plist has key #Mtext and the value is an
4808 M-text of the title for identifying the input method. The second
4809 element (if any) has key #Mtext and the value is an M-text of the
4810 icon image (absolute) filename for the same purpose.
4813 If there exists a specified input method and it defines an title,
4814 a plist is returned. Otherwise, NULL is returned. The caller
4815 must free the plist by m17n_object_unref (). */
4817 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4819 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4820 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4823 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4824 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4825 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4828 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4829 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4830 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4833 minput_get_title_icon (MSymbol language, MSymbol name)
4835 MInputMethodInfo *im_info;
4842 im_info = get_im_info (language, name, Mnil, Mtitle);
4843 if (! im_info || !im_info->title)
4845 mt = mtext_get_prop (im_info->title, 0, Mtext);
4847 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4850 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4853 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4854 (char *) MSYMBOL_NAME (name));
4855 file = mdatabase__find_file (buf);
4856 if (! file && language == Mt)
4858 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4859 file = mdatabase__find_file (buf);
4864 mplist_add (plist, Mtext, im_info->title);
4867 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4869 mplist_add (plist, Mtext, mt);
4870 M17N_OBJECT_UNREF (mt);
4878 @brief Get description text of an input method.
4880 The minput_get_description () function returns an M-text that
4881 describes the input method specified by $LANGUAGE and $NAME.
4884 If the specified input method has a description text, a pointer to
4885 #MText is returned. The caller has to free it by m17n_object_unref ().
4886 If the input method does not have a description text, @c NULL is
4889 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4891 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4892 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4895 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4896 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4897 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4898 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4901 minput_get_description (MSymbol language, MSymbol name)
4903 MInputMethodInfo *im_info;
4911 extra = language, language = Mt;
4913 im_info = get_im_info (language, name, extra, Mdescription);
4914 if (! im_info || ! im_info->description)
4916 M17N_OBJECT_REF (im_info->description);
4917 return im_info->description;
4923 @brief Get information about input method command(s).
4925 The minput_get_command () function returns information about
4926 the command $COMMAND of the input method specified by $LANGUAGE and
4927 $NAME. An input method command is a pseudo key event to which one
4928 or more actual input key sequences are assigned.
4930 There are two kinds of commands, global and local. A global
4931 command has a global definition, and the description and the key
4932 assignment may be inherited by a local command. Each input method
4933 defines a local command which has a local key assignment. It may
4934 also declare a local command that inherits the definition of a
4935 global command of the same name.
4937 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4938 information about a global command. Otherwise information about a
4939 local command is returned.
4941 If $COMMAND is #Mnil, information about all commands is returned.
4943 The return value is a @e well-formed plist (@ref m17nPlist) of this
4946 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4948 @c NAME is a symbol representing the command name.
4950 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4951 command has no description.
4953 @c STATUS is a symbol representing how the key assignment is decided.
4954 The value is #Mnil (the default key assignment), @b Mcustomized (the
4955 key assignment is customized by per-user customization file), or
4956 @b Mconfigured (the key assignment is set by the call of
4957 minput_config_command ()). For a local command only, it may also
4958 be @b Minherited (the key assignment is inherited from the
4959 corresponding global command).
4961 @c KEYSEQ is a plist of one or more symbols representing a key
4962 sequence assigned to the command. If there's no KEYSEQ, the
4963 command is currently disabled (i.e. no key sequence can trigger
4964 actions of the command).
4966 If $COMMAND is not #Mnil, the first element of the returned plist
4967 contains the information about $COMMAND.
4971 If the requested information was found, a pointer to a non-empty
4972 plist is returned. As the plist is kept in the library, the
4973 caller must not modify nor free it.
4975 Otherwise (the specified input method or the specified command
4976 does not exist), @c NULL is returned. */
4978 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4980 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4981 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4982 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4983 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4985 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4986 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4987 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4988 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4989 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4991 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4992 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4995 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4997 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5000 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
5002 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5004 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
5007 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
5008 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, @b Mcustomized ¡Ê¥æ¡¼
5009 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
5010 @b Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
5011 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
5012 @b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
5015 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
5016 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
5017 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
5018 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
5020 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
5021 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5025 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5026 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5029 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5034 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
5036 /* Return a description of the command COMMAND of the input method
5037 specified by LANGUAGE and NAME. */
5038 MPlist *cmd = minput_get_command (langauge, name, command);
5043 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
5044 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
5045 return (mplist_key (plist) == Mtext
5046 ? (MText *) mplist_value (plist)
5052 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5054 MInputMethodInfo *im_info;
5058 im_info = get_im_info (language, name, Mnil, Mcommand);
5060 || ! im_info->configured_cmds
5061 || MPLIST_TAIL_P (im_info->configured_cmds))
5063 if (command == Mnil)
5064 return im_info->configured_cmds;
5065 return mplist__assq (im_info->configured_cmds, command);
5071 @brief Configure the key sequence of an input method command.
5073 The minput_config_command () function assigns a list of key
5074 sequences $KEYSEQLIST to the command $COMMAND of the input method
5075 specified by $LANGUAGE and $NAME.
5077 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5078 sequences, and each key sequence must be a plist of symbols.
5080 If $KEYSEQLIST is an empty plist, any configuration and
5081 customization of the command are cancelled, and default key
5082 sequences become effective.
5084 If $KEYSEQLIST is NULL, the configuration of the command is
5085 canceled, and the original key sequences (what saved in per-user
5086 customization file, or the default one) become effective.
5088 In the latter two cases, $COMMAND can be #Mnil to make all the
5089 commands of the input method the target of the operation.
5091 If $NAME is #Mnil, this function configures the key assignment of a
5092 global command, not that of a specific input method.
5094 The configuration takes effect for input methods opened or
5095 re-opened later in the current session. In order to make the
5096 configuration take effect for the future session, it must be saved
5097 in a per-user customization file by the function
5098 minput_save_config ().
5101 If the operation was successful, this function returns 0,
5102 otherwise returns -1. The operation fails in these cases:
5104 <li>$KEYSEQLIST is not in a valid form.
5105 <li>$COMMAND is not available for the input method.
5106 <li>$LANGUAGE and $NAME do not specify an existing input method.
5110 minput_get_commands (), minput_save_config ().
5113 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5115 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5116 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5117 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5119 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5120 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5122 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5123 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5125 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5126 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5127 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5129 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5130 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5132 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5133 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5135 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5136 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5137 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5138 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5142 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5144 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5145 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5146 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5150 minput_get_commands (), minput_save_config ().
5154 /* Add "C-x u" to the "start" command of Unicode input method. */
5156 MSymbol start_command = msymbol ("start");
5157 MSymbol unicode = msymbol ("unicode");
5158 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5160 /* At first get the current key-sequence assignment. */
5161 cmd = minput_get_command (Mt, unicode, start_command);
5164 /* The input method does not have the command "start". Here
5165 should come some error handling code. */
5167 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5168 Extract the part (KEY-SEQUENCE ...). */
5169 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5170 /* Copy it because we should not modify it directly. */
5171 key_seq_list = mplist_copy (plist);
5173 key_seq = mplist ();
5174 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5175 mplist_add (key_seq, Msymbol, msymbol ("u"));
5176 mplist_add (key_seq_list, Mplist, key_seq);
5177 m17n_object_unref (key_seq);
5179 minput_config_command (Mt, unicode, start_command, key_seq_list);
5180 m17n_object_unref (key_seq_list);
5185 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5188 MInputMethodInfo *im_info, *config;
5193 im_info = get_im_info (language, name, Mnil, Mcommand);
5195 MERROR (MERROR_IM, -1);
5196 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5198 || ! mplist__assq (im_info->configured_cmds, command)))
5199 MERROR (MERROR_IM, -1);
5200 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5202 MPLIST_DO (plist, keyseqlist)
5203 if (! check_command_keyseq (plist))
5204 MERROR (MERROR_IM, -1);
5207 config = get_config_info (im_info);
5210 if (! im_config_list)
5211 im_config_list = mplist ();
5212 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5213 config->cmds = mplist ();
5214 config->vars = mplist ();
5217 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5218 /* Nothing to do. */
5221 if (command == Mnil)
5225 /* Cancal the configuration. */
5226 if (MPLIST_TAIL_P (config->cmds))
5228 mplist_set (config->cmds, Mnil, NULL);
5232 /* Cancal the customization. */
5233 MInputMethodInfo *custom = get_custom_info (im_info);
5235 if (MPLIST_TAIL_P (config->cmds)
5236 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5237 /* Nothing to do. */
5239 mplist_set (config->cmds, Mnil, NULL);
5240 MPLIST_DO (plist, custom->cmds)
5242 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5244 mplist_add (plist, Msymbol, command);
5245 mplist_push (config->cmds, Mplist, plist);
5246 M17N_OBJECT_UNREF (plist);
5252 plist = mplist__assq (config->cmds, command);
5255 /* Cancel the configuration. */
5258 mplist__pop_unref (plist);
5260 else if (MPLIST_TAIL_P (keyseqlist))
5262 /* Cancel the customization. */
5263 MInputMethodInfo *custom = get_custom_info (im_info);
5264 int no_custom = (! custom || ! custom->cmds
5265 || ! mplist__assq (custom->cmds, command));
5271 mplist_add (config->cmds, Mplist, plist);
5272 M17N_OBJECT_UNREF (plist);
5273 plist = mplist_add (plist, Msymbol, command);
5278 mplist__pop_unref (plist);
5281 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5282 plist = MPLIST_NEXT (plist);
5283 mplist_set (plist, Mnil, NULL);
5293 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5294 if (! MPLIST_TAIL_P (plist))
5295 mplist_set (plist, Mnil, NULL);
5300 mplist_add (config->cmds, Mplist, plist);
5301 M17N_OBJECT_UNREF (plist);
5302 plist = mplist_add (plist, Msymbol, command);
5303 plist = MPLIST_NEXT (plist);
5305 MPLIST_DO (keyseqlist, keyseqlist)
5307 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5308 plist = mplist_add (plist, Mplist, pl);
5309 M17N_OBJECT_UNREF (pl);
5313 config_all_commands (im_info);
5314 im_info->tick = time (NULL);
5321 @brief Get information about input method variable(s).
5323 The minput_get_variable () function returns information about
5324 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5325 An input method variable controls behavior of an input method.
5327 There are two kinds of variables, global and local. A global
5328 variable has a global definition, and the description and the value
5329 may be inherited by a local variable. Each input method defines a
5330 local variable which has local value. It may also declare a
5331 local variable that inherits definition of a global variable of
5334 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5335 variable is returned. Otherwise information about a local variable
5338 If $VARIABLE is #Mnil, information about all variables is
5341 The return value is a @e well-formed plist (@ref m17nPlist) of this
5344 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5346 @c NAME is a symbol representing the variable name.
5348 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5349 variable has no description.
5351 @c STATUS is a symbol representing how the value is decided. The
5352 value is #Mnil (the default value), @b Mcustomized (the value is
5353 customized by per-user customization file), or @b Mconfigured (the
5354 value is set by the call of minput_config_variable ()). For a
5355 local variable only, it may also be @b Minherited (the value is
5356 inherited from the corresponding global variable).
5358 @c VALUE is the initial value of the variable. If the key of this
5359 element is #Mt, the variable has no initial value. Otherwise, the
5360 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5363 @c VALID-VALUEs (if any) specify which values the variable can have.
5364 They have the same type (i.e. having the same key) as @c VALUE except
5365 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5366 may be a plist of two integers specifying the range of possible
5369 If there no @c VALID-VALUE, the variable can have any value as long
5370 as the type is the same as @c VALUE.
5372 If $VARIABLE is not #Mnil, the first element of the returned plist
5373 contains the information about $VARIABLE.
5377 If the requested information was found, a pointer to a non-empty
5378 plist is returned. As the plist is kept in the library, the
5379 caller must not modify nor free it.
5381 Otherwise (the specified input method or the specified variable
5382 does not exist), @c NULL is returned. */
5384 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5386 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5387 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5388 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5390 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5391 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5392 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5393 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5396 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5397 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5399 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5401 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5403 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5406 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5408 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5411 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5412 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, @b Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5413 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, @b Mconfigured
5414 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5415 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢@b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5416 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5418 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5419 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5420 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5422 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5423 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5424 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5425 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5427 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5430 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5431 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5435 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5436 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5439 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5443 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5445 MInputMethodInfo *im_info;
5449 im_info = get_im_info (language, name, Mnil, Mvariable);
5450 if (! im_info || ! im_info->configured_vars)
5452 if (variable == Mnil)
5453 return im_info->configured_vars;
5454 return mplist__assq (im_info->configured_vars, variable);
5460 @brief Configure the value of an input method variable.
5462 The minput_config_variable () function assigns $VALUE to the
5463 variable $VARIABLE of the input method specified by $LANGUAGE and
5466 If $VALUE is a non-empty plist, it must be a plist of one element
5467 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5468 the corresponding type. That value is assigned to the variable.
5470 If $VALUE is an empty plist, any configuration and customization
5471 of the variable are canceled, and the default value is assigned to
5474 If $VALUE is NULL, the configuration of the variable is canceled,
5475 and the original value (what saved in per-user customization file,
5476 or the default value) is assigned to the variable.
5478 In the latter two cases, $VARIABLE can be #Mnil to make all the
5479 variables of the input method the target of the operation.
5481 If $NAME is #Mnil, this function configures the value of global
5482 variable, not that of a specific input method.
5484 The configuration takes effect for input methods opened or
5485 re-opened later in the current session. To make the configuration
5486 take effect for the future session, it must be saved in a per-user
5487 customization file by the function minput_save_config ().
5491 If the operation was successful, this function returns 0,
5492 otherwise returns -1. The operation fails in these cases:
5494 <li>$VALUE is not in a valid form, the type does not match the
5495 definition, or the value is our of range.
5496 <li>$VARIABLE is not available for the input method.
5497 <li>$LANGUAGE and $NAME do not specify an existing input method.
5501 minput_get_variable (), minput_save_config (). */
5503 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5505 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5506 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5508 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5509 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5510 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5512 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5513 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5515 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5516 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5518 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5519 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5521 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5522 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5524 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5525 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5526 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5527 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5531 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5533 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5534 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5535 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5539 minput_get_commands (), minput_save_config ().
5542 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5545 MInputMethodInfo *im_info, *config;
5550 im_info = get_im_info (language, name, Mnil, Mvariable);
5552 MERROR (MERROR_IM, -1);
5553 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5555 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5556 MERROR (MERROR_IM, -1);
5558 if (value && ! MPLIST_TAIL_P (value))
5560 plist = MPLIST_PLIST (plist);
5561 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5562 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5563 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5564 if (MPLIST_KEY (plist) != Mt
5565 && ! check_variable_value (value, plist))
5566 MERROR (MERROR_IM, -1);
5569 config = get_config_info (im_info);
5572 if (! im_config_list)
5573 im_config_list = mplist ();
5574 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5575 config->cmds = mplist ();
5576 config->vars = mplist ();
5579 if (! value && MPLIST_TAIL_P (config->vars))
5580 /* Nothing to do. */
5583 if (variable == Mnil)
5587 /* Cancel the configuration. */
5588 if (MPLIST_TAIL_P (config->vars))
5590 mplist_set (config->vars, Mnil, NULL);
5594 /* Cancel the customization. */
5595 MInputMethodInfo *custom = get_custom_info (im_info);
5597 if (MPLIST_TAIL_P (config->vars)
5598 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5599 /* Nothing to do. */
5601 mplist_set (config->vars, Mnil, NULL);
5602 MPLIST_DO (plist, custom->vars)
5604 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5606 mplist_add (plist, Msymbol, variable);
5607 mplist_push (config->vars, Mplist, plist);
5608 M17N_OBJECT_UNREF (plist);
5614 plist = mplist__assq (config->vars, variable);
5617 /* Cancel the configuration. */
5620 mplist__pop_unref (plist);
5622 else if (MPLIST_TAIL_P (value))
5624 /* Cancel the customization. */
5625 MInputMethodInfo *custom = get_custom_info (im_info);
5626 int no_custom = (! custom || ! custom->vars
5627 || ! mplist__assq (custom->vars, variable));
5633 mplist_add (config->vars, Mplist, plist);
5634 M17N_OBJECT_UNREF (plist);
5635 plist = mplist_add (plist, Msymbol, variable);
5640 mplist__pop_unref (plist);
5643 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5644 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5645 mplist_set (plist, Mnil ,NULL);
5653 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5654 if (! MPLIST_TAIL_P (plist))
5655 mplist_set (plist, Mnil, NULL);
5660 mplist_add (config->vars, Mplist, plist);
5661 M17N_OBJECT_UNREF (plist);
5662 plist = mplist_add (plist, Msymbol, variable);
5663 plist = MPLIST_NEXT (plist);
5665 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5668 config_all_variables (im_info);
5669 im_info->tick = time (NULL);
5676 @brief Get the name of per-user customization file.
5678 The minput_config_file () function returns the absolute path name
5679 of per-user customization file into which minput_save_config ()
5680 save configurations. It is usually @c config.mic under the
5681 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5682 directory). It is not assured that the file of the returned name
5683 exists nor is readable/writable. If minput_save_config () fails
5684 and returns -1, an application program might check the file, make
5685 it writable (if possible), and try minput_save_config () again.
5689 This function returns a string. As the string is kept in the
5690 library, the caller must not modify nor free it.
5693 minput_save_config ()
5696 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5698 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5699 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5700 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5701 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5702 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5703 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5704 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5709 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5710 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5713 minput_save_config ()
5717 minput_config_file ()
5721 return mdatabase__file (im_custom_mdb);
5727 @brief Save configurations in per-user customization file.
5729 The minput_save_config () function saves the configurations done
5730 so far in the current session into the per-user customization
5735 If the operation was successful, 1 is returned. If the per-user
5736 customization file is currently locked, 0 is returned. In that
5737 case, the caller may wait for a while and try again. If the
5738 configuration file is not writable, -1 is returned. In that case,
5739 the caller may check the name of the file by calling
5740 minput_config_file (), make it writable if possible, and try
5744 minput_config_file () */
5746 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5748 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5749 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5753 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5754 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5755 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5756 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5760 minput_config_file () */
5763 minput_save_config (void)
5765 MPlist *data, *tail, *plist, *p, *elt;
5769 ret = mdatabase__lock (im_custom_mdb);
5772 if (! im_config_list)
5774 update_custom_info ();
5775 if (! im_custom_list)
5776 im_custom_list = mplist ();
5778 /* At first, reflect configuration in customization. */
5779 MPLIST_DO (plist, im_config_list)
5781 MPlist *pl = MPLIST_PLIST (plist);
5782 MSymbol language, name, extra, command, variable;
5783 MInputMethodInfo *custom, *config;
5785 language = MPLIST_SYMBOL (pl);
5786 pl = MPLIST_NEXT (pl);
5787 name = MPLIST_SYMBOL (pl);
5788 pl = MPLIST_NEXT (pl);
5789 extra = MPLIST_SYMBOL (pl);
5790 pl = MPLIST_NEXT (pl);
5791 config = MPLIST_VAL (pl);
5792 custom = get_custom_info (config);
5794 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5796 MPLIST_DO (pl, config->cmds)
5798 elt = MPLIST_PLIST (pl);
5799 command = MPLIST_SYMBOL (elt);
5801 p = mplist__assq (custom->cmds, command);
5803 custom->cmds = mplist (), p = NULL;
5804 elt = MPLIST_NEXT (elt);
5807 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5808 mplist_set (p, Mnil, NULL);
5813 mplist_add (custom->cmds, Mplist, p);
5814 M17N_OBJECT_UNREF (p);
5815 mplist_add (p, Msymbol, command);
5816 p = mplist_add (p, Msymbol, Mnil);
5817 p = MPLIST_NEXT (p);
5819 mplist__conc (p, elt);
5822 MPLIST_DO (pl, config->vars)
5824 elt = MPLIST_PLIST (pl);
5825 variable = MPLIST_SYMBOL (elt);
5827 p = mplist__assq (custom->vars, variable);
5829 custom->vars = mplist (), p = NULL;
5830 elt = MPLIST_NEXT (elt);
5833 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5834 mplist_set (p, Mnil, NULL);
5839 mplist_add (custom->vars, Mplist, p);
5840 M17N_OBJECT_UNREF (p);
5841 mplist_add (p, Msymbol, variable);
5842 p = mplist_add (p, Msymbol, Mnil);
5843 p = MPLIST_NEXT (p);
5845 mplist__conc (p, elt);
5848 free_im_list (im_config_list);
5849 im_config_list = NULL;
5851 /* Next, reflect customization to the actual plist to be written. */
5852 data = tail = mplist ();
5853 MPLIST_DO (plist, im_custom_list)
5855 MPlist *pl = MPLIST_PLIST (plist);
5856 MSymbol language, name, extra;
5857 MInputMethodInfo *custom, *im_info;
5859 language = MPLIST_SYMBOL (pl);
5860 pl = MPLIST_NEXT (pl);
5861 name = MPLIST_SYMBOL (pl);
5862 pl = MPLIST_NEXT (pl);
5863 extra = MPLIST_SYMBOL (pl);
5864 pl = MPLIST_NEXT (pl);
5865 custom = MPLIST_VAL (pl);
5866 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5867 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5869 im_info = lookup_im_info (im_info_list, language, name, extra);
5873 config_all_commands (im_info);
5875 config_all_variables (im_info);
5879 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5881 MPLIST_DO (p, custom->cmds)
5882 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5884 if (! MPLIST_TAIL_P (p))
5888 mplist_add (elt, Mplist, pl);
5889 M17N_OBJECT_UNREF (pl);
5890 pl = mplist_add (pl, Msymbol, Mcommand);
5891 MPLIST_DO (p, custom->cmds)
5892 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5893 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5896 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5898 MPLIST_DO (p, custom->vars)
5899 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5901 if (! MPLIST_TAIL_P (p))
5906 mplist_add (elt, Mplist, pl);
5907 M17N_OBJECT_UNREF (pl);
5908 pl = mplist_add (pl, Msymbol, Mvariable);
5909 MPLIST_DO (p, custom->vars)
5910 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5911 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5917 mplist_push (elt, Mplist, pl);
5918 M17N_OBJECT_UNREF (pl);
5919 pl = mplist_add (pl, Msymbol, Minput_method);
5920 pl = mplist_add (pl, Msymbol, language);
5921 pl = mplist_add (pl, Msymbol, name);
5923 pl = mplist_add (pl, Msymbol, extra);
5924 tail = mplist_add (tail, Mplist, elt);
5925 M17N_OBJECT_UNREF (elt);
5929 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5930 ret = mdatabase__save (im_custom_mdb, data);
5931 mdatabase__unlock (im_custom_mdb);
5932 M17N_OBJECT_UNREF (data);
5933 return (ret < 0 ? -1 : 1);
5937 @brief List available input methods.
5939 The minput_list () function returns a list of currently available
5940 input methods whose language is $LANGUAGE. If $LANGUAGE is #Mnil,
5941 all input methods are listed.
5944 The returned value is a plist of this form:
5945 ((LANGUAGE-NAME INPUT-METHOD-NAME SANE) ...)
5946 The third element SANE of each input method is #Mt if it can be
5947 successfully used, or #Mnil if it has some problem (e.g. syntax
5948 error of MIM file, unavailable external module, unavailable
5949 including input method). */
5957 main (int argc, char **argv)
5959 MPlist *imlist, *pl;
5962 imlist = minput_list ((argc > 1) ? msymbol (argv[1]) : Mnil);
5963 for (pl = imlist; mplist_key (pl) != Mnil; pl = mplist_next (pl))
5965 MPlist *p = mplist_value (pl);
5966 MSymbol lang, name, sane;
5968 lang = mplist_value (p);
5969 p = mplist_next (p);
5970 name = mplist_value (p);
5971 p = mplist_next (p);
5972 sane = mplist_value (p);
5974 printf ("%s %s %s\n", msymbol_name (lang), msymbol_name (name),
5975 sane == Mt ? "ok" : "no");
5978 m17n_object_unref (imlist);
5985 minput_list (MSymbol language)
5988 MPlist *imlist = mplist ();
5991 plist = mdatabase_list (Minput_method, language, Mnil, Mnil);
5994 MPLIST_DO (pl, plist)
5996 MDatabase *mdb = MPLIST_VAL (pl);
5997 MSymbol *tag = mdatabase_tag (mdb);
5998 MPlist *imdata, *p, *elm;
5999 int num_maps = 0, num_states = 0;
6003 imdata = mdatabase_load (mdb);
6006 MPLIST_DO (p, imdata)
6007 if (MPLIST_PLIST_P (p))
6009 /* Check these basic functionarity:
6010 All external modules (if any) are loadable.
6011 All included input method (if any) are loadable.
6012 At least one map is defined or included.
6013 At least one state is defined or included. */
6014 MPlist *elt = MPLIST_PLIST (p);
6017 if (MFAILP (MPLIST_SYMBOL_P (elt)))
6019 key = MPLIST_SYMBOL (elt);
6022 else if (key == Mstate)
6024 else if (key == Mmodule)
6026 MPLIST_DO (elt, MPLIST_NEXT (elt))
6028 MIMExternalModule *external;
6030 if (MFAILP (MPLIST_PLIST_P (elt)))
6032 external = load_external_module (MPLIST_PLIST (elt));
6033 if (MFAILP (external))
6035 unload_external_module (external);
6037 if (! MPLIST_TAIL_P (elt))
6040 else if (key == Minclude)
6042 MInputMethodInfo *im_info;
6044 elt = MPLIST_NEXT (elt);
6045 if (MFAILP (MPLIST_PLIST_P (elt)))
6047 im_info = get_im_info_by_tags (MPLIST_PLIST (elt));
6048 if (MFAILP (im_info))
6050 elt = MPLIST_NEXT (elt);
6051 if (MFAILP (MPLIST_SYMBOL_P (elt)))
6053 key = MPLIST_SYMBOL (elt);
6056 if (! im_info->maps)
6060 else if (key == Mstate)
6062 if (! im_info->states)
6069 mplist_add (elm, Msymbol, tag[1]);
6070 mplist_add (elm, Msymbol, tag[2]);
6071 if (MPLIST_TAIL_P (p) && num_maps > 0 && num_states > 0)
6072 mplist_add (elm, Msymbol, Mt);
6074 mplist_add (elm, Msymbol, Mnil);
6075 mplist_push (imlist, Mplist, elm);
6076 M17N_OBJECT_UNREF (elm);
6077 M17N_OBJECT_UNREF (imdata);
6079 M17N_OBJECT_UNREF (plist);
6087 @name Obsolete functions
6090 @name Obsolete ¤Ê´Ø¿ô
6096 @brief Get a list of variables of an input method (obsolete).
6098 This function is obsolete. Use minput_get_variable () instead.
6100 The minput_get_variables () function returns a plist (#MPlist) of
6101 variables used to control the behavior of the input method
6102 specified by $LANGUAGE and $NAME. The plist is @e well-formed
6103 (@ref m17nPlist) of the following format:
6106 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6107 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6111 @c VARNAME is a symbol representing the variable name.
6113 @c DOC-MTEXT is an M-text describing the variable.
6115 @c DEFAULT-VALUE is the default value of the variable. It is a
6116 symbol, integer, or M-text.
6118 @c VALUEs (if any) specifies the possible values of the variable.
6119 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
6120 @c TO), where @c FROM and @c TO specifies a range of possible
6123 For instance, suppose an input method has the variables:
6125 @li name:intvar, description:"value is an integer",
6126 initial value:0, value-range:0..3,10,20
6128 @li name:symvar, description:"value is a symbol",
6129 initial value:nil, value-range:a, b, c, nil
6131 @li name:txtvar, description:"value is an M-text",
6132 initial value:empty text, no value-range (i.e. any text)
6134 Then, the returned plist is as follows.
6137 (intvar ("value is an integer" 0 (0 3) 10 20)
6138 symvar ("value is a symbol" nil a b c nil)
6139 txtvar ("value is an M-text" ""))
6143 If the input method uses any variables, a pointer to #MPlist is
6144 returned. As the plist is kept in the library, the caller must not
6145 modify nor free it. If the input method does not use any
6146 variable, @c NULL is returned. */
6148 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
6150 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6151 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
6152 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
6156 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6157 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6161 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6163 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
6165 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
6168 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
6169 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
6170 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
6172 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
6174 @li name:intvar, ÀâÌÀ:"value is an integer",
6175 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
6177 @li name:symvar, ÀâÌÀ:"value is a symbol",
6178 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
6180 @li name:txtvar, ÀâÌÀ:"value is an M-text",
6181 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
6183 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
6186 (intvar ("value is an integer" 0 (0 3) 10 20)
6187 symvar ("value is a symbol" nil a b c nil)
6188 txtvar ("value is an M-text" ""))
6192 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
6193 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6194 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
6197 minput_get_variables (MSymbol language, MSymbol name)
6199 MInputMethodInfo *im_info;
6204 im_info = get_im_info (language, name, Mnil, Mvariable);
6205 if (! im_info || ! im_info->configured_vars)
6208 M17N_OBJECT_UNREF (im_info->bc_vars);
6209 im_info->bc_vars = mplist ();
6210 MPLIST_DO (vars, im_info->configured_vars)
6212 MPlist *plist = MPLIST_PLIST (vars);
6213 MPlist *elt = mplist ();
6215 mplist_push (im_info->bc_vars, Mplist, elt);
6216 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6217 elt = MPLIST_NEXT (elt);
6218 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6219 M17N_OBJECT_UNREF (elt);
6221 return im_info->bc_vars;
6227 @brief Set the initial value of an input method variable.
6229 The minput_set_variable () function sets the initial value of
6230 input method variable $VARIABLE to $VALUE for the input method
6231 specified by $LANGUAGE and $NAME.
6233 By default, the initial value is 0.
6235 This setting gets effective in a newly opened input method.
6238 If the operation was successful, 0 is returned. Otherwise -1 is
6239 returned, and #merror_code is set to @c MERROR_IM. */
6241 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6243 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6244 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6245 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6247 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6249 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6252 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6253 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6256 minput_set_variable (MSymbol language, MSymbol name,
6257 MSymbol variable, void *value)
6260 MInputMethodInfo *im_info;
6265 if (variable == Mnil)
6266 MERROR (MERROR_IM, -1);
6267 plist = minput_get_variable (language, name, variable);
6268 plist = MPLIST_PLIST (plist);
6269 plist = MPLIST_NEXT (plist);
6271 mplist_add (pl, MPLIST_KEY (plist), value);
6272 ret = minput_config_variable (language, name, variable, pl);
6273 M17N_OBJECT_UNREF (pl);
6276 im_info = get_im_info (language, name, Mnil, Mvariable);
6285 @brief Get information about input method commands.
6287 The minput_get_commands () function returns information about
6288 input method commands of the input method specified by $LANGUAGE
6289 and $NAME. An input method command is a pseudo key event to which
6290 one or more actual input key sequences are assigned.
6292 There are two kinds of commands, global and local. Global
6293 commands are used by multiple input methods for the same purpose,
6294 and have global key assignments. Local commands are used only by
6295 a specific input method, and have only local key assignments.
6297 Each input method may locally change key assignments for global
6298 commands. The global key assignment for a global command is
6299 effective only when the current input method does not have local
6300 key assignments for that command.
6302 If $NAME is #Mnil, information about global commands is returned.
6303 In this case $LANGUAGE is ignored.
6305 If $NAME is not #Mnil, information about those commands that have
6306 local key assignments in the input method specified by $LANGUAGE
6307 and $NAME is returned.
6310 If no input method commands are found, this function returns @c NULL.
6312 Otherwise, a pointer to a plist is returned. The key of each
6313 element in the plist is a symbol representing a command, and the
6314 value is a plist of the form COMMAND-INFO described below.
6316 The first element of COMMAND-INFO has the key #Mtext, and the
6317 value is an M-text describing the command.
6319 If there are no more elements, that means no key sequences are
6320 assigned to the command. Otherwise, each of the remaining
6321 elements has the key #Mplist, and the value is a plist whose keys are
6322 #Msymbol and values are symbols representing input keys, which are
6323 currently assigned to the command.
6325 As the returned plist is kept in the library, the caller must not
6326 modify nor free it. */
6328 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6330 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6331 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6332 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6333 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6335 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6336 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6337 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6338 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6340 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6341 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6342 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6345 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6346 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6348 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6349 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6353 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6355 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6356 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6357 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6359 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6360 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6361 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6364 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6365 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6366 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6367 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6368 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6370 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6371 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6374 minput_get_commands (MSymbol language, MSymbol name)
6376 MInputMethodInfo *im_info;
6381 im_info = get_im_info (language, name, Mnil, Mcommand);
6382 if (! im_info || ! im_info->configured_vars)
6384 M17N_OBJECT_UNREF (im_info->bc_cmds);
6385 im_info->bc_cmds = mplist ();
6386 MPLIST_DO (cmds, im_info->configured_cmds)
6388 MPlist *plist = MPLIST_PLIST (cmds);
6389 MPlist *elt = mplist ();
6391 mplist_push (im_info->bc_cmds, Mplist, elt);
6392 mplist_add (elt, MPLIST_SYMBOL (plist),
6393 mplist_copy (MPLIST_NEXT (plist)));
6394 M17N_OBJECT_UNREF (elt);
6396 return im_info->bc_cmds;
6402 @brief Assign a key sequence to an input method command (obsolete).
6404 This function is obsolete. Use minput_config_command () instead.
6406 The minput_assign_command_keys () function assigns input key
6407 sequence $KEYSEQ to input method command $COMMAND for the input
6408 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6409 key sequence is assigned globally no matter what $LANGUAGE is.
6410 Otherwise the key sequence is assigned locally.
6412 Each element of $KEYSEQ must have the key $Msymbol and the value
6413 must be a symbol representing an input key.
6415 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6416 globally or locally.
6418 This assignment gets effective in a newly opened input method.
6421 If the operation was successful, 0 is returned. Otherwise -1 is
6422 returned, and #merror_code is set to @c MERROR_IM. */
6424 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6426 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6427 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6428 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6429 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6430 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6432 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6433 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6435 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6436 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6438 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6442 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6443 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6446 minput_assign_command_keys (MSymbol language, MSymbol name,
6447 MSymbol command, MPlist *keyseq)
6453 if (command == Mnil)
6454 MERROR (MERROR_IM, -1);
6459 if (! check_command_keyseq (keyseq))
6460 MERROR (MERROR_IM, -1);
6462 mplist_add (plist, Mplist, keyseq);
6467 ret = minput_config_command (language, name, command, keyseq);
6468 M17N_OBJECT_UNREF (keyseq);
6475 @brief Call a callback function
6477 The minput_callback () functions calls a callback function
6478 $COMMAND assigned for the input context $IC. The caller must set
6479 specific elements in $IC->plist if the callback function requires.
6482 If there exists a specified callback function, 0 is returned.
6483 Otherwise -1 is returned. By side effects, $IC->plist may be
6487 minput_callback (MInputContext *ic, MSymbol command)
6489 MInputCallbackFunc func;
6491 if (! ic->im->driver.callback_list)
6493 func = ((MInputCallbackFunc)
6494 mplist_get_func (ic->im->driver.callback_list, command));
6497 (func) (ic, command);
6504 /*** @addtogroup m17nDebug */
6510 @brief Dump an input method.
6512 The mdebug_dump_im () function prints the input method $IM in a
6513 human readable way to the stderr or to what specified by the
6514 environment variable MDEBUG_OUTPUT_FILE. $INDENT specifies how
6515 many columns to indent the lines but the first one.
6518 This function returns $IM. */
6520 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6522 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤òɸ½à¥¨¥é¡¼½ÐÎϤ⤷¤¯¤Ï
6523 ´Ä¶ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç½Ð
6524 ÎϤ¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6527 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6530 mdebug_dump_im (MInputMethod *im, int indent)
6532 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6535 prefix = (char *) alloca (indent + 1);
6536 memset (prefix, 32, indent);
6537 prefix[indent] = '\0';
6539 fprintf (mdebug__output, "(input-method %s %s ", msymbol_name (im->language),
6540 msymbol_name (im->name));
6541 mdebug_dump_mtext (im_info->title, 0, 0);
6542 if (im->name != Mnil)
6546 MPLIST_DO (state, im_info->states)
6548 fprintf (mdebug__output, "\n%s ", prefix);
6549 dump_im_state (MPLIST_VAL (state), indent + 2);
6552 fprintf (mdebug__output, ")");