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 MTextProperty *prop;
3009 MPLIST_DO (action_list, action_list)
3011 MPlist *action = regularize_action (action_list, ic_info);
3017 name = MPLIST_SYMBOL (action);
3018 args = MPLIST_NEXT (action);
3020 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
3021 if (name == Minsert)
3023 if (MPLIST_SYMBOL_P (args))
3025 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3026 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3029 if (MPLIST_MTEXT_P (args))
3030 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3031 else /* MPLIST_INTEGER_P (args)) */
3032 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3034 else if (name == M_candidates)
3036 MPlist *plist = get_candidate_list (ic_info, args);
3042 if (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist))
3044 M17N_OBJECT_UNREF (plist);
3047 if (MPLIST_MTEXT_P (plist))
3049 preedit_insert (ic, ic->cursor_pos, NULL,
3050 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3055 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3057 preedit_insert (ic, ic->cursor_pos, mt, 0);
3058 len = mtext_nchars (mt);
3060 pl = mplist_copy (plist);
3061 M17N_OBJECT_UNREF (plist);
3062 mtext_put_prop (ic->preedit,
3063 ic->cursor_pos - len, ic->cursor_pos,
3064 Mcandidate_list, pl);
3065 M17N_OBJECT_UNREF (pl);
3066 mtext_put_prop (ic->preedit,
3067 ic->cursor_pos - len, ic->cursor_pos,
3068 Mcandidate_index, (void *) 0);
3070 else if (name == Mselect)
3073 int code, idx, gindex;
3074 int pos = ic->cursor_pos;
3076 int idx_decided = 0;
3079 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3082 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3083 group = find_candidates_group (mtext_property_value (prop), idx,
3084 &start, &end, &gindex);
3085 if (MPLIST_SYMBOL_P (args))
3087 code = marker_code (MPLIST_SYMBOL (args), 0);
3090 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3091 if (! MPLIST_INTEGER_P (args))
3093 idx = start + MPLIST_INTEGER (args);
3094 if (idx < start || idx >= end)
3102 if (code != '[' && code != ']')
3107 ? new_index (NULL, ic->candidate_index - start,
3108 end - start - 1, MPLIST_SYMBOL (args),
3110 : MPLIST_INTEGER (args)));
3113 find_candidates_group (mtext_property_value (prop), -1,
3118 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3123 int ingroup_index = idx - start;
3126 group = mtext_property_value (prop);
3127 len = mplist_length (group);
3140 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3141 idx += (MPLIST_MTEXT_P (group)
3142 ? mtext_nchars (MPLIST_MTEXT (group))
3143 : mplist_length (MPLIST_PLIST (group)));
3144 len = (MPLIST_MTEXT_P (group)
3145 ? mtext_nchars (MPLIST_MTEXT (group))
3146 : mplist_length (MPLIST_PLIST (group)));
3147 if (ingroup_index >= len)
3148 ingroup_index = len - 1;
3149 idx += ingroup_index;
3151 update_candidate (ic, prop, idx);
3152 MDEBUG_PRINT1 ("(%d)", idx);
3154 else if (name == Mshow)
3155 ic->candidate_show = 1;
3156 else if (name == Mhide)
3157 ic->candidate_show = 0;
3158 else if (name == Mdelete)
3160 int len = mtext_nchars (ic->preedit);
3164 if (MPLIST_SYMBOL_P (args)
3165 && surrounding_pos (MPLIST_SYMBOL (args), &pos))
3167 to = ic->cursor_pos + pos;
3170 delete_surrounding_text (ic, to);
3175 delete_surrounding_text (ic, to - len);
3181 to = (MPLIST_SYMBOL_P (args)
3182 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3184 : MPLIST_INTEGER (args));
3189 pos = to - ic->cursor_pos;
3191 MDEBUG_PRINT1 ("(%d)", pos);
3192 if (to < ic->cursor_pos)
3193 preedit_delete (ic, to, ic->cursor_pos);
3194 else if (to > ic->cursor_pos)
3195 preedit_delete (ic, ic->cursor_pos, to);
3197 else if (name == Mmove)
3199 int len = mtext_nchars (ic->preedit);
3201 = (MPLIST_SYMBOL_P (args)
3202 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3204 : MPLIST_INTEGER (args));
3210 if (pos != ic->cursor_pos)
3212 ic->cursor_pos = pos;
3213 ic->preedit_changed = 1;
3215 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3217 else if (name == Mmark)
3219 int code = marker_code (MPLIST_SYMBOL (args), 0);
3223 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3224 (void *) ic->cursor_pos);
3225 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3228 else if (name == Mpushback)
3230 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3234 if (MPLIST_SYMBOL_P (args))
3236 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3237 if (MPLIST_INTEGER_P (args))
3238 num = MPLIST_INTEGER (args);
3243 num = MPLIST_INTEGER (args);
3246 ic_info->key_head -= num;
3248 ic_info->key_head = 0;
3250 ic_info->key_head = - num;
3251 if (ic_info->key_head > ic_info->used)
3252 ic_info->key_head = ic_info->used;
3254 else if (MPLIST_MTEXT_P (args))
3256 MText *mt = MPLIST_MTEXT (args);
3257 int i, len = mtext_nchars (mt);
3260 ic_info->key_head--;
3261 for (i = 0; i < len; i++)
3263 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3264 if (ic_info->key_head + i < ic_info->used)
3265 ic_info->keys[ic_info->key_head + i] = key;
3267 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3272 MPlist *plist = MPLIST_PLIST (args), *pl;
3276 ic_info->key_head--;
3278 MPLIST_DO (pl, plist)
3280 key = MPLIST_SYMBOL (pl);
3281 if (ic_info->key_head < ic_info->used)
3282 ic_info->keys[ic_info->key_head + i] = key;
3284 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3289 else if (name == Mpop)
3291 if (ic_info->key_head < ic_info->used)
3292 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3294 else if (name == Mcall)
3296 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3297 MIMExternalFunc func = NULL;
3298 MSymbol module, func_name;
3299 MPlist *func_args, *val;
3302 module = MPLIST_SYMBOL (args);
3303 args = MPLIST_NEXT (args);
3304 func_name = MPLIST_SYMBOL (args);
3306 if (im_info->externals)
3308 MIMExternalModule *external
3309 = (MIMExternalModule *) mplist_get (im_info->externals,
3312 func = ((MIMExternalFunc)
3313 mplist_get_func (external->func_list, func_name));
3317 func_args = mplist ();
3318 mplist_add (func_args, Mt, ic);
3319 MPLIST_DO (args, MPLIST_NEXT (args))
3323 if (MPLIST_KEY (args) == Msymbol
3324 && MPLIST_KEY (args) != Mnil
3325 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3327 code = new_index (ic, ic->cursor_pos,
3328 mtext_nchars (ic->preedit),
3329 MPLIST_SYMBOL (args), ic->preedit);
3330 mplist_add (func_args, Minteger, (void *) code);
3333 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3335 val = (func) (func_args);
3336 M17N_OBJECT_UNREF (func_args);
3337 if (val && ! MPLIST_TAIL_P (val))
3338 ret = take_action_list (ic, val);
3339 M17N_OBJECT_UNREF (val);
3343 else if (name == Mshift)
3345 shift_state (ic, MPLIST_SYMBOL (args));
3347 else if (name == Mundo)
3349 int intarg = (MPLIST_TAIL_P (args)
3351 : integer_value (ic, args, 0));
3353 mtext_reset (ic->preedit);
3354 mtext_reset (ic_info->preedit_saved);
3355 mtext_reset (ic->produced);
3356 M17N_OBJECT_UNREF (ic_info->vars);
3357 ic_info->vars = mplist_copy (ic_info->vars_saved);
3358 ic->cursor_pos = ic_info->state_pos = 0;
3359 ic_info->state_key_head = ic_info->key_head
3360 = ic_info->commit_key_head = 0;
3362 shift_state (ic, Mnil);
3365 if (MPLIST_TAIL_P (args))
3370 ic_info->used += intarg;
3373 ic_info->used = intarg;
3376 else if (name == Mset || name == Madd || name == Msub
3377 || name == Mmul || name == Mdiv)
3379 MSymbol sym = MPLIST_SYMBOL (args);
3380 MPlist *value = resolve_variable (ic_info, sym);
3384 val1 = MPLIST_INTEGER (value);
3385 args = MPLIST_NEXT (args);
3386 val2 = resolve_expression (ic, args);
3388 val1 = val2, op = "=";
3389 else if (name == Madd)
3390 val1 += val2, op = "+=";
3391 else if (name == Msub)
3392 val1 -= val2, op = "-=";
3393 else if (name == Mmul)
3394 val1 *= val2, op = "*=";
3396 val1 /= val2, op = "/=";
3397 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3398 MSYMBOL_NAME (sym), op, val1, val1);
3399 mplist_set (value, Minteger, (void *) val1);
3401 else if (name == Mequal || name == Mless || name == Mgreater
3402 || name == Mless_equal || name == Mgreater_equal)
3405 MPlist *actions1, *actions2;
3408 val1 = resolve_expression (ic, args);
3409 args = MPLIST_NEXT (args);
3410 val2 = resolve_expression (ic, args);
3411 args = MPLIST_NEXT (args);
3412 actions1 = MPLIST_PLIST (args);
3413 args = MPLIST_NEXT (args);
3414 if (MPLIST_TAIL_P (args))
3417 actions2 = MPLIST_PLIST (args);
3418 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3419 if (name == Mequal ? val1 == val2
3420 : name == Mless ? val1 < val2
3421 : name == Mgreater ? val1 > val2
3422 : name == Mless_equal ? val1 <= val2
3425 MDEBUG_PRINT ("ok");
3426 ret = take_action_list (ic, actions1);
3430 MDEBUG_PRINT ("no");
3432 ret = take_action_list (ic, actions2);
3437 else if (name == Mcond)
3441 MPLIST_DO (args, args)
3446 if (! MPLIST_PLIST (args))
3448 cond = MPLIST_PLIST (args);
3449 if (resolve_expression (ic, cond) != 0)
3451 MDEBUG_PRINT1 ("(%dth)", idx);
3452 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3458 else if (name == Mcommit)
3460 preedit_commit (ic, 0);
3462 else if (name == Munhandle)
3464 preedit_commit (ic, 0);
3469 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3473 && (actions = mplist_get (im_info->macros, name)))
3475 if (take_action_list (ic, actions) < 0)
3484 /* Handle the input key KEY in the current state and map specified in
3485 the input context IC. If KEY is handled correctly, return 0.
3486 Otherwise, return -1. */
3489 handle_key (MInputContext *ic)
3491 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3492 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3493 MIMMap *map = ic_info->map;
3494 MIMMap *submap = NULL;
3495 MSymbol key = ic_info->keys[ic_info->key_head];
3496 MSymbol alias = Mnil;
3499 if (ic_info->state_hook)
3501 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
3502 MSYMBOL_NAME (ic_info->state->name));
3503 take_action_list (ic, ic_info->state_hook);
3504 ic_info->state_hook = NULL;
3507 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3508 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3512 submap = mplist_get (map->submaps, key);
3515 && (alias = msymbol_get (alias, M_key_alias))
3517 submap = mplist_get (map->submaps, alias);
3522 if (! alias || alias == key)
3523 MDEBUG_PRINT (" submap-found");
3525 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3526 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3527 ic->preedit_changed = 1;
3528 ic->cursor_pos = ic_info->state_pos;
3529 ic_info->key_head++;
3530 ic_info->map = map = submap;
3531 if (map->map_actions)
3533 MDEBUG_PRINT (" map-actions:");
3534 if (take_action_list (ic, map->map_actions) < 0)
3536 MDEBUG_PRINT ("\n");
3540 else if (map->submaps)
3542 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3544 MSymbol key = ic_info->keys[i];
3545 char *name = msymbol_name (key);
3547 if (! name[0] || ! name[1])
3548 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3552 /* If this is the terminal map or we have shifted to another
3553 state, perform branch actions (if any). */
3554 if (! map->submaps || map != ic_info->map)
3556 if (map->branch_actions)
3558 MDEBUG_PRINT (" branch-actions:");
3559 if (take_action_list (ic, map->branch_actions) < 0)
3561 MDEBUG_PRINT ("\n");
3565 /* If MAP is still not the root map, shift to the current
3567 if (ic_info->map != ic_info->state->map)
3568 shift_state (ic, ic_info->state->name);
3573 /* MAP can not handle KEY. */
3575 /* Perform branch actions if any. */
3576 if (map->branch_actions)
3578 MDEBUG_PRINT (" branch-actions:");
3579 if (take_action_list (ic, map->branch_actions) < 0)
3581 MDEBUG_PRINT ("\n");
3586 if (map == ic_info->map)
3588 /* The above branch actions didn't change the state. */
3590 /* If MAP is the root map of the initial state, and there
3591 still exist an unhandled key, it means that the current
3592 input method can not handle it. */
3593 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3594 && ic_info->key_head < ic_info->used)
3596 MDEBUG_PRINT (" unhandled\n");
3597 ic_info->state_hook = map->map_actions;
3601 if (map != ic_info->state->map)
3603 /* MAP is not the root map. Shift to the root map of the
3605 shift_state (ic, ic_info->state->name);
3607 else if (! map->branch_actions)
3609 /* MAP is the root map without any default branch
3610 actions. Shift to the initial state. */
3611 shift_state (ic, Mnil);
3615 MDEBUG_PRINT ("\n");
3619 /* Initialize IC->ic_info. */
3622 init_ic_info (MInputContext *ic)
3624 MInputMethodInfo *im_info = ic->im->info;
3625 MInputContextInfo *ic_info = ic->info;
3628 MLIST_INIT1 (ic_info, keys, 8);;
3630 ic_info->markers = mplist ();
3632 ic_info->vars = mplist ();
3633 if (im_info->configured_vars)
3634 MPLIST_DO (plist, im_info->configured_vars)
3636 MPlist *pl = MPLIST_PLIST (plist);
3637 MSymbol name = MPLIST_SYMBOL (pl);
3639 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3640 if (MPLIST_KEY (pl) != Mt)
3642 MPlist *p = mplist ();
3644 mplist_push (ic_info->vars, Mplist, p);
3645 M17N_OBJECT_UNREF (p);
3646 mplist_add (p, Msymbol, name);
3647 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3650 ic_info->vars_saved = mplist_copy (ic_info->vars);
3652 if (im_info->externals)
3654 MPlist *func_args = mplist (), *plist;
3656 mplist_add (func_args, Mt, ic);
3657 MPLIST_DO (plist, im_info->externals)
3659 MIMExternalModule *external = MPLIST_VAL (plist);
3660 MIMExternalFunc func
3661 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3666 M17N_OBJECT_UNREF (func_args);
3669 ic_info->preedit_saved = mtext ();
3670 ic_info->tick = im_info->tick;
3673 /* Finalize IC->ic_info. */
3676 fini_ic_info (MInputContext *ic)
3678 MInputMethodInfo *im_info = ic->im->info;
3679 MInputContextInfo *ic_info = ic->info;
3681 if (im_info->externals)
3683 MPlist *func_args = mplist (), *plist;
3685 mplist_add (func_args, Mt, ic);
3686 MPLIST_DO (plist, im_info->externals)
3688 MIMExternalModule *external = MPLIST_VAL (plist);
3689 MIMExternalFunc func
3690 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3695 M17N_OBJECT_UNREF (func_args);
3698 MLIST_FREE1 (ic_info, keys);
3699 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3700 M17N_OBJECT_UNREF (ic_info->markers);
3701 M17N_OBJECT_UNREF (ic_info->vars);
3702 M17N_OBJECT_UNREF (ic_info->vars_saved);
3703 M17N_OBJECT_UNREF (ic_info->preceding_text);
3704 M17N_OBJECT_UNREF (ic_info->following_text);
3706 memset (ic_info, 0, sizeof (MInputContextInfo));
3710 re_init_ic (MInputContext *ic, int reload)
3712 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3713 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3714 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3716 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3717 preedit_changed = mtext_nchars (ic->preedit) > 0;
3718 cursor_pos_changed = ic->cursor_pos > 0;
3719 candidates_changed = 0;
3720 if (ic->candidate_list)
3722 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3723 M17N_OBJECT_UNREF (ic->candidate_list);
3724 ic->candidate_list = NULL;
3726 if (ic->candidate_show)
3728 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3729 ic->candidate_show = 0;
3731 if (ic->candidate_index > 0)
3733 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3734 ic->candidate_index = 0;
3735 ic->candidate_from = ic->candidate_to = 0;
3737 if (mtext_nchars (ic->produced) > 0)
3738 mtext_reset (ic->produced);
3739 if (mtext_nchars (ic->preedit) > 0)
3740 mtext_reset (ic->preedit);
3742 M17N_OBJECT_UNREF (ic->plist);
3743 ic->plist = mplist ();
3747 reload_im_info (im_info);
3748 if (! im_info->states)
3750 struct MIMState *state;
3752 M17N_OBJECT (state, free_state, MERROR_IM);
3753 state->name = msymbol ("init");
3754 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3755 MSTRUCT_CALLOC (state->map, MERROR_IM);
3756 im_info->states = mplist ();
3757 mplist_add (im_info->states, state->name, state);
3760 shift_state (ic, Mnil);
3762 ic->status_changed = status_changed;
3763 ic->preedit_changed = preedit_changed;
3764 ic->cursor_pos_changed = cursor_pos_changed;
3765 ic->candidates_changed = candidates_changed;
3769 reset_ic (MInputContext *ic, MSymbol ignore)
3771 MDEBUG_PRINT ("\n [IM] reset\n");
3776 open_im (MInputMethod *im)
3778 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3780 if (! im_info || ! im_info->states || MPLIST_LENGTH (im_info->states) == 0)
3781 MERROR (MERROR_IM, -1);
3788 close_im (MInputMethod *im)
3794 create_ic (MInputContext *ic)
3796 MInputContextInfo *ic_info;
3798 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3801 shift_state (ic, Mnil);
3806 destroy_ic (MInputContext *ic)
3813 check_reload (MInputContext *ic, MSymbol key)
3815 MInputMethodInfo *im_info = ic->im->info;
3816 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3820 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3824 MPLIST_DO (plist, plist)
3826 MSymbol this_key, alias;
3828 if (MPLIST_MTEXT_P (plist))
3830 MText *mt = MPLIST_MTEXT (plist);
3831 int c = mtext_ref_char (mt, 0);
3835 this_key = one_char_symbol[c];
3839 MPlist *pl = MPLIST_PLIST (plist);
3841 this_key = MPLIST_SYMBOL (pl);
3845 && (alias = msymbol_get (alias, M_key_alias))
3846 && alias != this_key);
3850 if (MPLIST_TAIL_P (plist))
3853 MDEBUG_PRINT ("\n [IM] reload");
3859 /** Handle the input key KEY in the current state and map of IC->info.
3860 If KEY is handled but no text is produced, return 0, otherwise
3866 filter (MInputContext *ic, MSymbol key, void *arg)
3868 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3869 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3872 if (check_reload (ic, key))
3875 if (! ic_info->state)
3877 ic_info->key_unhandled = 1;
3880 mtext_reset (ic->produced);
3881 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3882 M17N_OBJECT_UNREF (ic_info->preceding_text);
3883 M17N_OBJECT_UNREF (ic_info->following_text);
3884 ic_info->preceding_text = ic_info->following_text = NULL;
3885 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3886 ic_info->key_unhandled = 0;
3889 MPlist *candidate_list = ic->candidate_list;
3890 int candidate_index = ic->candidate_index;
3891 int candidate_show = ic->candidate_show;
3892 MTextProperty *prop;
3893 int result = handle_key (ic);
3895 if (ic->candidate_list)
3897 M17N_OBJECT_UNREF (ic->candidate_list);
3898 ic->candidate_list = NULL;
3900 if (ic->cursor_pos > 0
3901 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3904 ic->candidate_list = mtext_property_value (prop);
3905 M17N_OBJECT_REF (ic->candidate_list);
3907 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3909 ic->candidate_from = mtext_property_start (prop);
3910 ic->candidate_to = mtext_property_end (prop);
3912 if (candidate_list != ic->candidate_list)
3913 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3914 if (candidate_index != ic->candidate_index)
3915 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3916 if (candidate_show != ic->candidate_show)
3917 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3921 /* KEY was not handled. Delete it from the current key sequence. */
3922 if (ic_info->used > 0)
3924 memmove (ic_info->keys, ic_info->keys + 1,
3925 sizeof (int) * (ic_info->used - 1));
3927 if (ic_info->state_key_head > 0)
3928 ic_info->state_key_head--;
3929 if (ic_info->commit_key_head > 0)
3930 ic_info->commit_key_head--;
3932 /* This forces returning 1. */
3933 ic_info->key_unhandled = 1;
3939 reset_ic (ic, Mnil);
3940 ic_info->key_unhandled = 1;
3943 /* Break the loop if all keys were handled. */
3944 } while (ic_info->key_head < ic_info->used);
3946 /* If the current map is the root of the initial state, we should
3947 produce any preedit text in ic->produced. */
3948 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3949 preedit_commit (ic, 1);
3951 if (mtext_nchars (ic->produced) > 0)
3955 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3956 MSYMBOL_NAME (ic_info->state->name));
3957 for (i = 0; i < mtext_nchars (ic->produced); i++)
3958 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3962 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3963 Mlanguage, ic->im->language);
3965 if (ic_info->commit_key_head > 0)
3967 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3968 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3969 ic_info->used -= ic_info->commit_key_head;
3970 ic_info->key_head -= ic_info->commit_key_head;
3971 ic_info->state_key_head -= ic_info->commit_key_head;
3972 ic_info->commit_key_head = 0;
3974 if (ic_info->key_unhandled)
3977 ic_info->key_head = ic_info->state_key_head
3978 = ic_info->commit_key_head = 0;
3981 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3985 /** Return 1 if the last event or key was not handled, otherwise
3988 There is no need of looking up because ic->produced should already
3989 contain the produced text (if any).
3994 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3996 mtext_cat (mt, ic->produced);
3997 mtext_reset (ic->produced);
3998 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
4002 /* Input method command handler. */
4004 /* List of all (global and local) commands.
4005 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
4006 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
4007 Global commands are stored as (t (t COMMAND ...)) */
4010 /* Input method variable handler. */
4013 /* Support functions for mdebug_dump_im. */
4016 dump_im_map (MPlist *map_list, int indent)
4019 MSymbol key = MPLIST_KEY (map_list);
4020 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
4022 prefix = (char *) alloca (indent + 1);
4023 memset (prefix, 32, indent);
4024 prefix[indent] = '\0';
4026 fprintf (mdebug__output, "(\"%s\" ", msymbol_name (key));
4027 if (map->map_actions)
4028 mdebug_dump_plist (map->map_actions, indent + 2);
4031 MPLIST_DO (map_list, map->submaps)
4033 fprintf (mdebug__output, "\n%s ", prefix);
4034 dump_im_map (map_list, indent + 2);
4037 if (map->branch_actions)
4039 fprintf (mdebug__output, "\n%s (branch\n%s ", prefix, prefix);
4040 mdebug_dump_plist (map->branch_actions, indent + 4);
4041 fprintf (mdebug__output, ")");
4043 fprintf (mdebug__output, ")");
4048 dump_im_state (MIMState *state, int indent)
4053 prefix = (char *) alloca (indent + 1);
4054 memset (prefix, 32, indent);
4055 prefix[indent] = '\0';
4057 fprintf (mdebug__output, "(%s", msymbol_name (state->name));
4058 if (state->map->submaps)
4060 MPLIST_DO (map_list, state->map->submaps)
4062 fprintf (mdebug__output, "\n%s ", prefix);
4063 dump_im_map (map_list, indent + 2);
4066 fprintf (mdebug__output, ")");
4074 Minput_driver = msymbol ("input-driver");
4076 Minput_preedit_start = msymbol ("input-preedit-start");
4077 Minput_preedit_done = msymbol ("input-preedit-done");
4078 Minput_preedit_draw = msymbol ("input-preedit-draw");
4079 Minput_status_start = msymbol ("input-status-start");
4080 Minput_status_done = msymbol ("input-status-done");
4081 Minput_status_draw = msymbol ("input-status-draw");
4082 Minput_candidates_start = msymbol ("input-candidates-start");
4083 Minput_candidates_done = msymbol ("input-candidates-done");
4084 Minput_candidates_draw = msymbol ("input-candidates-draw");
4085 Minput_set_spot = msymbol ("input-set-spot");
4086 Minput_focus_move = msymbol ("input-focus-move");
4087 Minput_focus_in = msymbol ("input-focus-in");
4088 Minput_focus_out = msymbol ("input-focus-out");
4089 Minput_toggle = msymbol ("input-toggle");
4090 Minput_reset = msymbol ("input-reset");
4091 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4092 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4093 Mcustomized = msymbol ("customized");
4094 Mconfigured = msymbol ("configured");
4095 Minherited = msymbol ("inherited");
4097 minput_default_driver.open_im = open_im;
4098 minput_default_driver.close_im = close_im;
4099 minput_default_driver.create_ic = create_ic;
4100 minput_default_driver.destroy_ic = destroy_ic;
4101 minput_default_driver.filter = filter;
4102 minput_default_driver.lookup = lookup;
4103 minput_default_driver.callback_list = mplist ();
4104 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4105 M17N_FUNC (reset_ic));
4106 minput_driver = &minput_default_driver;
4108 fully_initialized = 0;
4115 if (fully_initialized)
4117 free_im_list (im_info_list);
4119 free_im_list (im_custom_list);
4121 free_im_list (im_config_list);
4122 M17N_OBJECT_UNREF (load_im_info_keys);
4125 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4126 M17N_OBJECT_UNREF (minput_driver->callback_list);
4131 minput__char_to_key (int c)
4133 if (c < 0 || c >= 0x100)
4136 return one_char_symbol[c];
4140 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4145 /*** @addtogroup m17nInputMethod */
4150 @brief Symbol whose name is "input-method".
4153 @brief "input-method" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
4155 MSymbol Minput_method;
4158 @name Variables: Predefined symbols for callback commands. */
4160 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4163 These are the predefined symbols that are used as the @c COMMAND
4164 argument of callback functions of an input method driver (see
4165 #MInputDriver::callback_list).
4167 Most of them do not require extra argument nor return any value;
4168 exceptions are these:
4170 @b Minput_get_surrounding_text: When a callback function assigned for
4171 this command is called, the first element of #MInputContext::plist
4172 has key #Minteger and the value specifies which portion of the
4173 surrounding text should be retrieved. If the value is positive,
4174 it specifies the number of characters following the current cursor
4175 position. If the value is negative, the absolute value specifies
4176 the number of characters preceding the current cursor position.
4177 If the value is zero, it means that the caller just wants to know
4178 if the surrounding text is currently supported or not.
4180 If the surrounding text is currently supported, the callback
4181 function must set the key of this element to #Mtext and the value
4182 to the retrieved M-text. The length of the M-text may be shorter
4183 than the requested number of characters, if the available text is
4184 not that long. The length can be zero in the worst case. Or, the
4185 length may be longer if an application thinks it is more efficient
4186 to return that length.
4188 If the surrounding text is not currently supported, the callback
4189 function should return without changing the first element of
4190 #MInputContext::plist.
4192 @b Minput_delete_surrounding_text: When a callback function assigned
4193 for this command is called, the first element of
4194 #MInputContext::plist has key #Minteger and the value specifies
4195 which portion of the surrounding text should be deleted in the
4196 same way as the case of Minput_get_surrounding_text. The callback
4197 function must delete the specified text. It should not alter
4198 #MInputContext::plist. */
4200 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4201 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4203 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4205 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4206 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4207 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4208 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4209 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4210 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4211 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4213 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4214 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4215 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4216 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4217 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4219 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4220 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4222 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4223 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4224 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4225 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4226 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4227 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4228 MSymbol Minput_preedit_start;
4229 MSymbol Minput_preedit_done;
4230 MSymbol Minput_preedit_draw;
4231 MSymbol Minput_status_start;
4232 MSymbol Minput_status_done;
4233 MSymbol Minput_status_draw;
4234 MSymbol Minput_candidates_start;
4235 MSymbol Minput_candidates_done;
4236 MSymbol Minput_candidates_draw;
4237 MSymbol Minput_set_spot;
4238 MSymbol Minput_toggle;
4239 MSymbol Minput_reset;
4240 MSymbol Minput_get_surrounding_text;
4241 MSymbol Minput_delete_surrounding_text;
4247 @name Variables: Predefined symbols for special input events.
4249 These are the predefined symbols that are used as the @c KEY
4250 argument of minput_filter (). */
4252 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4254 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4259 MSymbol Minput_focus_out;
4260 MSymbol Minput_focus_in;
4261 MSymbol Minput_focus_move;
4267 @name Variables: Predefined symbols used in input method information. */
4269 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4273 These are the predefined symbols describing status of input method
4274 command and variable, and are used in a return value of
4275 minput_get_command () and minput_get_variable (). */
4277 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4278 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4280 MSymbol Mcustomized;
4281 MSymbol Mconfigured;
4287 @brief The default driver for internal input methods.
4289 The variable #minput_default_driver is the default driver for
4290 internal input methods.
4292 The member MInputDriver::open_im () searches the m17n database for
4293 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4294 $NAME\> and loads it.
4296 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4297 programmers responsibility to set it to a plist of proper callback
4298 functions. Otherwise, no feedback information (e.g. preedit text)
4299 can be shown to users.
4301 The macro M17N_INIT () sets the variable #minput_driver to the
4302 pointer to this driver so that all internal input methods use it.
4304 Therefore, unless @c minput_driver is set differently, the driver
4305 dependent arguments $ARG of the functions whose name begins with
4306 "minput_" are all ignored. */
4308 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4310 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4312 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4313 \< #Minput_method, $LANGUAGE, $NAME\>
4314 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4316 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4317 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4318 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4319 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4321 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4322 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4324 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4325 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4327 MInputDriver minput_default_driver;
4331 @brief The driver for internal input methods.
4333 The variable #minput_driver is a pointer to the input method
4334 driver that is used by internal input methods. The macro
4335 M17N_INIT () initializes it to a pointer to #minput_default_driver
4336 if <m17n<EM></EM>.h> is included. */
4338 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4340 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4341 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4342 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4343 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4345 MInputDriver *minput_driver;
4349 The variable #Minput_driver is a symbol for a foreign input method.
4350 See @ref foreign-input-method "foreign input method" for the detail. */
4351 MSymbol Minput_driver;
4366 @brief Open an input method.
4368 The minput_open_im () function opens an input method whose
4369 language and name match $LANGUAGE and $NAME, and returns a pointer
4370 to the input method object newly allocated.
4372 This function at first decides a driver for the input method as
4375 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4376 #minput_driver is used.
4378 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4379 driver pointed to by the property value is used to open the input
4380 method. If $NAME has no such a property, @c NULL is returned.
4382 Then, the member MInputDriver::open_im () of the driver is
4385 $ARG is set in the member @c arg of the structure MInputMethod so
4386 that the driver can refer to it. */
4388 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4390 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4391 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4393 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4395 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4396 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4398 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4399 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4400 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4402 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4404 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4406 @latexonly \IPAlabel{minput_open} @endlatexonly
4411 minput_open_im (MSymbol language, MSymbol name, void *arg)
4414 MInputDriver *driver;
4418 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4419 msymbol_name (language), msymbol_name (name));
4423 MERROR (MERROR_IM, NULL);
4424 driver = minput_driver;
4428 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4430 MERROR (MERROR_IM, NULL);
4433 MSTRUCT_CALLOC (im, MERROR_IM);
4434 im->language = language;
4437 im->driver = *driver;
4438 if ((*im->driver.open_im) (im) < 0)
4440 MDEBUG_PRINT (" failed\n");
4444 MDEBUG_PRINT (" ok\n");
4451 @brief Close an input method.
4453 The minput_close_im () function closes the input method $IM, which
4454 must have been created by minput_open_im (). */
4457 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4459 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4460 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4463 minput_close_im (MInputMethod *im)
4465 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4466 msymbol_name (im->name), msymbol_name (im->language));
4467 (*im->driver.close_im) (im);
4469 MDEBUG_PRINT (" done\n");
4475 @brief Create an input context.
4477 The minput_create_ic () function creates an input context object
4478 associated with input method $IM, and calls callback functions
4479 corresponding to @b Minput_preedit_start, @b Minput_status_start, and
4480 @b Minput_status_draw in this order.
4483 If an input context is successfully created, minput_create_ic ()
4484 returns a pointer to it. Otherwise it returns @c NULL. */
4487 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4489 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4490 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4491 @b Minput_preedit_start, @b Minput_status_start, @b Minput_status_draw
4492 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4495 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4496 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4500 minput_create_ic (MInputMethod *im, void *arg)
4504 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4505 msymbol_name (im->name), msymbol_name (im->language));
4506 MSTRUCT_CALLOC (ic, MERROR_IM);
4509 ic->preedit = mtext ();
4510 ic->candidate_list = NULL;
4511 ic->produced = mtext ();
4512 ic->spot.x = ic->spot.y = 0;
4514 ic->plist = mplist ();
4515 if ((*im->driver.create_ic) (ic) < 0)
4517 MDEBUG_PRINT (" failed\n");
4518 M17N_OBJECT_UNREF (ic->preedit);
4519 M17N_OBJECT_UNREF (ic->produced);
4520 M17N_OBJECT_UNREF (ic->plist);
4525 if (im->driver.callback_list)
4527 minput_callback (ic, Minput_preedit_start);
4528 minput_callback (ic, Minput_status_start);
4529 minput_callback (ic, Minput_status_draw);
4532 MDEBUG_PRINT (" ok\n");
4539 @brief Destroy an input context.
4541 The minput_destroy_ic () function destroys the input context $IC,
4542 which must have been created by minput_create_ic (). It calls
4543 callback functions corresponding to @b Minput_preedit_done,
4544 @b Minput_status_done, and @b Minput_candidates_done in this order. */
4547 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4549 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4550 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4551 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4552 @b Minput_preedit_done, @b Minput_status_done, @b Minput_candidates_done
4553 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4557 minput_destroy_ic (MInputContext *ic)
4559 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4560 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4561 if (ic->im->driver.callback_list)
4563 minput_callback (ic, Minput_preedit_done);
4564 minput_callback (ic, Minput_status_done);
4565 minput_callback (ic, Minput_candidates_done);
4567 (*ic->im->driver.destroy_ic) (ic);
4568 M17N_OBJECT_UNREF (ic->preedit);
4569 M17N_OBJECT_UNREF (ic->produced);
4570 M17N_OBJECT_UNREF (ic->plist);
4571 MDEBUG_PRINT (" done\n");
4578 @brief Filter an input key.
4580 The minput_filter () function filters input key $KEY according to
4581 input context $IC, and calls callback functions corresponding to
4582 @b Minput_preedit_draw, @b Minput_status_draw, and
4583 @b Minput_candidates_draw if the preedit text, the status, and the
4584 current candidate are changed respectively.
4586 To make the input method commit the current preedit text (if any)
4587 and shift to the initial state, call this function with #Mnil as
4590 To inform the input method about the focus-out event, call this
4591 function with @b Minput_focus_out as $KEY.
4593 To inform the input method about the focus-in event, call this
4594 function with @b Minput_focus_in as $KEY.
4596 To inform the input method about the focus-move event (i.e. input
4597 spot change within the same input context), call this function
4598 with @b Minput_focus_move as $KEY.
4601 If $KEY is filtered out, this function returns 1. In that case,
4602 the caller should discard the key. Otherwise, it returns 0, and
4603 the caller should handle the key, for instance, by calling the
4604 function minput_lookup () with the same key. */
4607 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4609 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4610 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4611 @b Minput_preedit_draw, @b Minput_status_draw,
4612 @b Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4615 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4616 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4617 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4618 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4620 @latexonly \IPAlabel{minput_filter} @endlatexonly
4624 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4631 if (ic->im->driver.callback_list
4632 && mtext_nchars (ic->preedit) > 0)
4633 minput_callback (ic, Minput_preedit_draw);
4635 ret = (*ic->im->driver.filter) (ic, key, arg);
4637 if (ic->im->driver.callback_list)
4639 if (ic->preedit_changed)
4640 minput_callback (ic, Minput_preedit_draw);
4641 if (ic->status_changed)
4642 minput_callback (ic, Minput_status_draw);
4643 if (ic->candidates_changed)
4644 minput_callback (ic, Minput_candidates_draw);
4653 @brief Look up a text produced in the input context.
4655 The minput_lookup () function looks up a text in the input context
4656 $IC. $KEY must be identical to the one that was used in the previous call of
4659 If a text was produced by the input method, it is concatenated
4662 This function calls #MInputDriver::lookup .
4665 If $KEY was correctly handled by the input method, this function
4666 returns 0. Otherwise, it returns -1, even though some text
4667 might be produced in $MT. */
4670 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4672 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4673 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4675 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4678 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4681 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4682 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4683 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4685 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4688 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4690 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4695 @brief Set the spot of the input context.
4697 The minput_set_spot () function sets the spot of input context $IC
4698 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4699 The semantics of these values depends on the input method driver.
4701 For instance, a driver designed to work in a CUI environment may
4702 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4703 $DESCENT . A driver designed to work in a window system may
4704 interpret $X and $Y as the pixel offsets relative to the origin of the
4705 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4706 descent pixels of the line at ($X . $Y ).
4708 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4710 $MT and $POS are the M-text and the character position at the spot.
4711 $MT may be @c NULL, in which case, the input method cannot get
4712 information about the text around the spot. */
4715 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4717 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4718 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4719 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4721 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4722 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4723 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4724 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4725 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4726 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4728 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4730 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4731 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4735 minput_set_spot (MInputContext *ic, int x, int y,
4736 int ascent, int descent, int fontsize,
4741 ic->spot.ascent = ascent;
4742 ic->spot.descent = descent;
4743 ic->spot.fontsize = fontsize;
4746 if (ic->im->driver.callback_list)
4747 minput_callback (ic, Minput_set_spot);
4752 @brief Toggle input method.
4754 The minput_toggle () function toggles the input method associated
4755 with input context $IC. */
4757 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4759 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4760 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4764 minput_toggle (MInputContext *ic)
4766 if (ic->im->driver.callback_list)
4767 minput_callback (ic, Minput_toggle);
4768 ic->active = ! ic->active;
4774 @brief Reset an input context.
4776 The minput_reset_ic () function resets input context $IC by
4777 calling a callback function corresponding to @b Minput_reset. It
4778 resets the status of $IC to its initial one. As the
4779 current preedit text is deleted without commitment, if necessary,
4780 call minput_filter () with the arg @b key #Mnil to force the input
4781 method to commit the preedit in advance. */
4784 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4786 ´Ø¿ô minput_reset_ic () ¤Ï @b Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4787 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4788 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4789 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4790 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @b key #Mnil ¤Ç¸Æ¤ó¤Ç
4791 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4794 minput_reset_ic (MInputContext *ic)
4796 if (ic->im->driver.callback_list)
4797 minput_callback (ic, Minput_reset);
4803 @brief Get title and icon filename of an input method.
4805 The minput_get_title_icon () function returns a plist containing a
4806 title and icon filename (if any) of an input method specified by
4807 $LANGUAGE and $NAME.
4809 The first element of the plist has key #Mtext and the value is an
4810 M-text of the title for identifying the input method. The second
4811 element (if any) has key #Mtext and the value is an M-text of the
4812 icon image (absolute) filename for the same purpose.
4815 If there exists a specified input method and it defines an title,
4816 a plist is returned. Otherwise, NULL is returned. The caller
4817 must free the plist by m17n_object_unref (). */
4819 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4821 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4822 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4825 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4826 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4827 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4830 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4831 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4832 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4835 minput_get_title_icon (MSymbol language, MSymbol name)
4837 MInputMethodInfo *im_info;
4844 im_info = get_im_info (language, name, Mnil, Mtitle);
4845 if (! im_info || !im_info->title)
4847 mt = mtext_get_prop (im_info->title, 0, Mtext);
4849 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4852 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4855 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4856 (char *) MSYMBOL_NAME (name));
4857 file = mdatabase__find_file (buf);
4858 if (! file && language == Mt)
4860 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4861 file = mdatabase__find_file (buf);
4866 mplist_add (plist, Mtext, im_info->title);
4869 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4871 mplist_add (plist, Mtext, mt);
4872 M17N_OBJECT_UNREF (mt);
4880 @brief Get description text of an input method.
4882 The minput_get_description () function returns an M-text that
4883 describes the input method specified by $LANGUAGE and $NAME.
4886 If the specified input method has a description text, a pointer to
4887 #MText is returned. The caller has to free it by m17n_object_unref ().
4888 If the input method does not have a description text, @c NULL is
4891 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4893 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4894 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4897 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4898 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4899 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4900 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4903 minput_get_description (MSymbol language, MSymbol name)
4905 MInputMethodInfo *im_info;
4913 extra = language, language = Mt;
4915 im_info = get_im_info (language, name, extra, Mdescription);
4916 if (! im_info || ! im_info->description)
4918 M17N_OBJECT_REF (im_info->description);
4919 return im_info->description;
4925 @brief Get information about input method command(s).
4927 The minput_get_command () function returns information about
4928 the command $COMMAND of the input method specified by $LANGUAGE and
4929 $NAME. An input method command is a pseudo key event to which one
4930 or more actual input key sequences are assigned.
4932 There are two kinds of commands, global and local. A global
4933 command has a global definition, and the description and the key
4934 assignment may be inherited by a local command. Each input method
4935 defines a local command which has a local key assignment. It may
4936 also declare a local command that inherits the definition of a
4937 global command of the same name.
4939 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4940 information about a global command. Otherwise information about a
4941 local command is returned.
4943 If $COMMAND is #Mnil, information about all commands is returned.
4945 The return value is a @e well-formed plist (@ref m17nPlist) of this
4948 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4950 @c NAME is a symbol representing the command name.
4952 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4953 command has no description.
4955 @c STATUS is a symbol representing how the key assignment is decided.
4956 The value is #Mnil (the default key assignment), @b Mcustomized (the
4957 key assignment is customized by per-user customization file), or
4958 @b Mconfigured (the key assignment is set by the call of
4959 minput_config_command ()). For a local command only, it may also
4960 be @b Minherited (the key assignment is inherited from the
4961 corresponding global command).
4963 @c KEYSEQ is a plist of one or more symbols representing a key
4964 sequence assigned to the command. If there's no KEYSEQ, the
4965 command is currently disabled (i.e. no key sequence can trigger
4966 actions of the command).
4968 If $COMMAND is not #Mnil, the first element of the returned plist
4969 contains the information about $COMMAND.
4973 If the requested information was found, a pointer to a non-empty
4974 plist is returned. As the plist is kept in the library, the
4975 caller must not modify nor free it.
4977 Otherwise (the specified input method or the specified command
4978 does not exist), @c NULL is returned. */
4980 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4982 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4983 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4984 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4985 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4987 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4988 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4989 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4990 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4991 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4993 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4994 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4997 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4999 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5002 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
5004 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5006 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
5009 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
5010 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, @b Mcustomized ¡Ê¥æ¡¼
5011 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
5012 @b Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
5013 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
5014 @b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
5017 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
5018 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
5019 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
5020 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
5022 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
5023 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5027 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5028 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5031 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5036 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
5038 /* Return a description of the command COMMAND of the input method
5039 specified by LANGUAGE and NAME. */
5040 MPlist *cmd = minput_get_command (langauge, name, command);
5045 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
5046 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
5047 return (mplist_key (plist) == Mtext
5048 ? (MText *) mplist_value (plist)
5054 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5056 MInputMethodInfo *im_info;
5060 im_info = get_im_info (language, name, Mnil, Mcommand);
5062 || ! im_info->configured_cmds
5063 || MPLIST_TAIL_P (im_info->configured_cmds))
5065 if (command == Mnil)
5066 return im_info->configured_cmds;
5067 return mplist__assq (im_info->configured_cmds, command);
5073 @brief Configure the key sequence of an input method command.
5075 The minput_config_command () function assigns a list of key
5076 sequences $KEYSEQLIST to the command $COMMAND of the input method
5077 specified by $LANGUAGE and $NAME.
5079 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5080 sequences, and each key sequence must be a plist of symbols.
5082 If $KEYSEQLIST is an empty plist, any configuration and
5083 customization of the command are cancelled, and default key
5084 sequences become effective.
5086 If $KEYSEQLIST is NULL, the configuration of the command is
5087 canceled, and the original key sequences (what saved in per-user
5088 customization file, or the default one) become effective.
5090 In the latter two cases, $COMMAND can be #Mnil to make all the
5091 commands of the input method the target of the operation.
5093 If $NAME is #Mnil, this function configures the key assignment of a
5094 global command, not that of a specific input method.
5096 The configuration takes effect for input methods opened or
5097 re-opened later in the current session. In order to make the
5098 configuration take effect for the future session, it must be saved
5099 in a per-user customization file by the function
5100 minput_save_config ().
5103 If the operation was successful, this function returns 0,
5104 otherwise returns -1. The operation fails in these cases:
5106 <li>$KEYSEQLIST is not in a valid form.
5107 <li>$COMMAND is not available for the input method.
5108 <li>$LANGUAGE and $NAME do not specify an existing input method.
5112 minput_get_commands (), minput_save_config ().
5115 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5117 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5118 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5119 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5121 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5122 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5124 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5125 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5127 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5128 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5129 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5131 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5132 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5134 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5135 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5137 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5138 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5139 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5140 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5144 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5146 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5147 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5148 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5152 minput_get_commands (), minput_save_config ().
5156 /* Add "C-x u" to the "start" command of Unicode input method. */
5158 MSymbol start_command = msymbol ("start");
5159 MSymbol unicode = msymbol ("unicode");
5160 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5162 /* At first get the current key-sequence assignment. */
5163 cmd = minput_get_command (Mt, unicode, start_command);
5166 /* The input method does not have the command "start". Here
5167 should come some error handling code. */
5169 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5170 Extract the part (KEY-SEQUENCE ...). */
5171 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5172 /* Copy it because we should not modify it directly. */
5173 key_seq_list = mplist_copy (plist);
5175 key_seq = mplist ();
5176 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5177 mplist_add (key_seq, Msymbol, msymbol ("u"));
5178 mplist_add (key_seq_list, Mplist, key_seq);
5179 m17n_object_unref (key_seq);
5181 minput_config_command (Mt, unicode, start_command, key_seq_list);
5182 m17n_object_unref (key_seq_list);
5187 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5190 MInputMethodInfo *im_info, *config;
5195 im_info = get_im_info (language, name, Mnil, Mcommand);
5197 MERROR (MERROR_IM, -1);
5198 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5200 || ! mplist__assq (im_info->configured_cmds, command)))
5201 MERROR (MERROR_IM, -1);
5202 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5204 MPLIST_DO (plist, keyseqlist)
5205 if (! check_command_keyseq (plist))
5206 MERROR (MERROR_IM, -1);
5209 config = get_config_info (im_info);
5212 if (! im_config_list)
5213 im_config_list = mplist ();
5214 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5215 config->cmds = mplist ();
5216 config->vars = mplist ();
5219 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5220 /* Nothing to do. */
5223 if (command == Mnil)
5227 /* Cancal the configuration. */
5228 if (MPLIST_TAIL_P (config->cmds))
5230 mplist_set (config->cmds, Mnil, NULL);
5234 /* Cancal the customization. */
5235 MInputMethodInfo *custom = get_custom_info (im_info);
5237 if (MPLIST_TAIL_P (config->cmds)
5238 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5239 /* Nothing to do. */
5241 mplist_set (config->cmds, Mnil, NULL);
5242 MPLIST_DO (plist, custom->cmds)
5244 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5246 mplist_add (plist, Msymbol, command);
5247 mplist_push (config->cmds, Mplist, plist);
5248 M17N_OBJECT_UNREF (plist);
5254 plist = mplist__assq (config->cmds, command);
5257 /* Cancel the configuration. */
5260 mplist__pop_unref (plist);
5262 else if (MPLIST_TAIL_P (keyseqlist))
5264 /* Cancel the customization. */
5265 MInputMethodInfo *custom = get_custom_info (im_info);
5266 int no_custom = (! custom || ! custom->cmds
5267 || ! mplist__assq (custom->cmds, command));
5273 mplist_add (config->cmds, Mplist, plist);
5274 M17N_OBJECT_UNREF (plist);
5275 plist = mplist_add (plist, Msymbol, command);
5280 mplist__pop_unref (plist);
5283 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5284 plist = MPLIST_NEXT (plist);
5285 mplist_set (plist, Mnil, NULL);
5295 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5296 if (! MPLIST_TAIL_P (plist))
5297 mplist_set (plist, Mnil, NULL);
5302 mplist_add (config->cmds, Mplist, plist);
5303 M17N_OBJECT_UNREF (plist);
5304 plist = mplist_add (plist, Msymbol, command);
5305 plist = MPLIST_NEXT (plist);
5307 MPLIST_DO (keyseqlist, keyseqlist)
5309 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5310 plist = mplist_add (plist, Mplist, pl);
5311 M17N_OBJECT_UNREF (pl);
5315 config_all_commands (im_info);
5316 im_info->tick = time (NULL);
5323 @brief Get information about input method variable(s).
5325 The minput_get_variable () function returns information about
5326 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5327 An input method variable controls behavior of an input method.
5329 There are two kinds of variables, global and local. A global
5330 variable has a global definition, and the description and the value
5331 may be inherited by a local variable. Each input method defines a
5332 local variable which has local value. It may also declare a
5333 local variable that inherits definition of a global variable of
5336 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5337 variable is returned. Otherwise information about a local variable
5340 If $VARIABLE is #Mnil, information about all variables is
5343 The return value is a @e well-formed plist (@ref m17nPlist) of this
5346 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5348 @c NAME is a symbol representing the variable name.
5350 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5351 variable has no description.
5353 @c STATUS is a symbol representing how the value is decided. The
5354 value is #Mnil (the default value), @b Mcustomized (the value is
5355 customized by per-user customization file), or @b Mconfigured (the
5356 value is set by the call of minput_config_variable ()). For a
5357 local variable only, it may also be @b Minherited (the value is
5358 inherited from the corresponding global variable).
5360 @c VALUE is the initial value of the variable. If the key of this
5361 element is #Mt, the variable has no initial value. Otherwise, the
5362 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5365 @c VALID-VALUEs (if any) specify which values the variable can have.
5366 They have the same type (i.e. having the same key) as @c VALUE except
5367 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5368 may be a plist of two integers specifying the range of possible
5371 If there no @c VALID-VALUE, the variable can have any value as long
5372 as the type is the same as @c VALUE.
5374 If $VARIABLE is not #Mnil, the first element of the returned plist
5375 contains the information about $VARIABLE.
5379 If the requested information was found, a pointer to a non-empty
5380 plist is returned. As the plist is kept in the library, the
5381 caller must not modify nor free it.
5383 Otherwise (the specified input method or the specified variable
5384 does not exist), @c NULL is returned. */
5386 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5388 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5389 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5390 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5392 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5393 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5394 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5395 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5398 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5399 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5401 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5403 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5405 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5408 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5410 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5413 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5414 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, @b Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5415 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, @b Mconfigured
5416 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5417 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢@b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5418 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5420 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5421 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5422 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5424 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5425 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5426 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5427 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5429 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5432 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5433 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5437 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5438 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5441 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5445 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5447 MInputMethodInfo *im_info;
5451 im_info = get_im_info (language, name, Mnil, Mvariable);
5452 if (! im_info || ! im_info->configured_vars)
5454 if (variable == Mnil)
5455 return im_info->configured_vars;
5456 return mplist__assq (im_info->configured_vars, variable);
5462 @brief Configure the value of an input method variable.
5464 The minput_config_variable () function assigns $VALUE to the
5465 variable $VARIABLE of the input method specified by $LANGUAGE and
5468 If $VALUE is a non-empty plist, it must be a plist of one element
5469 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5470 the corresponding type. That value is assigned to the variable.
5472 If $VALUE is an empty plist, any configuration and customization
5473 of the variable are canceled, and the default value is assigned to
5476 If $VALUE is NULL, the configuration of the variable is canceled,
5477 and the original value (what saved in per-user customization file,
5478 or the default value) is assigned to the variable.
5480 In the latter two cases, $VARIABLE can be #Mnil to make all the
5481 variables of the input method the target of the operation.
5483 If $NAME is #Mnil, this function configures the value of global
5484 variable, not that of a specific input method.
5486 The configuration takes effect for input methods opened or
5487 re-opened later in the current session. To make the configuration
5488 take effect for the future session, it must be saved in a per-user
5489 customization file by the function minput_save_config ().
5493 If the operation was successful, this function returns 0,
5494 otherwise returns -1. The operation fails in these cases:
5496 <li>$VALUE is not in a valid form, the type does not match the
5497 definition, or the value is our of range.
5498 <li>$VARIABLE is not available for the input method.
5499 <li>$LANGUAGE and $NAME do not specify an existing input method.
5503 minput_get_variable (), minput_save_config (). */
5505 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5507 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5508 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5510 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5511 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5512 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5514 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5515 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5517 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5518 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5520 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5521 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5523 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5524 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5526 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5527 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5528 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5529 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5533 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5535 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5536 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5537 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5541 minput_get_commands (), minput_save_config ().
5544 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5547 MInputMethodInfo *im_info, *config;
5552 im_info = get_im_info (language, name, Mnil, Mvariable);
5554 MERROR (MERROR_IM, -1);
5555 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5557 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5558 MERROR (MERROR_IM, -1);
5560 if (value && ! MPLIST_TAIL_P (value))
5562 plist = MPLIST_PLIST (plist);
5563 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5564 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5565 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5566 if (MPLIST_KEY (plist) != Mt
5567 && ! check_variable_value (value, plist))
5568 MERROR (MERROR_IM, -1);
5571 config = get_config_info (im_info);
5574 if (! im_config_list)
5575 im_config_list = mplist ();
5576 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5577 config->cmds = mplist ();
5578 config->vars = mplist ();
5581 if (! value && MPLIST_TAIL_P (config->vars))
5582 /* Nothing to do. */
5585 if (variable == Mnil)
5589 /* Cancel the configuration. */
5590 if (MPLIST_TAIL_P (config->vars))
5592 mplist_set (config->vars, Mnil, NULL);
5596 /* Cancel the customization. */
5597 MInputMethodInfo *custom = get_custom_info (im_info);
5599 if (MPLIST_TAIL_P (config->vars)
5600 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5601 /* Nothing to do. */
5603 mplist_set (config->vars, Mnil, NULL);
5604 MPLIST_DO (plist, custom->vars)
5606 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5608 mplist_add (plist, Msymbol, variable);
5609 mplist_push (config->vars, Mplist, plist);
5610 M17N_OBJECT_UNREF (plist);
5616 plist = mplist__assq (config->vars, variable);
5619 /* Cancel the configuration. */
5622 mplist__pop_unref (plist);
5624 else if (MPLIST_TAIL_P (value))
5626 /* Cancel the customization. */
5627 MInputMethodInfo *custom = get_custom_info (im_info);
5628 int no_custom = (! custom || ! custom->vars
5629 || ! mplist__assq (custom->vars, variable));
5635 mplist_add (config->vars, Mplist, plist);
5636 M17N_OBJECT_UNREF (plist);
5637 plist = mplist_add (plist, Msymbol, variable);
5642 mplist__pop_unref (plist);
5645 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5646 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5647 mplist_set (plist, Mnil ,NULL);
5655 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5656 if (! MPLIST_TAIL_P (plist))
5657 mplist_set (plist, Mnil, NULL);
5662 mplist_add (config->vars, Mplist, plist);
5663 M17N_OBJECT_UNREF (plist);
5664 plist = mplist_add (plist, Msymbol, variable);
5665 plist = MPLIST_NEXT (plist);
5667 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5670 config_all_variables (im_info);
5671 im_info->tick = time (NULL);
5678 @brief Get the name of per-user customization file.
5680 The minput_config_file () function returns the absolute path name
5681 of per-user customization file into which minput_save_config ()
5682 save configurations. It is usually @c config.mic under the
5683 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5684 directory). It is not assured that the file of the returned name
5685 exists nor is readable/writable. If minput_save_config () fails
5686 and returns -1, an application program might check the file, make
5687 it writable (if possible), and try minput_save_config () again.
5691 This function returns a string. As the string is kept in the
5692 library, the caller must not modify nor free it.
5695 minput_save_config ()
5698 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5700 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5701 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5702 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5703 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5704 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5705 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5706 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5711 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5712 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5715 minput_save_config ()
5719 minput_config_file ()
5723 return mdatabase__file (im_custom_mdb);
5729 @brief Save configurations in per-user customization file.
5731 The minput_save_config () function saves the configurations done
5732 so far in the current session into the per-user customization
5737 If the operation was successful, 1 is returned. If the per-user
5738 customization file is currently locked, 0 is returned. In that
5739 case, the caller may wait for a while and try again. If the
5740 configuration file is not writable, -1 is returned. In that case,
5741 the caller may check the name of the file by calling
5742 minput_config_file (), make it writable if possible, and try
5746 minput_config_file () */
5748 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5750 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5751 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5755 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5756 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5757 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5758 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5762 minput_config_file () */
5765 minput_save_config (void)
5767 MPlist *data, *tail, *plist, *p, *elt;
5771 ret = mdatabase__lock (im_custom_mdb);
5774 if (! im_config_list)
5776 update_custom_info ();
5777 if (! im_custom_list)
5778 im_custom_list = mplist ();
5780 /* At first, reflect configuration in customization. */
5781 MPLIST_DO (plist, im_config_list)
5783 MPlist *pl = MPLIST_PLIST (plist);
5784 MSymbol language, name, extra, command, variable;
5785 MInputMethodInfo *custom, *config;
5787 language = MPLIST_SYMBOL (pl);
5788 pl = MPLIST_NEXT (pl);
5789 name = MPLIST_SYMBOL (pl);
5790 pl = MPLIST_NEXT (pl);
5791 extra = MPLIST_SYMBOL (pl);
5792 pl = MPLIST_NEXT (pl);
5793 config = MPLIST_VAL (pl);
5794 custom = get_custom_info (config);
5796 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5798 MPLIST_DO (pl, config->cmds)
5800 elt = MPLIST_PLIST (pl);
5801 command = MPLIST_SYMBOL (elt);
5803 p = mplist__assq (custom->cmds, command);
5805 custom->cmds = mplist (), p = NULL;
5806 elt = MPLIST_NEXT (elt);
5809 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5810 mplist_set (p, Mnil, NULL);
5815 mplist_add (custom->cmds, Mplist, p);
5816 M17N_OBJECT_UNREF (p);
5817 mplist_add (p, Msymbol, command);
5818 p = mplist_add (p, Msymbol, Mnil);
5819 p = MPLIST_NEXT (p);
5821 mplist__conc (p, elt);
5824 MPLIST_DO (pl, config->vars)
5826 elt = MPLIST_PLIST (pl);
5827 variable = MPLIST_SYMBOL (elt);
5829 p = mplist__assq (custom->vars, variable);
5831 custom->vars = mplist (), p = NULL;
5832 elt = MPLIST_NEXT (elt);
5835 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5836 mplist_set (p, Mnil, NULL);
5841 mplist_add (custom->vars, Mplist, p);
5842 M17N_OBJECT_UNREF (p);
5843 mplist_add (p, Msymbol, variable);
5844 p = mplist_add (p, Msymbol, Mnil);
5845 p = MPLIST_NEXT (p);
5847 mplist__conc (p, elt);
5850 free_im_list (im_config_list);
5851 im_config_list = NULL;
5853 /* Next, reflect customization to the actual plist to be written. */
5854 data = tail = mplist ();
5855 MPLIST_DO (plist, im_custom_list)
5857 MPlist *pl = MPLIST_PLIST (plist);
5858 MSymbol language, name, extra;
5859 MInputMethodInfo *custom, *im_info;
5861 language = MPLIST_SYMBOL (pl);
5862 pl = MPLIST_NEXT (pl);
5863 name = MPLIST_SYMBOL (pl);
5864 pl = MPLIST_NEXT (pl);
5865 extra = MPLIST_SYMBOL (pl);
5866 pl = MPLIST_NEXT (pl);
5867 custom = MPLIST_VAL (pl);
5868 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5869 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5871 im_info = lookup_im_info (im_info_list, language, name, extra);
5875 config_all_commands (im_info);
5877 config_all_variables (im_info);
5881 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5883 MPLIST_DO (p, custom->cmds)
5884 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5886 if (! MPLIST_TAIL_P (p))
5890 mplist_add (elt, Mplist, pl);
5891 M17N_OBJECT_UNREF (pl);
5892 pl = mplist_add (pl, Msymbol, Mcommand);
5893 MPLIST_DO (p, custom->cmds)
5894 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5895 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5898 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5900 MPLIST_DO (p, custom->vars)
5901 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5903 if (! MPLIST_TAIL_P (p))
5908 mplist_add (elt, Mplist, pl);
5909 M17N_OBJECT_UNREF (pl);
5910 pl = mplist_add (pl, Msymbol, Mvariable);
5911 MPLIST_DO (p, custom->vars)
5912 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5913 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5919 mplist_push (elt, Mplist, pl);
5920 M17N_OBJECT_UNREF (pl);
5921 pl = mplist_add (pl, Msymbol, Minput_method);
5922 pl = mplist_add (pl, Msymbol, language);
5923 pl = mplist_add (pl, Msymbol, name);
5925 pl = mplist_add (pl, Msymbol, extra);
5926 tail = mplist_add (tail, Mplist, elt);
5927 M17N_OBJECT_UNREF (elt);
5931 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5932 ret = mdatabase__save (im_custom_mdb, data);
5933 mdatabase__unlock (im_custom_mdb);
5934 M17N_OBJECT_UNREF (data);
5935 return (ret < 0 ? -1 : 1);
5939 @brief List available input methods.
5941 The minput_list () function returns a list of currently available
5942 input methods whose language is $LANGUAGE. If $LANGUAGE is #Mnil,
5943 all input methods are listed.
5946 The returned value is a plist of this form:
5947 ((LANGUAGE-NAME INPUT-METHOD-NAME SANE) ...)
5948 The third element SANE of each input method is #Mt if it can be
5949 successfully used, or #Mnil if it has some problem (e.g. syntax
5950 error of MIM file, unavailable external module, unavailable
5951 including input method). */
5959 main (int argc, char **argv)
5961 MPlist *imlist, *pl;
5964 imlist = minput_list ((argc > 1) ? msymbol (argv[1]) : Mnil);
5965 for (pl = imlist; mplist_key (pl) != Mnil; pl = mplist_next (pl))
5967 MPlist *p = mplist_value (pl);
5968 MSymbol lang, name, sane;
5970 lang = mplist_value (p);
5971 p = mplist_next (p);
5972 name = mplist_value (p);
5973 p = mplist_next (p);
5974 sane = mplist_value (p);
5976 printf ("%s %s %s\n", msymbol_name (lang), msymbol_name (name),
5977 sane == Mt ? "ok" : "no");
5980 m17n_object_unref (imlist);
5987 minput_list (MSymbol language)
5990 MPlist *imlist = mplist ();
5993 plist = mdatabase_list (Minput_method, language, Mnil, Mnil);
5996 MPLIST_DO (pl, plist)
5998 MDatabase *mdb = MPLIST_VAL (pl);
5999 MSymbol *tag = mdatabase_tag (mdb);
6000 MPlist *imdata, *p, *elm;
6001 int num_maps = 0, num_states = 0;
6005 imdata = mdatabase_load (mdb);
6008 MPLIST_DO (p, imdata)
6009 if (MPLIST_PLIST_P (p))
6011 /* Check these basic functionarity:
6012 All external modules (if any) are loadable.
6013 All included input method (if any) are loadable.
6014 At least one map is defined or included.
6015 At least one state is defined or included. */
6016 MPlist *elt = MPLIST_PLIST (p);
6019 if (MFAILP (MPLIST_SYMBOL_P (elt)))
6021 key = MPLIST_SYMBOL (elt);
6024 else if (key == Mstate)
6026 else if (key == Mmodule)
6028 MPLIST_DO (elt, MPLIST_NEXT (elt))
6030 MIMExternalModule *external;
6032 if (MFAILP (MPLIST_PLIST_P (elt)))
6034 external = load_external_module (MPLIST_PLIST (elt));
6035 if (MFAILP (external))
6037 unload_external_module (external);
6039 if (! MPLIST_TAIL_P (elt))
6042 else if (key == Minclude)
6044 MInputMethodInfo *im_info;
6046 elt = MPLIST_NEXT (elt);
6047 if (MFAILP (MPLIST_PLIST_P (elt)))
6049 im_info = get_im_info_by_tags (MPLIST_PLIST (elt));
6050 if (MFAILP (im_info))
6052 elt = MPLIST_NEXT (elt);
6053 if (MFAILP (MPLIST_SYMBOL_P (elt)))
6055 key = MPLIST_SYMBOL (elt);
6058 if (! im_info->maps)
6062 else if (key == Mstate)
6064 if (! im_info->states)
6071 mplist_add (elm, Msymbol, tag[1]);
6072 mplist_add (elm, Msymbol, tag[2]);
6073 if (MPLIST_TAIL_P (p) && num_maps > 0 && num_states > 0)
6074 mplist_add (elm, Msymbol, Mt);
6076 mplist_add (elm, Msymbol, Mnil);
6077 mplist_push (imlist, Mplist, elm);
6078 M17N_OBJECT_UNREF (elm);
6079 M17N_OBJECT_UNREF (imdata);
6081 M17N_OBJECT_UNREF (plist);
6089 @name Obsolete functions
6092 @name Obsolete ¤Ê´Ø¿ô
6098 @brief Get a list of variables of an input method (obsolete).
6100 This function is obsolete. Use minput_get_variable () instead.
6102 The minput_get_variables () function returns a plist (#MPlist) of
6103 variables used to control the behavior of the input method
6104 specified by $LANGUAGE and $NAME. The plist is @e well-formed
6105 (@ref m17nPlist) of the following format:
6108 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6109 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6113 @c VARNAME is a symbol representing the variable name.
6115 @c DOC-MTEXT is an M-text describing the variable.
6117 @c DEFAULT-VALUE is the default value of the variable. It is a
6118 symbol, integer, or M-text.
6120 @c VALUEs (if any) specifies the possible values of the variable.
6121 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
6122 @c TO), where @c FROM and @c TO specifies a range of possible
6125 For instance, suppose an input method has the variables:
6127 @li name:intvar, description:"value is an integer",
6128 initial value:0, value-range:0..3,10,20
6130 @li name:symvar, description:"value is a symbol",
6131 initial value:nil, value-range:a, b, c, nil
6133 @li name:txtvar, description:"value is an M-text",
6134 initial value:empty text, no value-range (i.e. any text)
6136 Then, the returned plist is as follows.
6139 (intvar ("value is an integer" 0 (0 3) 10 20)
6140 symvar ("value is a symbol" nil a b c nil)
6141 txtvar ("value is an M-text" ""))
6145 If the input method uses any variables, a pointer to #MPlist is
6146 returned. As the plist is kept in the library, the caller must not
6147 modify nor free it. If the input method does not use any
6148 variable, @c NULL is returned. */
6150 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
6152 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6153 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
6154 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
6158 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6159 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6163 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6165 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
6167 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
6170 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
6171 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
6172 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
6174 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
6176 @li name:intvar, ÀâÌÀ:"value is an integer",
6177 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
6179 @li name:symvar, ÀâÌÀ:"value is a symbol",
6180 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
6182 @li name:txtvar, ÀâÌÀ:"value is an M-text",
6183 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
6185 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
6188 (intvar ("value is an integer" 0 (0 3) 10 20)
6189 symvar ("value is a symbol" nil a b c nil)
6190 txtvar ("value is an M-text" ""))
6194 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
6195 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6196 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
6199 minput_get_variables (MSymbol language, MSymbol name)
6201 MInputMethodInfo *im_info;
6206 im_info = get_im_info (language, name, Mnil, Mvariable);
6207 if (! im_info || ! im_info->configured_vars)
6210 M17N_OBJECT_UNREF (im_info->bc_vars);
6211 im_info->bc_vars = mplist ();
6212 MPLIST_DO (vars, im_info->configured_vars)
6214 MPlist *plist = MPLIST_PLIST (vars);
6215 MPlist *elt = mplist ();
6217 mplist_push (im_info->bc_vars, Mplist, elt);
6218 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6219 elt = MPLIST_NEXT (elt);
6220 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6221 M17N_OBJECT_UNREF (elt);
6223 return im_info->bc_vars;
6229 @brief Set the initial value of an input method variable.
6231 The minput_set_variable () function sets the initial value of
6232 input method variable $VARIABLE to $VALUE for the input method
6233 specified by $LANGUAGE and $NAME.
6235 By default, the initial value is 0.
6237 This setting gets effective in a newly opened input method.
6240 If the operation was successful, 0 is returned. Otherwise -1 is
6241 returned, and #merror_code is set to @c MERROR_IM. */
6243 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6245 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6246 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6247 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6249 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6251 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6254 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6255 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6258 minput_set_variable (MSymbol language, MSymbol name,
6259 MSymbol variable, void *value)
6262 MInputMethodInfo *im_info;
6267 if (variable == Mnil)
6268 MERROR (MERROR_IM, -1);
6269 plist = minput_get_variable (language, name, variable);
6270 plist = MPLIST_PLIST (plist);
6271 plist = MPLIST_NEXT (plist);
6273 mplist_add (pl, MPLIST_KEY (plist), value);
6274 ret = minput_config_variable (language, name, variable, pl);
6275 M17N_OBJECT_UNREF (pl);
6278 im_info = get_im_info (language, name, Mnil, Mvariable);
6287 @brief Get information about input method commands.
6289 The minput_get_commands () function returns information about
6290 input method commands of the input method specified by $LANGUAGE
6291 and $NAME. An input method command is a pseudo key event to which
6292 one or more actual input key sequences are assigned.
6294 There are two kinds of commands, global and local. Global
6295 commands are used by multiple input methods for the same purpose,
6296 and have global key assignments. Local commands are used only by
6297 a specific input method, and have only local key assignments.
6299 Each input method may locally change key assignments for global
6300 commands. The global key assignment for a global command is
6301 effective only when the current input method does not have local
6302 key assignments for that command.
6304 If $NAME is #Mnil, information about global commands is returned.
6305 In this case $LANGUAGE is ignored.
6307 If $NAME is not #Mnil, information about those commands that have
6308 local key assignments in the input method specified by $LANGUAGE
6309 and $NAME is returned.
6312 If no input method commands are found, this function returns @c NULL.
6314 Otherwise, a pointer to a plist is returned. The key of each
6315 element in the plist is a symbol representing a command, and the
6316 value is a plist of the form COMMAND-INFO described below.
6318 The first element of COMMAND-INFO has the key #Mtext, and the
6319 value is an M-text describing the command.
6321 If there are no more elements, that means no key sequences are
6322 assigned to the command. Otherwise, each of the remaining
6323 elements has the key #Mplist, and the value is a plist whose keys are
6324 #Msymbol and values are symbols representing input keys, which are
6325 currently assigned to the command.
6327 As the returned plist is kept in the library, the caller must not
6328 modify nor free it. */
6330 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6332 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6333 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6334 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6335 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6337 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6338 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6339 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6340 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6342 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6343 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6344 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6347 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6348 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6350 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6351 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6355 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6357 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6358 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6359 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6361 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6362 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6363 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6366 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6367 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6368 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6369 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6370 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6372 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6373 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6376 minput_get_commands (MSymbol language, MSymbol name)
6378 MInputMethodInfo *im_info;
6383 im_info = get_im_info (language, name, Mnil, Mcommand);
6384 if (! im_info || ! im_info->configured_vars)
6386 M17N_OBJECT_UNREF (im_info->bc_cmds);
6387 im_info->bc_cmds = mplist ();
6388 MPLIST_DO (cmds, im_info->configured_cmds)
6390 MPlist *plist = MPLIST_PLIST (cmds);
6391 MPlist *elt = mplist ();
6393 mplist_push (im_info->bc_cmds, Mplist, elt);
6394 mplist_add (elt, MPLIST_SYMBOL (plist),
6395 mplist_copy (MPLIST_NEXT (plist)));
6396 M17N_OBJECT_UNREF (elt);
6398 return im_info->bc_cmds;
6404 @brief Assign a key sequence to an input method command (obsolete).
6406 This function is obsolete. Use minput_config_command () instead.
6408 The minput_assign_command_keys () function assigns input key
6409 sequence $KEYSEQ to input method command $COMMAND for the input
6410 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6411 key sequence is assigned globally no matter what $LANGUAGE is.
6412 Otherwise the key sequence is assigned locally.
6414 Each element of $KEYSEQ must have the key $Msymbol and the value
6415 must be a symbol representing an input key.
6417 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6418 globally or locally.
6420 This assignment gets effective in a newly opened input method.
6423 If the operation was successful, 0 is returned. Otherwise -1 is
6424 returned, and #merror_code is set to @c MERROR_IM. */
6426 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6428 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6429 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6430 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6431 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6432 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6434 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6435 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6437 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6438 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6440 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6444 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6445 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6448 minput_assign_command_keys (MSymbol language, MSymbol name,
6449 MSymbol command, MPlist *keyseq)
6455 if (command == Mnil)
6456 MERROR (MERROR_IM, -1);
6461 if (! check_command_keyseq (keyseq))
6462 MERROR (MERROR_IM, -1);
6464 mplist_add (plist, Mplist, keyseq);
6469 ret = minput_config_command (language, name, command, keyseq);
6470 M17N_OBJECT_UNREF (keyseq);
6477 @brief Call a callback function
6479 The minput_callback () functions calls a callback function
6480 $COMMAND assigned for the input context $IC. The caller must set
6481 specific elements in $IC->plist if the callback function requires.
6484 If there exists a specified callback function, 0 is returned.
6485 Otherwise -1 is returned. By side effects, $IC->plist may be
6489 minput_callback (MInputContext *ic, MSymbol command)
6491 MInputCallbackFunc func;
6493 if (! ic->im->driver.callback_list)
6495 func = ((MInputCallbackFunc)
6496 mplist_get_func (ic->im->driver.callback_list, command));
6499 (func) (ic, command);
6506 /*** @addtogroup m17nDebug */
6512 @brief Dump an input method.
6514 The mdebug_dump_im () function prints the input method $IM in a
6515 human readable way to the stderr or to what specified by the
6516 environment variable MDEBUG_OUTPUT_FILE. $INDENT specifies how
6517 many columns to indent the lines but the first one.
6520 This function returns $IM. */
6522 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6524 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤òɸ½à¥¨¥é¡¼½ÐÎϤ⤷¤¯¤Ï
6525 ´Ä¶ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç½Ð
6526 ÎϤ¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6529 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6532 mdebug_dump_im (MInputMethod *im, int indent)
6534 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6537 prefix = (char *) alloca (indent + 1);
6538 memset (prefix, 32, indent);
6539 prefix[indent] = '\0';
6541 fprintf (mdebug__output, "(input-method %s %s ", msymbol_name (im->language),
6542 msymbol_name (im->name));
6543 mdebug_dump_mtext (im_info->title, 0, 0);
6544 if (im->name != Mnil)
6548 MPLIST_DO (state, im_info->states)
6550 fprintf (mdebug__output, "\n%s ", prefix);
6551 dump_im_state (MPLIST_VAL (state), indent + 2);
6554 fprintf (mdebug__output, ")");