1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32], buf3[2];
284 /* Maximum case: '\215', C-M-m, C-M-M, M-Return, C-A-m, C-A-M, A-Return
285 plus one for cyclic alias. */
288 M_key_alias = msymbol (" key-alias");
292 /* Aliases for 0x00-0x1F */
296 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
300 alias[j++] = msymbol (buf3);
301 alias[j++] = one_char_symbol[i] = msymbol (buf);
302 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
306 /* Ex: `Escape' == `C-[' */
307 alias[j++] = msymbol (key_names[i]);
309 if (buf[2] >= 'A' && buf[2] <= 'Z')
311 /* Ex: `C-a' == `C-A' */
313 alias[j++] = msymbol (buf);
317 /* Establish cyclic alias chain. */
320 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
323 /* Aliases for 0x20-0x7E */
325 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
327 one_char_symbol[i] = msymbol (buf + 2);
328 if (i >= 'A' && i <= 'Z')
330 /* Ex: `A' == `S-A' == `S-a'. */
331 alias[0] = alias[3] = one_char_symbol[i];
332 alias[1] = msymbol (buf);
334 alias[2] = msymbol (buf);
336 for (j = 0; j < 3; j++)
337 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
341 /* Aliases for 0x7F */
343 alias[0] = alias[3] = msymbol (buf3);
344 alias[1] = one_char_symbol[127] = msymbol ("Delete");
345 alias[2] = msymbol ("C-?");
346 for (j = 0; j < 3; j++)
347 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
349 /* Aliases for 0x80-0x9F */
351 /* buf[1] = '-'; -- already done */
355 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
359 alias[j++] = msymbol (buf3);
360 /* `C-M-a' == `C-A-a' */
362 alias[j++] = one_char_symbol[i] = msymbol (buf);
364 alias[j++] = msymbol (buf);
365 if (key_names[i - 128])
367 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
369 strcpy (buf2 + 2, key_names[i - 128]);
370 alias[j++] = msymbol (buf2);
372 alias[j++] = msymbol (buf2);
374 if (buf[4] >= 'A' && buf[4] <= 'Z')
376 /* Ex: `C-M-a' == `C-M-A'. */
379 alias[j++] = msymbol (buf);
381 alias[j++] = msymbol (buf);
385 /* Establish cyclic alias chain. */
388 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
391 /* Aliases for 0xA0-0xFF */
392 for (i = 160, buf[4] = ' '; i < 255; i++, buf[4]++)
396 alias[j++] = msymbol (buf3);
398 alias[j++] = one_char_symbol[i] = msymbol (buf + 2);
400 alias[j++] = msymbol (buf + 2);
403 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
407 alias[0] = alias[3] = msymbol (buf3);
408 alias[1] = one_char_symbol[255] = msymbol ("M-Delete");
409 alias[2] = msymbol ("A-Delete");
410 for (j = 0; j < 3; j++)
411 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
413 /* Aliases for keys that can't be mapped to one-char-symbol
415 /* buf is already set to "C-?-". */
416 for (i = ' '; i <= '~'; i++)
430 alias[0] = alias[2] = msymbol (buf);
432 alias[1] = msymbol (buf);
433 for (j = 0; j < 2; j++)
434 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
437 Minput_method = msymbol ("input-method");
438 Mtitle = msymbol ("title");
439 Mmacro = msymbol ("macro");
440 Mmodule = msymbol ("module");
441 Mmap = msymbol ("map");
442 Mstate = msymbol ("state");
443 Minclude = msymbol ("include");
444 Minsert = msymbol ("insert");
445 M_candidates = msymbol (" candidates");
446 Mdelete = msymbol ("delete");
447 Mmove = msymbol ("move");
448 Mmark = msymbol ("mark");
449 Mpushback = msymbol ("pushback");
450 Mpop = msymbol ("pop");
451 Mundo = msymbol ("undo");
452 Mcall = msymbol ("call");
453 Mshift = msymbol ("shift");
454 Mselect = msymbol ("select");
455 Mshow = msymbol ("show");
456 Mhide = msymbol ("hide");
457 Mcommit = msymbol ("commit");
458 Munhandle = msymbol ("unhandle");
459 Mset = msymbol ("set");
460 Madd = msymbol ("add");
461 Msub = msymbol ("sub");
462 Mmul = msymbol ("mul");
463 Mdiv = msymbol ("div");
464 Mequal = msymbol ("=");
465 Mless = msymbol ("<");
466 Mgreater = msymbol (">");
467 Mless_equal = msymbol ("<=");
468 Mgreater_equal = msymbol (">=");
469 Mcond = msymbol ("cond");
470 Mplus = msymbol ("+");
471 Mminus = msymbol ("-");
472 Mstar = msymbol ("*");
473 Mslash = msymbol ("/");
474 Mand = msymbol ("&");
476 Mnot = msymbol ("!");
478 Mat_reload = msymbol ("-reload");
480 Mcandidates_group_size = msymbol ("candidates-group-size");
481 Mcandidates_charset = msymbol ("candidates-charset");
483 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
484 Mcandidate_index = msymbol (" candidate-index");
486 Minit = msymbol ("init");
487 Mfini = msymbol ("fini");
489 Mdescription = msymbol ("description");
490 Mcommand = msymbol ("command");
491 Mvariable = msymbol ("variable");
492 Mglobal = msymbol ("global");
493 Mconfig = msymbol ("config");
494 M_gettext = msymbol ("_");
496 load_im_info_keys = mplist ();
497 mplist_add (load_im_info_keys, Mstate, Mnil);
498 mplist_push (load_im_info_keys, Mmap, Mnil);
500 im_info_list = mplist ();
501 im_config_list = im_custom_list = NULL;
502 im_custom_mdb = NULL;
503 update_custom_info ();
505 update_global_info ();
507 fully_initialized = 1;
510 #define MINPUT__INIT() \
512 if (! fully_initialized) \
513 fully_initialize (); \
518 marker_code (MSymbol sym, int surrounding)
524 name = MSYMBOL_NAME (sym);
525 return (name[0] != '@' ? -1
526 : (((name[1] >= '0' && name[1] <= '9')
527 || name[1] == '<' || name[1] == '>' || name[1] == '='
528 || name[1] == '[' || name[1] == ']'
530 && name[2] == '\0') ? name[1]
531 : (name[1] != '+' && name[1] != '-') ? -1
532 : (name[2] == '\0' || surrounding) ? name[1]
537 /* Return a plist containing an integer value of VAR. */
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)
666 name = MSYMBOL_NAME (sym);
668 && (name[1] == '-' || name[1] == '+')
669 && name[2] >= '1' && name[2] <= '9')
670 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
675 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
677 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
679 MText *preedit = ic->preedit;
680 int len = mtext_nchars (preedit);
682 if (MPLIST_INTEGER_P (arg))
683 return MPLIST_INTEGER (arg);
685 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
688 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
690 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
693 return ic_info->key_head;
694 if ((code == '-' || code == '+'))
696 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
700 pos = atoi (name + 1);
702 return get_preceding_char (ic, 0);
704 pos = ic->cursor_pos + pos;
706 pos = ic->cursor_pos + pos - 1;
709 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
710 return mtext_ref_char (ic->produced,
711 mtext_len (ic->produced) + pos);
712 return get_preceding_char (ic, - pos);
715 return get_following_char (ic, pos - len);
718 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
720 else if (code >= '0' && code <= '9')
722 else if (code == '=')
723 pos = ic->cursor_pos;
724 else if (code == '[')
725 pos = ic->cursor_pos - 1;
726 else if (code == ']')
727 pos = ic->cursor_pos + 1;
728 else if (code == '<')
730 else if (code == '>')
732 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
736 parse_expression (MPlist *plist)
740 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
742 if (! MPLIST_PLIST_P (plist))
744 plist = MPLIST_PLIST (plist);
745 op = MPLIST_SYMBOL (plist);
746 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
747 && op != Mand && op != Mor && op != Mnot
748 && op != Mless && op != Mgreater && op != Mequal
749 && op != Mless_equal && op != Mgreater_equal)
750 MERROR (MERROR_IM, -1);
751 MPLIST_DO (plist, MPLIST_NEXT (plist))
752 if (parse_expression (plist) < 0)
758 resolve_expression (MInputContext *ic, MPlist *plist)
763 if (MPLIST_INTEGER_P (plist))
764 return MPLIST_INTEGER (plist);
765 if (MPLIST_SYMBOL_P (plist))
766 return integer_value (ic, plist, 1);
767 if (! MPLIST_PLIST_P (plist))
769 plist = MPLIST_PLIST (plist);
770 if (! MPLIST_SYMBOL_P (plist))
772 op = MPLIST_SYMBOL (plist);
773 plist = MPLIST_NEXT (plist);
774 val = resolve_expression (ic, plist);
776 MPLIST_DO (plist, MPLIST_NEXT (plist))
777 val += resolve_expression (ic, plist);
778 else if (op == Mminus)
779 MPLIST_DO (plist, MPLIST_NEXT (plist))
780 val -= resolve_expression (ic, plist);
781 else if (op == Mstar)
782 MPLIST_DO (plist, MPLIST_NEXT (plist))
783 val *= resolve_expression (ic, plist);
784 else if (op == Mslash)
785 MPLIST_DO (plist, MPLIST_NEXT (plist))
786 val /= resolve_expression (ic, plist);
788 MPLIST_DO (plist, MPLIST_NEXT (plist))
789 val &= resolve_expression (ic, plist);
791 MPLIST_DO (plist, MPLIST_NEXT (plist))
792 val |= resolve_expression (ic, plist);
795 else if (op == Mless)
796 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
797 else if (op == Mequal)
798 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
799 else if (op == Mgreater)
800 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
801 else if (op == Mless_equal)
802 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
803 else if (op == Mgreater_equal)
804 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
808 /* Parse PLIST as an action list. PLIST should have this form:
809 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
810 Return 0 if successfully parsed, otherwise return -1. */
813 parse_action_list (MPlist *plist, MPlist *macros)
815 MPLIST_DO (plist, plist)
817 if (MPLIST_MTEXT_P (plist))
819 /* This is a short form of (insert MTEXT). */
820 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
821 MERROR (MERROR_IM, -1); */
823 else if (MPLIST_PLIST_P (plist)
824 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
825 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
829 /* This is a short form of (insert (GROUPS *)). */
830 MPLIST_DO (pl, MPLIST_PLIST (plist))
832 if (MPLIST_PLIST_P (pl))
836 MPLIST_DO (elt, MPLIST_PLIST (pl))
837 if (! MPLIST_MTEXT_P (elt)
838 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
839 MERROR (MERROR_IM, -1);
843 if (! MPLIST_MTEXT_P (pl)
844 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
845 MERROR (MERROR_IM, -1);
849 else if (MPLIST_INTEGER_P (plist))
851 int c = MPLIST_INTEGER (plist);
853 if (c < 0 || c > MCHAR_MAX)
854 MERROR (MERROR_IM, -1);
856 else if (MPLIST_PLIST_P (plist)
857 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
859 MPlist *pl = MPLIST_PLIST (plist);
860 MSymbol action_name = MPLIST_SYMBOL (pl);
862 pl = MPLIST_NEXT (pl);
864 if (action_name == M_candidates)
866 /* This is an already regularised action. */
869 if (action_name == Minsert)
871 if (MPLIST_MTEXT_P (pl))
873 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
874 MERROR (MERROR_IM, -1);
876 else if (MPLIST_INTEGER_P (pl))
878 int c = MPLIST_INTEGER (pl);
880 if (c < 0 || c > MCHAR_MAX)
881 MERROR (MERROR_IM, -1);
883 else if (MPLIST_PLIST_P (pl))
885 MPLIST_DO (pl, MPLIST_PLIST (pl))
887 if (MPLIST_PLIST_P (pl))
891 MPLIST_DO (elt, MPLIST_PLIST (pl))
892 if (! MPLIST_MTEXT_P (elt)
893 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
894 MERROR (MERROR_IM, -1);
898 if (! MPLIST_MTEXT_P (pl)
899 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
900 MERROR (MERROR_IM, -1);
904 else if (! MPLIST_SYMBOL_P (pl))
905 MERROR (MERROR_IM, -1);
907 else if (action_name == Mselect
908 || action_name == Mdelete
909 || action_name == Mmove)
911 if (parse_expression (pl) < 0)
914 else if (action_name == Mmark
915 || action_name == Mcall
916 || action_name == Mshift)
918 if (! MPLIST_SYMBOL_P (pl))
919 MERROR (MERROR_IM, -1);
921 else if (action_name == Mundo)
923 if (! MPLIST_TAIL_P (pl))
925 if (! MPLIST_SYMBOL_P (pl)
926 && ! MPLIST_INTEGER_P (pl))
927 MERROR (MERROR_IM, -1);
930 else if (action_name == Mpushback)
932 if (MPLIST_MTEXT_P (pl))
934 MText *mt = MPLIST_MTEXT (pl);
936 if (mtext_nchars (mt) != mtext_nbytes (mt))
937 MERROR (MERROR_IM, -1);
939 else if (MPLIST_PLIST_P (pl))
943 MPLIST_DO (p, MPLIST_PLIST (pl))
944 if (! MPLIST_SYMBOL_P (p))
945 MERROR (MERROR_IM, -1);
947 else if (! MPLIST_INTEGER_P (pl))
948 MERROR (MERROR_IM, -1);
950 else if (action_name == Mset || action_name == Madd
951 || action_name == Msub || action_name == Mmul
952 || action_name == Mdiv)
954 if (! MPLIST_SYMBOL_P (pl))
955 MERROR (MERROR_IM, -1);
956 if (parse_expression (MPLIST_NEXT (pl)) < 0)
959 else if (action_name == Mequal || action_name == Mless
960 || action_name == Mgreater || action_name == Mless_equal
961 || action_name == Mgreater_equal)
963 if (parse_expression (pl) < 0
964 || parse_expression (MPLIST_NEXT (pl)) < 0)
966 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
967 if (! MPLIST_PLIST_P (pl))
968 MERROR (MERROR_IM, -1);
969 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
970 MERROR (MERROR_IM, -1);
971 pl = MPLIST_NEXT (pl);
972 if (MPLIST_PLIST_P (pl)
973 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
974 MERROR (MERROR_IM, -1);
976 else if (action_name == Mshow || action_name == Mhide
977 || action_name == Mcommit || action_name == Munhandle
978 || action_name == Mpop)
980 else if (action_name == Mcond)
983 if (! MPLIST_PLIST_P (pl))
984 MERROR (MERROR_IM, -1);
986 else if (! macros || ! mplist_get (macros, action_name))
987 MERROR (MERROR_IM, -1);
989 else if (! MPLIST_SYMBOL_P (plist))
990 MERROR (MERROR_IM, -1);
997 resolve_command (MPlist *cmds, MSymbol command)
1001 if (! cmds || ! (plist = mplist__assq (cmds, command)))
1003 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
1004 plist = MPLIST_NEXT (plist);
1005 plist = MPLIST_NEXT (plist);
1006 plist = MPLIST_NEXT (plist);
1010 /* Load a translation into MAP from PLIST.
1011 PLIST has this form:
1012 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
1015 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
1016 MPlist *branch_actions, MPlist *macros)
1021 if (MPLIST_MTEXT_P (keylist))
1023 MText *mt = MPLIST_MTEXT (keylist);
1025 len = mtext_nchars (mt);
1026 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
1028 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1029 for (i = 0; i < len; i++)
1030 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1036 if (MFAILP (MPLIST_PLIST_P (keylist)))
1038 elt = MPLIST_PLIST (keylist);
1039 len = MPLIST_LENGTH (elt);
1040 if (MFAILP (len > 0))
1042 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1043 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1045 if (MPLIST_INTEGER_P (elt))
1047 int c = MPLIST_INTEGER (elt);
1049 if (MFAILP (c >= 0 && c < 0x100))
1051 keyseq[i] = one_char_symbol[c];
1055 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1057 keyseq[i] = MPLIST_SYMBOL (elt);
1062 for (i = 0; i < len; i++)
1064 MIMMap *deeper = NULL;
1067 deeper = mplist_get (map->submaps, keyseq[i]);
1069 map->submaps = mplist ();
1072 /* Fixme: It is better to make all deeper maps at once. */
1073 MSTRUCT_CALLOC (deeper, MERROR_IM);
1074 mplist_put (map->submaps, keyseq[i], deeper);
1079 /* We reach a terminal map. */
1080 if (map->map_actions
1081 || map->branch_actions)
1082 /* This map is already defined. We avoid overriding it. */
1085 if (! MPLIST_TAIL_P (map_actions))
1087 if (parse_action_list (map_actions, macros) < 0)
1088 MERROR (MERROR_IM, -1);
1089 map->map_actions = map_actions;
1093 map->branch_actions = branch_actions;
1094 M17N_OBJECT_REF (branch_actions);
1100 /* Load a branch from PLIST into MAP. PLIST has this form:
1101 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1104 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1107 MPlist *branch_actions;
1109 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1111 map_name = MPLIST_SYMBOL (plist);
1112 plist = MPLIST_NEXT (plist);
1113 if (MPLIST_TAIL_P (plist))
1114 branch_actions = NULL;
1115 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1118 branch_actions = plist;
1119 if (map_name == Mnil)
1121 map->branch_actions = branch_actions;
1123 M17N_OBJECT_REF (branch_actions);
1125 else if (map_name == Mt)
1127 map->map_actions = branch_actions;
1129 M17N_OBJECT_REF (branch_actions);
1131 else if (im_info->maps)
1133 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1134 if (! plist && im_info->configured_vars)
1136 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1138 if (p && MPLIST_PLIST_P (p))
1140 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1141 if (MPLIST_SYMBOL_P (p))
1142 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1147 MPLIST_DO (plist, plist)
1149 MPlist *keylist, *map_actions;
1151 if (! MPLIST_PLIST_P (plist))
1152 MERROR (MERROR_IM, -1);
1153 keylist = MPLIST_PLIST (plist);
1154 map_actions = MPLIST_NEXT (keylist);
1155 if (MPLIST_SYMBOL_P (keylist))
1157 MSymbol command = MPLIST_SYMBOL (keylist);
1160 if (MFAILP (command != Mat_reload))
1162 pl = resolve_command (im_info->configured_cmds, command);
1166 load_translation (map, pl, map_actions, branch_actions,
1170 load_translation (map, keylist, map_actions, branch_actions,
1179 /* Load a macro from PLIST into IM_INFO->macros.
1180 PLIST has this from:
1181 PLIST ::= ( MACRO-NAME ACTION * )
1182 IM_INFO->macros is a plist of macro names vs action list. */
1185 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1190 if (! MPLIST_SYMBOL_P (plist))
1191 MERROR (MERROR_IM, -1);
1192 name = MPLIST_SYMBOL (plist);
1193 plist = MPLIST_NEXT (plist);
1194 if (MPLIST_TAIL_P (plist)
1195 || parse_action_list (plist, im_info->macros) < 0)
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 into IM_INFO->externals.
1205 PLIST has this form:
1206 PLIST ::= ( MODULE-NAME FUNCTION * )
1207 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1210 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1215 MIMExternalModule *external;
1219 if (MPLIST_MTEXT_P (plist))
1220 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1221 else if (MPLIST_SYMBOL_P (plist))
1222 module = MPLIST_SYMBOL (plist);
1223 module_file = alloca (strlen (MSYMBOL_NAME (module))
1224 + strlen (DLOPEN_SHLIB_EXT) + 1);
1225 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1227 handle = dlopen (module_file, RTLD_NOW);
1228 if (MFAILP (handle))
1230 fprintf (stderr, "%s\n", dlerror ());
1233 func_list = mplist ();
1234 MPLIST_DO (plist, MPLIST_NEXT (plist))
1236 if (! MPLIST_SYMBOL_P (plist))
1237 MERROR_GOTO (MERROR_IM, err_label);
1238 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1241 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1244 MSTRUCT_MALLOC (external, MERROR_IM);
1245 external->handle = handle;
1246 external->func_list = func_list;
1247 mplist_add (im_info->externals, module, external);
1252 M17N_OBJECT_UNREF (func_list);
1257 free_map (MIMMap *map, int top)
1262 M17N_OBJECT_UNREF (map->map_actions);
1265 MPLIST_DO (plist, map->submaps)
1266 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1267 M17N_OBJECT_UNREF (map->submaps);
1269 M17N_OBJECT_UNREF (map->branch_actions);
1274 free_state (void *object)
1276 MIMState *state = object;
1278 M17N_OBJECT_UNREF (state->title);
1280 free_map (state->map, 1);
1284 /** Load a state from PLIST into a newly allocated state object.
1285 PLIST has this form:
1286 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1287 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1288 Return the state object. */
1291 load_state (MInputMethodInfo *im_info, MPlist *plist)
1295 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1297 M17N_OBJECT (state, free_state, MERROR_IM);
1298 state->name = MPLIST_SYMBOL (plist);
1299 plist = MPLIST_NEXT (plist);
1300 if (MPLIST_MTEXT_P (plist))
1302 state->title = MPLIST_MTEXT (plist);
1303 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1304 Mlanguage, im_info->language);
1305 M17N_OBJECT_REF (state->title);
1306 plist = MPLIST_NEXT (plist);
1308 MSTRUCT_CALLOC (state->map, MERROR_IM);
1309 MPLIST_DO (plist, plist)
1311 if (MFAILP (MPLIST_PLIST_P (plist)))
1313 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1318 /* Return a newly created IM_INFO for an input method specified by
1319 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1321 static MInputMethodInfo *
1322 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1325 MInputMethodInfo *im_info;
1328 if (name == Mnil && extra == Mnil)
1329 language = Mt, extra = Mglobal;
1330 MSTRUCT_CALLOC (im_info, MERROR_IM);
1332 im_info->language = language;
1333 im_info->name = name;
1334 im_info->extra = extra;
1337 mplist_add (plist, Mplist, elt);
1338 M17N_OBJECT_UNREF (elt);
1339 elt = mplist_add (elt, Msymbol, language);
1340 elt = mplist_add (elt, Msymbol, name);
1341 elt = mplist_add (elt, Msymbol, extra);
1342 mplist_add (elt, Mt, im_info);
1348 fini_im_info (MInputMethodInfo *im_info)
1352 M17N_OBJECT_UNREF (im_info->cmds);
1353 M17N_OBJECT_UNREF (im_info->configured_cmds);
1354 M17N_OBJECT_UNREF (im_info->bc_cmds);
1355 M17N_OBJECT_UNREF (im_info->vars);
1356 M17N_OBJECT_UNREF (im_info->configured_vars);
1357 M17N_OBJECT_UNREF (im_info->bc_vars);
1358 M17N_OBJECT_UNREF (im_info->description);
1359 M17N_OBJECT_UNREF (im_info->title);
1360 if (im_info->states)
1362 MPLIST_DO (plist, im_info->states)
1364 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1366 M17N_OBJECT_UNREF (state);
1368 M17N_OBJECT_UNREF (im_info->states);
1371 if (im_info->macros)
1373 MPLIST_DO (plist, im_info->macros)
1374 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1375 M17N_OBJECT_UNREF (im_info->macros);
1378 if (im_info->externals)
1380 MPLIST_DO (plist, im_info->externals)
1382 MIMExternalModule *external = MPLIST_VAL (plist);
1384 dlclose (external->handle);
1385 M17N_OBJECT_UNREF (external->func_list);
1387 MPLIST_KEY (plist) = Mt;
1389 M17N_OBJECT_UNREF (im_info->externals);
1393 MPLIST_DO (plist, im_info->maps)
1395 MPlist *p = MPLIST_PLIST (plist);
1397 M17N_OBJECT_UNREF (p);
1399 M17N_OBJECT_UNREF (im_info->maps);
1406 free_im_info (MInputMethodInfo *im_info)
1408 fini_im_info (im_info);
1413 free_im_list (MPlist *plist)
1417 MPLIST_DO (pl, plist)
1419 MInputMethodInfo *im_info;
1421 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1422 im_info = MPLIST_VAL (elt);
1423 free_im_info (im_info);
1425 M17N_OBJECT_UNREF (plist);
1428 static MInputMethodInfo *
1429 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1431 if (name == Mnil && extra == Mnil)
1432 language = Mt, extra = Mglobal;
1433 while ((plist = mplist__assq (plist, language)))
1435 MPlist *elt = MPLIST_PLIST (plist);
1437 plist = MPLIST_NEXT (plist);
1438 elt = MPLIST_NEXT (elt);
1439 if (MPLIST_SYMBOL (elt) != name)
1441 elt = MPLIST_NEXT (elt);
1442 if (MPLIST_SYMBOL (elt) != extra)
1444 elt = MPLIST_NEXT (elt);
1445 return MPLIST_VAL (elt);
1450 static void load_im_info (MPlist *, MInputMethodInfo *);
1452 #define get_custom_info(im_info) \
1454 ? lookup_im_info (im_custom_list, (im_info)->language, \
1455 (im_info)->name, (im_info)->extra) \
1458 #define get_config_info(im_info) \
1460 ? lookup_im_info (im_config_list, (im_info)->language, \
1461 (im_info)->name, (im_info)->extra) \
1465 update_custom_info (void)
1471 if (mdatabase__check (im_custom_mdb) > 0)
1476 MDatabaseInfo *custom_dir_info;
1477 char custom_path[PATH_MAX + 1];
1479 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1480 if (! custom_dir_info->filename
1481 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1483 strcpy (custom_path, custom_dir_info->filename);
1484 strcat (custom_path, CUSTOM_FILE);
1485 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1491 free_im_list (im_custom_list);
1492 im_custom_list = NULL;
1494 plist = mdatabase_load (im_custom_mdb);
1497 im_custom_list = mplist ();
1499 MPLIST_DO (pl, plist)
1501 MSymbol language, name, extra;
1502 MInputMethodInfo *im_info;
1503 MPlist *im_data, *p;
1505 if (! MPLIST_PLIST_P (pl))
1507 p = MPLIST_PLIST (pl);
1508 im_data = MPLIST_NEXT (p);
1509 if (! MPLIST_PLIST_P (p))
1511 p = MPLIST_PLIST (p);
1512 if (! MPLIST_SYMBOL_P (p)
1513 || MPLIST_SYMBOL (p) != Minput_method)
1515 p = MPLIST_NEXT (p);
1516 if (! MPLIST_SYMBOL_P (p))
1518 language = MPLIST_SYMBOL (p);
1519 p = MPLIST_NEXT (p);
1520 if (! MPLIST_SYMBOL_P (p))
1522 name = MPLIST_SYMBOL (p);
1523 p = MPLIST_NEXT (p);
1524 if (MPLIST_TAIL_P (p))
1526 else if (MPLIST_SYMBOL_P (p))
1527 extra = MPLIST_SYMBOL (p);
1528 if (language == Mnil || (name == Mnil && extra == Mnil))
1530 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1531 load_im_info (im_data, im_info);
1533 M17N_OBJECT_UNREF (plist);
1538 update_global_info (void)
1544 int ret = mdatabase__check (global_info->mdb);
1548 fini_im_info (global_info);
1552 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1556 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1558 if (! global_info->mdb
1559 || ! (plist = mdatabase_load (global_info->mdb)))
1562 load_im_info (plist, global_info);
1563 M17N_OBJECT_UNREF (plist);
1568 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1569 and EXTRA. KEY, if not Mnil, tells which kind of information about
1570 the input method is necessary, and the returned IM_INFO may contain
1571 only that information. */
1573 static MInputMethodInfo *
1574 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1577 MInputMethodInfo *im_info;
1580 if (name == Mnil && extra == Mnil)
1581 language = Mt, extra = Mglobal;
1582 im_info = lookup_im_info (im_info_list, language, name, extra);
1585 if (key == Mnil ? im_info->states != NULL
1586 : key == Mcommand ? im_info->cmds != NULL
1587 : key == Mvariable ? im_info->vars != NULL
1588 : key == Mtitle ? im_info->title != NULL
1589 : key == Mdescription ? im_info->description != NULL
1591 /* IM_INFO already contains required information. */
1593 /* We have not yet loaded required information. */
1597 mdb = mdatabase_find (Minput_method, language, name, extra);
1600 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1605 plist = mdatabase_load (im_info->mdb);
1609 mplist_push (load_im_info_keys, key, Mt);
1610 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1611 mplist_pop (load_im_info_keys);
1615 MERROR (MERROR_IM, im_info);
1616 update_global_info ();
1617 load_im_info (plist, im_info);
1618 M17N_OBJECT_UNREF (plist);
1621 if (! im_info->cmds)
1622 im_info->cmds = mplist ();
1623 if (! im_info->vars)
1624 im_info->vars = mplist ();
1625 if (! im_info->states)
1626 im_info->states = mplist ();
1628 if (! im_info->title
1629 && (key == Mnil || key == Mtitle))
1630 im_info->title = (name == Mnil ? mtext ()
1631 : mtext_from_data (MSYMBOL_NAME (name),
1632 MSYMBOL_NAMELEN (name),
1633 MTEXT_FORMAT_US_ASCII));
1637 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1638 If updated, but got unloadable, return -1. Otherwise, update
1639 contents of IM_INFO from the new database, and return 1. */
1642 reload_im_info (MInputMethodInfo *im_info)
1647 update_custom_info ();
1648 update_global_info ();
1649 check = mdatabase__check (im_info->mdb);
1652 plist = mdatabase_load (im_info->mdb);
1655 fini_im_info (im_info);
1656 load_im_info (plist, im_info);
1657 M17N_OBJECT_UNREF (plist);
1658 if (! im_info->cmds)
1659 im_info->cmds = mplist ();
1660 if (! im_info->vars)
1661 im_info->vars = mplist ();
1662 if (! im_info->title)
1664 MSymbol name = im_info->name;
1666 im_info->title = (name == Mnil ? mtext ()
1667 : mtext_from_data (MSYMBOL_NAME (name),
1668 MSYMBOL_NAMELEN (name),
1669 MTEXT_FORMAT_US_ASCII));
1674 static MInputMethodInfo *
1675 get_im_info_by_tags (MPlist *plist)
1680 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1681 i++, plist = MPLIST_NEXT (plist))
1682 tag[i] = MPLIST_SYMBOL (plist);
1687 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1692 check_description (MPlist *plist)
1696 if (MPLIST_MTEXT_P (plist))
1698 if (MPLIST_PLIST_P (plist))
1700 MPlist *pl = MPLIST_PLIST (plist);
1702 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1704 pl =MPLIST_NEXT (pl);
1705 if (MFAILP (MPLIST_MTEXT_P (pl)))
1707 mt = MPLIST_MTEXT (pl);
1708 M17N_OBJECT_REF (mt);
1711 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1713 if (translated == (char *) MTEXT_DATA (mt))
1714 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1715 if (translated != (char *) MTEXT_DATA (mt))
1717 M17N_OBJECT_UNREF (mt);
1718 mt = mtext__from_data (translated, strlen (translated),
1719 MTEXT_FORMAT_UTF_8, 1);
1723 mplist_set (plist, Mtext, mt);
1724 M17N_OBJECT_UNREF (mt);
1727 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1733 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1737 check_command_keyseq (MPlist *keyseq)
1739 if (MPLIST_PLIST_P (keyseq))
1741 MPlist *p = MPLIST_PLIST (keyseq);
1744 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1748 if (MPLIST_MTEXT_P (keyseq))
1750 MText *mt = MPLIST_MTEXT (keyseq);
1753 for (i = 0; i < mtext_nchars (mt); i++)
1754 if (mtext_ref_char (mt, i) >= 256)
1761 /* Load command defitions from PLIST into IM_INFO->cmds.
1763 PLIST is well-formed and has this form;
1764 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1765 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1766 M-text or a plist of symbols.
1768 The returned list has the same form, but for each element...
1770 (1) If DESCRIPTION and the rest are omitted, the element is not
1771 stored in the returned list.
1773 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1774 description in global_info->cmds (if any). */
1777 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1781 im_info->cmds = tail = mplist ();
1783 MPLIST_DO (plist, MPLIST_NEXT (plist))
1785 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1788 if (MFAILP (MPLIST_PLIST_P (plist)))
1790 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1791 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1793 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1794 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1796 if (MFAILP (im_info != global_info))
1797 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1801 if (! check_description (p))
1802 mplist_set (p, Msymbol, Mnil);
1803 p = MPLIST_NEXT (p);
1804 while (! MPLIST_TAIL_P (p))
1806 if (MFAILP (check_command_keyseq (p)))
1807 mplist__pop_unref (p);
1809 p = MPLIST_NEXT (p);
1812 tail = mplist_add (tail, Mplist, pl);
1817 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1818 MPlist *config_cmds)
1820 MPlist *global = NULL, *custom = NULL, *config = NULL;
1821 MSymbol name = MPLIST_SYMBOL (plist);
1823 MPlist *description, *keyseq;
1825 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1826 global = MPLIST_NEXT (MPLIST_PLIST (global));
1828 plist = MPLIST_NEXT (plist);
1829 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1831 description = plist;
1832 plist = MPLIST_NEXT (plist);
1836 description = global;
1837 if (! MPLIST_TAIL_P (plist))
1838 plist = MPLIST_NEXT (plist);
1840 if (MPLIST_TAIL_P (plist) && global)
1842 keyseq = MPLIST_NEXT (global);
1843 status = Minherited;
1851 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1853 status = Mconfigured;
1854 config = MPLIST_NEXT (MPLIST_PLIST (config));
1855 if (! MPLIST_TAIL_P (config))
1858 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1860 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1862 if (MPLIST_TAIL_P (this_keyseq))
1863 mplist__pop_unref (custom);
1866 status = Mcustomized;
1867 keyseq = this_keyseq;
1872 mplist_add (plist, Msymbol, name);
1874 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1876 mplist_add (plist, Msymbol, Mnil);
1877 mplist_add (plist, Msymbol, status);
1878 mplist__conc (plist, keyseq);
1883 config_all_commands (MInputMethodInfo *im_info)
1885 MPlist *global_cmds, *custom_cmds, *config_cmds;
1886 MInputMethodInfo *temp;
1887 MPlist *tail, *plist;
1889 M17N_OBJECT_UNREF (im_info->configured_cmds);
1891 if (MPLIST_TAIL_P (im_info->cmds)
1895 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1896 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1897 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1899 im_info->configured_cmds = tail = mplist ();
1900 MPLIST_DO (plist, im_info->cmds)
1902 MPlist *pl = config_command (MPLIST_PLIST (plist),
1903 global_cmds, custom_cmds, config_cmds);
1906 tail = mplist_add (tail, Mplist, pl);
1907 M17N_OBJECT_UNREF (pl);
1912 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1913 valid, return 0 if not. */
1916 check_variable_value (MPlist *val, MPlist *global)
1918 MSymbol type = MPLIST_KEY (val);
1919 MPlist *valids = MPLIST_NEXT (val);
1921 if (type != Minteger && type != Mtext && type != Msymbol)
1925 if (MPLIST_KEY (global) != Mt
1926 && MPLIST_KEY (global) != MPLIST_KEY (val))
1928 if (MPLIST_TAIL_P (valids))
1929 valids = MPLIST_NEXT (global);
1931 if (MPLIST_TAIL_P (valids))
1934 if (type == Minteger)
1936 int n = MPLIST_INTEGER (val);
1938 MPLIST_DO (valids, valids)
1940 if (MPLIST_INTEGER_P (valids))
1942 if (n == MPLIST_INTEGER (valids))
1945 else if (MPLIST_PLIST_P (valids))
1947 MPlist *p = MPLIST_PLIST (valids);
1948 int min_bound, max_bound;
1950 if (! MPLIST_INTEGER_P (p))
1951 MERROR (MERROR_IM, 0);
1952 min_bound = MPLIST_INTEGER (p);
1953 p = MPLIST_NEXT (p);
1954 if (! MPLIST_INTEGER_P (p))
1955 MERROR (MERROR_IM, 0);
1956 max_bound = MPLIST_INTEGER (p);
1957 if (n >= min_bound && n <= max_bound)
1962 else if (type == Msymbol)
1964 MSymbol sym = MPLIST_SYMBOL (val);
1966 MPLIST_DO (valids, valids)
1968 if (! MPLIST_SYMBOL_P (valids))
1969 MERROR (MERROR_IM, 0);
1970 if (sym == MPLIST_SYMBOL (valids))
1976 MText *mt = MPLIST_MTEXT (val);
1978 MPLIST_DO (valids, valids)
1980 if (! MPLIST_MTEXT_P (valids))
1981 MERROR (MERROR_IM, 0);
1982 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1987 return (! MPLIST_TAIL_P (valids));
1990 /* Load variable defitions from PLIST into IM_INFO->vars.
1992 PLIST is well-formed and has this form;
1993 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1995 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1997 The returned list has the same form, but for each element...
1999 (1) If DESCRIPTION and the rest are omitted, the element is not
2000 stored in the returned list.
2002 (2) If DESCRIPTION is nil, it is complemented by the corresponding
2003 description in global_info->vars (if any). */
2006 load_variables (MInputMethodInfo *im_info, MPlist *plist)
2008 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
2009 ? global_info->vars : NULL);
2012 im_info->vars = tail = mplist ();
2013 MPLIST_DO (plist, MPLIST_NEXT (plist))
2017 if (MFAILP (MPLIST_PLIST_P (plist)))
2019 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
2020 if (MFAILP (MPLIST_SYMBOL_P (pl)))
2022 if (im_info == global_info)
2024 /* Loading a global variable. */
2025 p = MPLIST_NEXT (pl);
2026 if (MPLIST_TAIL_P (p))
2027 mplist_add (p, Msymbol, Mnil);
2030 if (! check_description (p))
2031 mplist_set (p, Msymbol, Mnil);
2032 p = MPLIST_NEXT (p);
2033 if (MFAILP (! MPLIST_TAIL_P (p)
2034 && check_variable_value (p, NULL)))
2035 mplist_set (p, Mt, NULL);
2038 else if (im_info->mdb)
2040 /* Loading a local variable. */
2041 MSymbol name = MPLIST_SYMBOL (pl);
2042 MPlist *global = NULL;
2045 && (p = mplist__assq (global_vars, name)))
2047 /* P ::= ((NAME DESC ...) ...) */
2048 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2049 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2050 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2053 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2054 if (! MPLIST_TAIL_P (p))
2056 if (! check_description (p))
2057 mplist_set (p, Msymbol, Mnil);
2058 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2059 if (MFAILP (! MPLIST_TAIL_P (p)))
2060 mplist_set (p, Mt, NULL);
2063 MPlist *valid_values = MPLIST_NEXT (p);
2065 if (! MPLIST_TAIL_P (valid_values)
2066 ? MFAILP (check_variable_value (p, NULL))
2067 : global && MFAILP (check_variable_value (p, global)))
2068 mplist_set (p, Mt, NULL);
2074 /* Loading a variable customization. */
2075 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2076 if (MFAILP (! MPLIST_TAIL_P (p)))
2078 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2079 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2080 || MPLIST_MTEXT_P (p)))
2083 tail = mplist_add (tail, Mplist, pl);
2088 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2089 MPlist *config_vars)
2091 MPlist *global = NULL, *custom = NULL, *config = NULL;
2092 MSymbol name = MPLIST_SYMBOL (plist);
2094 MPlist *description = NULL, *value, *valids;
2098 global = mplist__assq (global_vars, name);
2100 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2103 plist = MPLIST_NEXT (plist);
2104 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2105 description = plist;
2107 description = global;
2109 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2111 if (MPLIST_TAIL_P (plist))
2113 /* Inherit from global (if any). */
2117 if (MPLIST_KEY (value) == Mt)
2119 valids = MPLIST_NEXT (global);
2120 status = Minherited;
2132 value = plist = MPLIST_NEXT (plist);
2133 valids = MPLIST_NEXT (value);
2134 if (MPLIST_KEY (value) == Mt)
2136 if (! MPLIST_TAIL_P (valids))
2139 valids = MPLIST_NEXT (global);
2143 if (config_vars && (config = mplist__assq (config_vars, name)))
2145 status = Mconfigured;
2146 config = MPLIST_NEXT (MPLIST_PLIST (config));
2147 if (! MPLIST_TAIL_P (config))
2150 if (MFAILP (check_variable_value (value, global ? global : plist)))
2154 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2156 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2158 if (MPLIST_TAIL_P (this_value))
2159 mplist__pop_unref (custom);
2163 if (MFAILP (check_variable_value (value, global ? global : plist)))
2165 status = Mcustomized;
2170 mplist_add (plist, Msymbol, name);
2172 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2174 mplist_add (plist, Msymbol, Mnil);
2175 mplist_add (plist, Msymbol, status);
2177 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2179 mplist_add (plist, Mt, NULL);
2180 if (valids && ! MPLIST_TAIL_P (valids))
2181 mplist__conc (plist, valids);
2185 /* Return a configured variable definition list based on
2186 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2187 get it from global_info->vars. */
2190 config_all_variables (MInputMethodInfo *im_info)
2192 MPlist *global_vars, *custom_vars, *config_vars;
2193 MInputMethodInfo *temp;
2194 MPlist *tail, *plist;
2196 M17N_OBJECT_UNREF (im_info->configured_vars);
2198 if (MPLIST_TAIL_P (im_info->vars)
2202 global_vars = im_info != global_info ? global_info->vars : NULL;
2203 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2204 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2206 im_info->configured_vars = tail = mplist ();
2207 MPLIST_DO (plist, im_info->vars)
2209 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2210 global_vars, custom_vars, config_vars);
2213 tail = mplist_add (tail, Mplist, pl);
2214 M17N_OBJECT_UNREF (pl);
2219 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2220 CONFIG contains configuration information of the input method. */
2223 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2227 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2229 load_commands (im_info, MPLIST_PLIST (pl));
2230 config_all_commands (im_info);
2231 pl = mplist_pop (pl);
2232 M17N_OBJECT_UNREF (pl);
2235 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2237 load_variables (im_info, MPLIST_PLIST (pl));
2238 config_all_variables (im_info);
2239 pl = mplist_pop (pl);
2240 M17N_OBJECT_UNREF (pl);
2243 MPLIST_DO (plist, plist)
2244 if (MPLIST_PLIST_P (plist))
2246 MPlist *elt = MPLIST_PLIST (plist);
2249 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2251 key = MPLIST_SYMBOL (elt);
2256 elt = MPLIST_NEXT (elt);
2257 if (MFAILP (MPLIST_MTEXT_P (elt)))
2259 im_info->title = MPLIST_MTEXT (elt);
2260 M17N_OBJECT_REF (im_info->title);
2262 else if (key == Mmap)
2264 pl = mplist__from_alist (MPLIST_NEXT (elt));
2267 if (! im_info->maps)
2271 mplist__conc (im_info->maps, pl);
2272 M17N_OBJECT_UNREF (pl);
2275 else if (key == Mmacro)
2277 if (! im_info->macros)
2278 im_info->macros = mplist ();
2279 MPLIST_DO (elt, MPLIST_NEXT (elt))
2281 if (MFAILP (MPLIST_PLIST_P (elt)))
2283 load_macros (im_info, MPLIST_PLIST (elt));
2286 else if (key == Mmodule)
2288 if (! im_info->externals)
2289 im_info->externals = mplist ();
2290 MPLIST_DO (elt, MPLIST_NEXT (elt))
2292 if (MFAILP (MPLIST_PLIST_P (elt)))
2294 load_external_module (im_info, MPLIST_PLIST (elt));
2297 else if (key == Mstate)
2299 MPLIST_DO (elt, MPLIST_NEXT (elt))
2303 if (MFAILP (MPLIST_PLIST_P (elt)))
2305 pl = MPLIST_PLIST (elt);
2306 if (! im_info->states)
2307 im_info->states = mplist ();
2308 state = load_state (im_info, MPLIST_PLIST (elt));
2311 mplist_put (im_info->states, state->name, state);
2314 else if (key == Minclude)
2316 /* elt ::= include (tag1 tag2 ...) key item ... */
2318 MInputMethodInfo *temp;
2320 elt = MPLIST_NEXT (elt);
2321 if (MFAILP (MPLIST_PLIST_P (elt)))
2323 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2326 elt = MPLIST_NEXT (elt);
2327 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2329 key = MPLIST_SYMBOL (elt);
2330 elt = MPLIST_NEXT (elt);
2333 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2335 if (! im_info->maps)
2336 im_info->maps = mplist ();
2337 MPLIST_DO (pl, temp->maps)
2339 p = MPLIST_VAL (pl);
2340 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2341 M17N_OBJECT_REF (p);
2344 else if (key == Mmacro)
2346 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2348 if (! im_info->macros)
2349 im_info->macros = mplist ();
2350 MPLIST_DO (pl, temp->macros)
2352 p = MPLIST_VAL (pl);
2353 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2354 M17N_OBJECT_REF (p);
2357 else if (key == Mstate)
2359 if (! temp->states || MPLIST_TAIL_P (temp->states))
2361 if (! im_info->states)
2362 im_info->states = mplist ();
2363 MPLIST_DO (pl, temp->states)
2365 MIMState *state = MPLIST_VAL (pl);
2367 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2368 M17N_OBJECT_REF (state);
2372 else if (key == Mdescription)
2374 if (im_info->description)
2376 elt = MPLIST_NEXT (elt);
2377 if (! check_description (elt))
2379 im_info->description = MPLIST_MTEXT (elt);
2380 M17N_OBJECT_REF (im_info->description);
2383 im_info->tick = time (NULL);
2388 static int take_action_list (MInputContext *ic, MPlist *action_list);
2389 static void preedit_commit (MInputContext *ic, int need_prefix);
2392 shift_state (MInputContext *ic, MSymbol state_name)
2394 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2395 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2396 MIMState *orig_state = ic_info->state, *state;
2398 /* Find a state to shift to. If not found, shift to the initial
2400 if (state_name == Mt)
2402 if (! ic_info->prev_state)
2404 state = ic_info->prev_state;
2406 else if (state_name == Mnil)
2408 state = (MIMState *) MPLIST_VAL (im_info->states);
2412 state = (MIMState *) mplist_get (im_info->states, state_name);
2414 state = (MIMState *) MPLIST_VAL (im_info->states);
2420 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2421 MSYMBOL_NAME (orig_state->name),
2422 MSYMBOL_NAME (state->name));
2424 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2427 /* Enter the new state. */
2428 ic_info->state = state;
2429 ic_info->map = state->map;
2430 ic_info->state_key_head = ic_info->key_head;
2431 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2433 /* We have shifted to the initial state. */
2434 preedit_commit (ic, 0);
2435 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2436 ic_info->state_pos = ic->cursor_pos;
2437 if (state != orig_state)
2439 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2441 /* Shifted to the initial state. */
2442 ic_info->prev_state = NULL;
2443 M17N_OBJECT_UNREF (ic_info->vars_saved);
2444 ic_info->vars_saved = mplist_copy (ic_info->vars);
2447 ic_info->prev_state = orig_state;
2450 ic->status = state->title;
2452 ic->status = im_info->title;
2453 ic->status_changed = 1;
2454 if (ic_info->map == ic_info->state->map
2455 && ic_info->map->map_actions)
2457 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2458 MSYMBOL_NAME (state->name));
2459 take_action_list (ic, ic_info->map->map_actions);
2464 /* Find a candidate group that contains a candidate number INDEX from
2465 PLIST. Set START_INDEX to the first candidate number of the group,
2466 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2467 candidate group number if they are non-NULL. If INDEX is -1, find
2468 the last candidate group. */
2471 find_candidates_group (MPlist *plist, int index,
2472 int *start_index, int *end_index, int *group_index)
2474 int i = 0, gidx = 0, len;
2476 MPLIST_DO (plist, plist)
2478 if (MPLIST_MTEXT_P (plist))
2479 len = mtext_nchars (MPLIST_MTEXT (plist));
2481 len = mplist_length (MPLIST_PLIST (plist));
2482 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2488 *end_index = i + len;
2490 *group_index = gidx;
2499 /* Adjust markers for the change of preedit text.
2500 If FROM == TO, the change is insertion of INS chars.
2501 If FROM < TO and INS == 0, the change is deletion of the range.
2502 If FROM < TO and INS > 0, the change is replacement. */
2505 adjust_markers (MInputContext *ic, int from, int to, int ins)
2507 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2512 MPLIST_DO (markers, ic_info->markers)
2513 if (MPLIST_INTEGER (markers) > from)
2514 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2515 if (ic->cursor_pos >= from)
2516 ic->cursor_pos += ins;
2520 MPLIST_DO (markers, ic_info->markers)
2522 if (MPLIST_INTEGER (markers) >= to)
2523 MPLIST_VAL (markers)
2524 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2525 else if (MPLIST_INTEGER (markers) > from)
2526 MPLIST_VAL (markers) = (void *) from;
2528 if (ic->cursor_pos >= to)
2529 ic->cursor_pos += ins - (to - from);
2530 else if (ic->cursor_pos > from)
2531 ic->cursor_pos = from;
2537 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2539 int nchars = mt ? mtext_nchars (mt) : 1;
2543 mtext_ins (ic->preedit, pos, mt);
2544 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2548 mtext_ins_char (ic->preedit, pos, c, 1);
2550 MDEBUG_PRINT1 ("('%c')", c);
2552 MDEBUG_PRINT1 ("(U+%04X)", c);
2554 adjust_markers (ic, pos, pos, nchars);
2555 ic->preedit_changed = 1;
2560 preedit_delete (MInputContext *ic, int from, int to)
2562 mtext_del (ic->preedit, from, to);
2563 adjust_markers (ic, from, to, 0);
2564 ic->preedit_changed = 1;
2568 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2572 mtext_del (ic->preedit, from, to);
2575 mtext_ins (ic->preedit, from, mt);
2576 ins = mtext_nchars (mt);
2580 mtext_ins_char (ic->preedit, from, c, 1);
2583 adjust_markers (ic, from, to, ins);
2584 ic->preedit_changed = 1;
2589 preedit_commit (MInputContext *ic, int need_prefix)
2591 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2592 int preedit_len = mtext_nchars (ic->preedit);
2594 if (preedit_len > 0)
2598 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2599 Mcandidate_list, NULL, 0);
2600 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2601 Mcandidate_index, NULL, 0);
2602 mtext_cat (ic->produced, ic->preedit);
2608 MDEBUG_PRINT1 ("\n [IM] [%s]",
2609 MSYMBOL_NAME (ic_info->state->name));
2610 MDEBUG_PRINT (" (commit");
2611 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2612 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2616 mtext_reset (ic->preedit);
2617 mtext_reset (ic_info->preedit_saved);
2618 MPLIST_DO (p, ic_info->markers)
2620 ic->cursor_pos = ic_info->state_pos = 0;
2621 ic->preedit_changed = 1;
2622 ic_info->commit_key_head = ic_info->key_head;
2624 if (ic->candidate_list)
2626 M17N_OBJECT_UNREF (ic->candidate_list);
2627 ic->candidate_list = NULL;
2628 ic->candidate_index = 0;
2629 ic->candidate_from = ic->candidate_to = 0;
2630 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2631 if (ic->candidate_show)
2633 ic->candidate_show = 0;
2634 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2640 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2642 int code = marker_code (sym, 0);
2644 if (mt && (code == '[' || code == ']'))
2648 if (code == '[' && current > 0)
2650 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2654 else if (code == ']' && current < mtext_nchars (mt))
2656 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2662 return (code == '<' ? 0
2663 : code == '>' ? limit
2664 : code == '-' ? current - 1
2665 : code == '+' ? current + 1
2666 : code == '=' ? current
2667 : code - '0' > limit ? limit
2671 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2675 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2677 int from = mtext_property_start (prop);
2678 int to = mtext_property_end (prop);
2680 MPlist *candidate_list = mtext_property_value (prop);
2681 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2683 int ingroup_index = idx - start;
2686 candidate_list = mplist_copy (candidate_list);
2687 if (MPLIST_MTEXT_P (group))
2689 mt = MPLIST_MTEXT (group);
2690 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2698 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2699 i++, plist = MPLIST_NEXT (plist));
2700 mt = MPLIST_MTEXT (plist);
2701 preedit_replace (ic, from, to, mt, 0);
2702 to = from + mtext_nchars (mt);
2704 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2705 M17N_OBJECT_UNREF (candidate_list);
2706 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2707 ic->cursor_pos = to;
2711 get_select_charset (MInputContextInfo * ic_info)
2713 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2716 if (! MPLIST_VAL (plist))
2718 sym = MPLIST_SYMBOL (plist);
2721 return MCHARSET (sym);
2725 adjust_candidates (MPlist *plist, MCharset *charset)
2729 /* plist ::= MTEXT ... | PLIST ... */
2730 plist = mplist_copy (plist);
2731 if (MPLIST_MTEXT_P (plist))
2734 while (! MPLIST_TAIL_P (pl))
2736 /* pl ::= MTEXT ... */
2737 MText *mt = MPLIST_MTEXT (pl);
2741 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2743 c = mtext_ref_char (mt, i);
2744 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2748 mt = mtext_dup (mt);
2749 mplist_set (pl, Mtext, mt);
2750 M17N_OBJECT_UNREF (mt);
2753 mtext_del (mt, i, i + 1);
2756 if (mtext_len (mt) > 0)
2757 pl = MPLIST_NEXT (pl);
2761 M17N_OBJECT_UNREF (mt);
2765 else /* MPLIST_PLIST_P (plist) */
2768 while (! MPLIST_TAIL_P (pl))
2770 /* pl ::= (MTEXT ...) ... */
2771 MPlist *p = MPLIST_PLIST (pl);
2773 /* p ::= MTEXT ... */
2777 while (! MPLIST_TAIL_P (p0))
2779 MText *mt = MPLIST_MTEXT (p0);
2782 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2784 c = mtext_ref_char (mt, i);
2785 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2790 p0 = MPLIST_NEXT (p0);
2797 p = mplist_copy (p);
2798 mplist_set (pl, Mplist, p);
2799 M17N_OBJECT_UNREF (p);
2803 p0 = MPLIST_NEXT (p0);
2806 M17N_OBJECT_UNREF (mt);
2809 if (! MPLIST_TAIL_P (p))
2810 pl = MPLIST_NEXT (pl);
2814 M17N_OBJECT_UNREF (p);
2818 if (MPLIST_TAIL_P (plist))
2820 M17N_OBJECT_UNREF (plist);
2827 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2829 MCharset *charset = get_select_charset (ic_info);
2834 plist = resolve_variable (ic_info, Mcandidates_group_size);
2835 column = MPLIST_INTEGER (plist);
2837 plist = MPLIST_PLIST (args);
2839 plist = adjust_candidates (plist, charset);
2841 if (plist && column > 0)
2843 if (MPLIST_MTEXT_P (plist))
2845 MText *mt = MPLIST_MTEXT (plist);
2846 MPlist *next = MPLIST_NEXT (plist);
2848 if (MPLIST_TAIL_P (next))
2849 M17N_OBJECT_REF (mt);
2852 mt = mtext_dup (mt);
2853 while (! MPLIST_TAIL_P (next))
2855 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2856 next = MPLIST_NEXT (next);
2860 M17N_OBJECT_UNREF (plist);
2862 len = mtext_nchars (mt);
2864 mplist_add (plist, Mtext, mt);
2867 for (i = 0; i < len; i += column)
2869 int to = (i + column < len ? i + column : len);
2870 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2872 mplist_add (plist, Mtext, sub);
2873 M17N_OBJECT_UNREF (sub);
2876 M17N_OBJECT_UNREF (mt);
2878 else if (! MPLIST_TAIL_P (plist))
2880 MPlist *tail = plist;
2881 MPlist *new = mplist ();
2882 MPlist *this = mplist ();
2885 MPLIST_DO (tail, tail)
2887 MPlist *p = MPLIST_PLIST (tail);
2891 MText *mt = MPLIST_MTEXT (p);
2893 if (count == column)
2895 mplist_add (new, Mplist, this);
2896 M17N_OBJECT_UNREF (this);
2900 mplist_add (this, Mtext, mt);
2904 mplist_add (new, Mplist, this);
2905 M17N_OBJECT_UNREF (this);
2906 mplist_set (plist, Mnil, NULL);
2907 MPLIST_DO (tail, new)
2909 MPlist *elt = MPLIST_PLIST (tail);
2911 mplist_add (plist, Mplist, elt);
2913 M17N_OBJECT_UNREF (new);
2922 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2924 MPlist *action = NULL;
2928 if (MPLIST_SYMBOL_P (action_list))
2930 MSymbol var = MPLIST_SYMBOL (action_list);
2933 MPLIST_DO (p, ic_info->vars)
2934 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2936 if (MPLIST_TAIL_P (p))
2938 action = MPLIST_NEXT (MPLIST_PLIST (p));
2939 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2942 if (MPLIST_PLIST_P (action_list))
2944 action = MPLIST_PLIST (action_list);
2945 if (MPLIST_SYMBOL_P (action))
2947 name = MPLIST_SYMBOL (action);
2948 args = MPLIST_NEXT (action);
2950 && MPLIST_PLIST_P (args))
2951 mplist_set (action, Msymbol, M_candidates);
2953 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2956 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2957 mplist_push (action, Msymbol, M_candidates);
2958 mplist_set (action_list, Mplist, action);
2959 M17N_OBJECT_UNREF (action);
2962 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2965 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2966 mplist_push (action, Msymbol, Minsert);
2967 mplist_set (action_list, Mplist, action);
2968 M17N_OBJECT_UNREF (action);
2973 /* Perform list of actions in ACTION_LIST for the current input
2974 context IC. If unhandle action was not performed, return 0.
2975 Otherwise, return -1. */
2978 take_action_list (MInputContext *ic, MPlist *action_list)
2980 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2981 MPlist *candidate_list = ic->candidate_list;
2982 int candidate_index = ic->candidate_index;
2983 int candidate_show = ic->candidate_show;
2984 MTextProperty *prop;
2986 MPLIST_DO (action_list, action_list)
2988 MPlist *action = regularize_action (action_list, ic_info);
2994 name = MPLIST_SYMBOL (action);
2995 args = MPLIST_NEXT (action);
2997 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2998 if (name == Minsert)
3000 if (MPLIST_SYMBOL_P (args))
3002 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3003 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3006 if (MPLIST_MTEXT_P (args))
3007 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3008 else /* MPLIST_INTEGER_P (args)) */
3009 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3011 else if (name == M_candidates)
3013 MPlist *plist = get_candidate_list (ic_info, args);
3016 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
3018 if (MPLIST_MTEXT_P (plist))
3020 preedit_insert (ic, ic->cursor_pos, NULL,
3021 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3024 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
3028 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3030 preedit_insert (ic, ic->cursor_pos, mt, 0);
3031 len = mtext_nchars (mt);
3033 plist = mplist_copy (plist);
3034 mtext_put_prop (ic->preedit,
3035 ic->cursor_pos - len, ic->cursor_pos,
3036 Mcandidate_list, plist);
3037 M17N_OBJECT_UNREF (plist);
3038 mtext_put_prop (ic->preedit,
3039 ic->cursor_pos - len, ic->cursor_pos,
3040 Mcandidate_index, (void *) 0);
3042 else if (name == Mselect)
3045 int code, idx, gindex;
3046 int pos = ic->cursor_pos;
3048 int idx_decided = 0;
3051 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3054 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3055 group = find_candidates_group (mtext_property_value (prop), idx,
3056 &start, &end, &gindex);
3057 if (MPLIST_SYMBOL_P (args))
3059 code = marker_code (MPLIST_SYMBOL (args), 0);
3062 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3063 if (! MPLIST_INTEGER_P (args))
3065 idx = start + MPLIST_INTEGER (args);
3066 if (idx < start || idx >= end)
3074 if (code != '[' && code != ']')
3079 ? new_index (NULL, ic->candidate_index - start,
3080 end - start - 1, MPLIST_SYMBOL (args),
3082 : MPLIST_INTEGER (args)));
3085 find_candidates_group (mtext_property_value (prop), -1,
3090 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3095 int ingroup_index = idx - start;
3098 group = mtext_property_value (prop);
3099 len = mplist_length (group);
3112 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3113 idx += (MPLIST_MTEXT_P (group)
3114 ? mtext_nchars (MPLIST_MTEXT (group))
3115 : mplist_length (MPLIST_PLIST (group)));
3116 len = (MPLIST_MTEXT_P (group)
3117 ? mtext_nchars (MPLIST_MTEXT (group))
3118 : mplist_length (MPLIST_PLIST (group)));
3119 if (ingroup_index >= len)
3120 ingroup_index = len - 1;
3121 idx += ingroup_index;
3123 update_candidate (ic, prop, idx);
3124 MDEBUG_PRINT1 ("(%d)", idx);
3126 else if (name == Mshow)
3127 ic->candidate_show = 1;
3128 else if (name == Mhide)
3129 ic->candidate_show = 0;
3130 else if (name == Mdelete)
3132 int len = mtext_nchars (ic->preedit);
3136 if (MPLIST_SYMBOL_P (args)
3137 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3139 to = ic->cursor_pos + pos;
3142 delete_surrounding_text (ic, to);
3147 delete_surrounding_text (ic, to - len);
3153 to = (MPLIST_SYMBOL_P (args)
3154 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3156 : MPLIST_INTEGER (args));
3161 pos = to - ic->cursor_pos;
3163 MDEBUG_PRINT1 ("(%d)", pos);
3164 if (to < ic->cursor_pos)
3165 preedit_delete (ic, to, ic->cursor_pos);
3166 else if (to > ic->cursor_pos)
3167 preedit_delete (ic, ic->cursor_pos, to);
3169 else if (name == Mmove)
3171 int len = mtext_nchars (ic->preedit);
3173 = (MPLIST_SYMBOL_P (args)
3174 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3176 : MPLIST_INTEGER (args));
3182 if (pos != ic->cursor_pos)
3184 ic->cursor_pos = pos;
3185 ic->preedit_changed = 1;
3187 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3189 else if (name == Mmark)
3191 int code = marker_code (MPLIST_SYMBOL (args), 0);
3195 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3196 (void *) ic->cursor_pos);
3197 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3200 else if (name == Mpushback)
3202 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3206 if (MPLIST_SYMBOL_P (args))
3208 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3209 if (MPLIST_INTEGER_P (args))
3210 num = MPLIST_INTEGER (args);
3215 num = MPLIST_INTEGER (args);
3218 ic_info->key_head -= num;
3220 ic_info->key_head = 0;
3222 ic_info->key_head = - num;
3223 if (ic_info->key_head > ic_info->used)
3224 ic_info->key_head = ic_info->used;
3226 else if (MPLIST_MTEXT_P (args))
3228 MText *mt = MPLIST_MTEXT (args);
3229 int i, len = mtext_nchars (mt);
3232 ic_info->key_head--;
3233 for (i = 0; i < len; i++)
3235 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3236 if (ic_info->key_head + i < ic_info->used)
3237 ic_info->keys[ic_info->key_head + i] = key;
3239 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3244 MPlist *plist = MPLIST_PLIST (args), *pl;
3248 ic_info->key_head--;
3250 MPLIST_DO (pl, plist)
3252 key = MPLIST_SYMBOL (pl);
3253 if (ic_info->key_head < ic_info->used)
3254 ic_info->keys[ic_info->key_head + i] = key;
3256 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3261 else if (name == Mpop)
3263 if (ic_info->key_head < ic_info->used)
3264 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3266 else if (name == Mcall)
3268 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3269 MIMExternalFunc func = NULL;
3270 MSymbol module, func_name;
3271 MPlist *func_args, *val;
3274 module = MPLIST_SYMBOL (args);
3275 args = MPLIST_NEXT (args);
3276 func_name = MPLIST_SYMBOL (args);
3278 if (im_info->externals)
3280 MIMExternalModule *external
3281 = (MIMExternalModule *) mplist_get (im_info->externals,
3284 func = ((MIMExternalFunc)
3285 mplist_get_func (external->func_list, func_name));
3289 func_args = mplist ();
3290 mplist_add (func_args, Mt, ic);
3291 MPLIST_DO (args, MPLIST_NEXT (args))
3295 if (MPLIST_KEY (args) == Msymbol
3296 && MPLIST_KEY (args) != Mnil
3297 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3299 code = new_index (ic, ic->cursor_pos,
3300 mtext_nchars (ic->preedit),
3301 MPLIST_SYMBOL (args), ic->preedit);
3302 mplist_add (func_args, Minteger, (void *) code);
3305 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3307 val = (func) (func_args);
3308 M17N_OBJECT_UNREF (func_args);
3309 if (val && ! MPLIST_TAIL_P (val))
3310 ret = take_action_list (ic, val);
3311 M17N_OBJECT_UNREF (val);
3315 else if (name == Mshift)
3317 shift_state (ic, MPLIST_SYMBOL (args));
3319 else if (name == Mundo)
3321 int intarg = (MPLIST_TAIL_P (args)
3323 : integer_value (ic, args, 0));
3325 mtext_reset (ic->preedit);
3326 mtext_reset (ic_info->preedit_saved);
3327 mtext_reset (ic->produced);
3328 M17N_OBJECT_UNREF (ic_info->vars);
3329 ic_info->vars = mplist_copy (ic_info->vars_saved);
3330 ic->cursor_pos = ic_info->state_pos = 0;
3331 ic_info->state_key_head = ic_info->key_head
3332 = ic_info->commit_key_head = 0;
3334 shift_state (ic, Mnil);
3337 if (MPLIST_TAIL_P (args))
3342 ic_info->used += intarg;
3345 ic_info->used = intarg;
3348 else if (name == Mset || name == Madd || name == Msub
3349 || name == Mmul || name == Mdiv)
3351 MSymbol sym = MPLIST_SYMBOL (args);
3352 MPlist *value = resolve_variable (ic_info, sym);
3356 val1 = MPLIST_INTEGER (value);
3357 args = MPLIST_NEXT (args);
3358 val2 = resolve_expression (ic, args);
3360 val1 = val2, op = "=";
3361 else if (name == Madd)
3362 val1 += val2, op = "+=";
3363 else if (name == Msub)
3364 val1 -= val2, op = "-=";
3365 else if (name == Mmul)
3366 val1 *= val2, op = "*=";
3368 val1 /= val2, op = "/=";
3369 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3370 MSYMBOL_NAME (sym), op, val1, val1);
3371 mplist_set (value, Minteger, (void *) val1);
3373 else if (name == Mequal || name == Mless || name == Mgreater
3374 || name == Mless_equal || name == Mgreater_equal)
3377 MPlist *actions1, *actions2;
3380 val1 = resolve_expression (ic, args);
3381 args = MPLIST_NEXT (args);
3382 val2 = resolve_expression (ic, args);
3383 args = MPLIST_NEXT (args);
3384 actions1 = MPLIST_PLIST (args);
3385 args = MPLIST_NEXT (args);
3386 if (MPLIST_TAIL_P (args))
3389 actions2 = MPLIST_PLIST (args);
3390 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3391 if (name == Mequal ? val1 == val2
3392 : name == Mless ? val1 < val2
3393 : name == Mgreater ? val1 > val2
3394 : name == Mless_equal ? val1 <= val2
3397 MDEBUG_PRINT ("ok");
3398 ret = take_action_list (ic, actions1);
3402 MDEBUG_PRINT ("no");
3404 ret = take_action_list (ic, actions2);
3409 else if (name == Mcond)
3413 MPLIST_DO (args, args)
3418 if (! MPLIST_PLIST (args))
3420 cond = MPLIST_PLIST (args);
3421 if (resolve_expression (ic, cond) != 0)
3423 MDEBUG_PRINT1 ("(%dth)", idx);
3424 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3430 else if (name == Mcommit)
3432 preedit_commit (ic, 0);
3434 else if (name == Munhandle)
3436 preedit_commit (ic, 0);
3441 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3445 && (actions = mplist_get (im_info->macros, name)))
3447 if (take_action_list (ic, actions) < 0)
3453 if (ic->candidate_list)
3455 M17N_OBJECT_UNREF (ic->candidate_list);
3456 ic->candidate_list = NULL;
3458 if (ic->cursor_pos > 0
3459 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3462 ic->candidate_list = mtext_property_value (prop);
3463 M17N_OBJECT_REF (ic->candidate_list);
3465 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3467 ic->candidate_from = mtext_property_start (prop);
3468 ic->candidate_to = mtext_property_end (prop);
3471 if (candidate_list != ic->candidate_list)
3472 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3473 if (candidate_index != ic->candidate_index)
3474 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3475 if (candidate_show != ic->candidate_show)
3476 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3481 /* Handle the input key KEY in the current state and map specified in
3482 the input context IC. If KEY is handled correctly, return 0.
3483 Otherwise, return -1. */
3486 handle_key (MInputContext *ic)
3488 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3489 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3490 MIMMap *map = ic_info->map;
3491 MIMMap *submap = NULL;
3492 MSymbol key = ic_info->keys[ic_info->key_head];
3493 MSymbol alias = Mnil;
3496 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3497 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3501 submap = mplist_get (map->submaps, key);
3504 && (alias = msymbol_get (alias, M_key_alias))
3506 submap = mplist_get (map->submaps, alias);
3511 if (! alias || alias == key)
3512 MDEBUG_PRINT (" submap-found");
3514 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3515 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3516 ic->preedit_changed = 1;
3517 ic->cursor_pos = ic_info->state_pos;
3518 ic_info->key_head++;
3519 ic_info->map = map = submap;
3520 if (map->map_actions)
3522 MDEBUG_PRINT (" map-actions:");
3523 if (take_action_list (ic, map->map_actions) < 0)
3525 MDEBUG_PRINT ("\n");
3529 else if (map->submaps)
3531 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3533 MSymbol key = ic_info->keys[i];
3534 char *name = msymbol_name (key);
3536 if (! name[0] || ! name[1])
3537 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3541 /* If this is the terminal map or we have shifted to another
3542 state, perform branch actions (if any). */
3543 if (! map->submaps || map != ic_info->map)
3545 if (map->branch_actions)
3547 MDEBUG_PRINT (" branch-actions:");
3548 if (take_action_list (ic, map->branch_actions) < 0)
3550 MDEBUG_PRINT ("\n");
3554 /* If MAP is still not the root map, shift to the current
3556 if (ic_info->map != ic_info->state->map)
3557 shift_state (ic, ic_info->state->name);
3562 /* MAP can not handle KEY. */
3564 /* Perform branch actions if any. */
3565 if (map->branch_actions)
3567 MDEBUG_PRINT (" branch-actions:");
3568 if (take_action_list (ic, map->branch_actions) < 0)
3570 MDEBUG_PRINT ("\n");
3575 if (map == ic_info->map)
3577 /* The above branch actions didn't change the state. */
3579 /* If MAP is the root map of the initial state, and there
3580 still exist an unhandled key, it means that the current
3581 input method can not handle it. */
3582 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3583 && ic_info->key_head < ic_info->used)
3585 MDEBUG_PRINT (" unhandled\n");
3589 if (map != ic_info->state->map)
3591 /* MAP is not the root map. Shift to the root map of the
3593 shift_state (ic, ic_info->state->name);
3595 else if (! map->branch_actions)
3597 /* MAP is the root map without any default branch
3598 actions. Shift to the initial state. */
3599 shift_state (ic, Mnil);
3603 MDEBUG_PRINT ("\n");
3607 /* Initialize IC->ic_info. */
3610 init_ic_info (MInputContext *ic)
3612 MInputMethodInfo *im_info = ic->im->info;
3613 MInputContextInfo *ic_info = ic->info;
3616 MLIST_INIT1 (ic_info, keys, 8);;
3618 ic_info->markers = mplist ();
3620 ic_info->vars = mplist ();
3621 if (im_info->configured_vars)
3622 MPLIST_DO (plist, im_info->configured_vars)
3624 MPlist *pl = MPLIST_PLIST (plist);
3625 MSymbol name = MPLIST_SYMBOL (pl);
3627 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3628 if (MPLIST_KEY (pl) != Mt)
3630 MPlist *p = mplist ();
3632 mplist_push (ic_info->vars, Mplist, p);
3633 M17N_OBJECT_UNREF (p);
3634 mplist_add (p, Msymbol, name);
3635 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3638 ic_info->vars_saved = mplist_copy (ic_info->vars);
3640 if (im_info->externals)
3642 MPlist *func_args = mplist (), *plist;
3644 mplist_add (func_args, Mt, ic);
3645 MPLIST_DO (plist, im_info->externals)
3647 MIMExternalModule *external = MPLIST_VAL (plist);
3648 MIMExternalFunc func
3649 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3654 M17N_OBJECT_UNREF (func_args);
3657 ic_info->preedit_saved = mtext ();
3658 ic_info->tick = im_info->tick;
3661 /* Finalize IC->ic_info. */
3664 fini_ic_info (MInputContext *ic)
3666 MInputMethodInfo *im_info = ic->im->info;
3667 MInputContextInfo *ic_info = ic->info;
3669 if (im_info->externals)
3671 MPlist *func_args = mplist (), *plist;
3673 mplist_add (func_args, Mt, ic);
3674 MPLIST_DO (plist, im_info->externals)
3676 MIMExternalModule *external = MPLIST_VAL (plist);
3677 MIMExternalFunc func
3678 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3683 M17N_OBJECT_UNREF (func_args);
3686 MLIST_FREE1 (ic_info, keys);
3687 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3688 M17N_OBJECT_UNREF (ic_info->markers);
3689 M17N_OBJECT_UNREF (ic_info->vars);
3690 M17N_OBJECT_UNREF (ic_info->vars_saved);
3691 M17N_OBJECT_UNREF (ic_info->preceding_text);
3692 M17N_OBJECT_UNREF (ic_info->following_text);
3694 memset (ic_info, 0, sizeof (MInputContextInfo));
3698 re_init_ic (MInputContext *ic, int reload)
3700 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3701 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3702 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3704 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3705 preedit_changed = mtext_nchars (ic->preedit) > 0;
3706 cursor_pos_changed = ic->cursor_pos > 0;
3707 candidates_changed = 0;
3708 if (ic->candidate_list)
3710 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3711 M17N_OBJECT_UNREF (ic->candidate_list);
3712 ic->candidate_list = NULL;
3714 if (ic->candidate_show)
3716 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3717 ic->candidate_show = 0;
3719 if (ic->candidate_index > 0)
3721 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3722 ic->candidate_index = 0;
3723 ic->candidate_from = ic->candidate_to = 0;
3725 if (mtext_nchars (ic->produced) > 0)
3726 mtext_reset (ic->produced);
3727 if (mtext_nchars (ic->preedit) > 0)
3728 mtext_reset (ic->preedit);
3730 M17N_OBJECT_UNREF (ic->plist);
3731 ic->plist = mplist ();
3735 reload_im_info (im_info);
3736 if (! im_info->states)
3738 struct MIMState *state;
3740 M17N_OBJECT (state, free_state, MERROR_IM);
3741 state->name = msymbol ("init");
3742 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3743 MSTRUCT_CALLOC (state->map, MERROR_IM);
3744 im_info->states = mplist ();
3745 mplist_add (im_info->states, state->name, state);
3748 shift_state (ic, Mnil);
3750 ic->status_changed = status_changed;
3751 ic->preedit_changed = preedit_changed;
3752 ic->cursor_pos_changed = cursor_pos_changed;
3753 ic->candidates_changed = candidates_changed;
3757 reset_ic (MInputContext *ic, MSymbol ignore)
3759 MDEBUG_PRINT ("\n [IM] reset\n");
3764 open_im (MInputMethod *im)
3766 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3768 if (! im_info || ! im_info->states)
3769 MERROR (MERROR_IM, -1);
3776 close_im (MInputMethod *im)
3782 create_ic (MInputContext *ic)
3784 MInputContextInfo *ic_info;
3786 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3789 shift_state (ic, Mnil);
3794 destroy_ic (MInputContext *ic)
3801 check_reload (MInputContext *ic, MSymbol key)
3803 MInputMethodInfo *im_info = ic->im->info;
3804 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3808 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3812 MPLIST_DO (plist, plist)
3814 MSymbol this_key, alias;
3816 if (MPLIST_MTEXT_P (plist))
3818 MText *mt = MPLIST_MTEXT (plist);
3819 int c = mtext_ref_char (mt, 0);
3823 this_key = one_char_symbol[c];
3827 MPlist *pl = MPLIST_PLIST (plist);
3829 this_key = MPLIST_SYMBOL (pl);
3833 && (alias = msymbol_get (alias, M_key_alias))
3834 && alias != this_key);
3838 if (MPLIST_TAIL_P (plist))
3841 MDEBUG_PRINT ("\n [IM] reload");
3847 /** Handle the input key KEY in the current state and map of IC->info.
3848 If KEY is handled but no text is produced, return 0, otherwise
3854 filter (MInputContext *ic, MSymbol key, void *arg)
3856 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3857 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3860 if (check_reload (ic, key))
3863 if (! ic_info->state)
3865 ic_info->key_unhandled = 1;
3868 mtext_reset (ic->produced);
3869 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3870 M17N_OBJECT_UNREF (ic_info->preceding_text);
3871 M17N_OBJECT_UNREF (ic_info->following_text);
3872 ic_info->preceding_text = ic_info->following_text = NULL;
3873 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3874 ic_info->key_unhandled = 0;
3877 if (handle_key (ic) < 0)
3879 /* KEY was not handled. Delete it from the current key sequence. */
3880 if (ic_info->used > 0)
3882 memmove (ic_info->keys, ic_info->keys + 1,
3883 sizeof (int) * (ic_info->used - 1));
3885 if (ic_info->state_key_head > 0)
3886 ic_info->state_key_head--;
3887 if (ic_info->commit_key_head > 0)
3888 ic_info->commit_key_head--;
3890 /* This forces returning 1. */
3891 ic_info->key_unhandled = 1;
3897 reset_ic (ic, Mnil);
3898 ic_info->key_unhandled = 1;
3901 /* Break the loop if all keys were handled. */
3902 } while (ic_info->key_head < ic_info->used);
3904 /* If the current map is the root of the initial state, we should
3905 produce any preedit text in ic->produced. */
3906 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3907 preedit_commit (ic, 1);
3909 if (mtext_nchars (ic->produced) > 0)
3913 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3914 MSYMBOL_NAME (ic_info->state->name));
3915 for (i = 0; i < mtext_nchars (ic->produced); i++)
3916 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3920 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3921 Mlanguage, ic->im->language);
3923 if (ic_info->commit_key_head > 0)
3925 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3926 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3927 ic_info->used -= ic_info->commit_key_head;
3928 ic_info->key_head -= ic_info->commit_key_head;
3929 ic_info->state_key_head -= ic_info->commit_key_head;
3930 ic_info->commit_key_head = 0;
3932 if (ic_info->key_unhandled)
3935 ic_info->key_head = ic_info->state_key_head
3936 = ic_info->commit_key_head = 0;
3939 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3943 /** Return 1 if the last event or key was not handled, otherwise
3946 There is no need of looking up because ic->produced should already
3947 contain the produced text (if any).
3952 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3954 mtext_cat (mt, ic->produced);
3955 mtext_reset (ic->produced);
3956 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3960 /* Input method command handler. */
3962 /* List of all (global and local) commands.
3963 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3964 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3965 Global commands are stored as (t (t COMMAND ...)) */
3968 /* Input method variable handler. */
3971 /* Support functions for mdebug_dump_im. */
3974 dump_im_map (MPlist *map_list, int indent)
3977 MSymbol key = MPLIST_KEY (map_list);
3978 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3980 prefix = (char *) alloca (indent + 1);
3981 memset (prefix, 32, indent);
3982 prefix[indent] = '\0';
3984 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3985 if (map->map_actions)
3986 mdebug_dump_plist (map->map_actions, indent + 2);
3989 MPLIST_DO (map_list, map->submaps)
3991 fprintf (stderr, "\n%s ", prefix);
3992 dump_im_map (map_list, indent + 2);
3995 if (map->branch_actions)
3997 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3998 mdebug_dump_plist (map->branch_actions, indent + 4);
3999 fprintf (stderr, ")");
4001 fprintf (stderr, ")");
4006 dump_im_state (MIMState *state, int indent)
4011 prefix = (char *) alloca (indent + 1);
4012 memset (prefix, 32, indent);
4013 prefix[indent] = '\0';
4015 fprintf (stderr, "(%s", msymbol_name (state->name));
4016 if (state->map->submaps)
4018 MPLIST_DO (map_list, state->map->submaps)
4020 fprintf (stderr, "\n%s ", prefix);
4021 dump_im_map (map_list, indent + 2);
4024 fprintf (stderr, ")");
4032 Minput_driver = msymbol ("input-driver");
4034 Minput_preedit_start = msymbol ("input-preedit-start");
4035 Minput_preedit_done = msymbol ("input-preedit-done");
4036 Minput_preedit_draw = msymbol ("input-preedit-draw");
4037 Minput_status_start = msymbol ("input-status-start");
4038 Minput_status_done = msymbol ("input-status-done");
4039 Minput_status_draw = msymbol ("input-status-draw");
4040 Minput_candidates_start = msymbol ("input-candidates-start");
4041 Minput_candidates_done = msymbol ("input-candidates-done");
4042 Minput_candidates_draw = msymbol ("input-candidates-draw");
4043 Minput_set_spot = msymbol ("input-set-spot");
4044 Minput_focus_move = msymbol ("input-focus-move");
4045 Minput_focus_in = msymbol ("input-focus-in");
4046 Minput_focus_out = msymbol ("input-focus-out");
4047 Minput_toggle = msymbol ("input-toggle");
4048 Minput_reset = msymbol ("input-reset");
4049 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4050 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4051 Mcustomized = msymbol ("customized");
4052 Mconfigured = msymbol ("configured");
4053 Minherited = msymbol ("inherited");
4055 minput_default_driver.open_im = open_im;
4056 minput_default_driver.close_im = close_im;
4057 minput_default_driver.create_ic = create_ic;
4058 minput_default_driver.destroy_ic = destroy_ic;
4059 minput_default_driver.filter = filter;
4060 minput_default_driver.lookup = lookup;
4061 minput_default_driver.callback_list = mplist ();
4062 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4063 M17N_FUNC (reset_ic));
4064 minput_driver = &minput_default_driver;
4066 fully_initialized = 0;
4073 if (fully_initialized)
4075 free_im_list (im_info_list);
4077 free_im_list (im_custom_list);
4079 free_im_list (im_config_list);
4080 M17N_OBJECT_UNREF (load_im_info_keys);
4083 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4084 M17N_OBJECT_UNREF (minput_driver->callback_list);
4089 minput__char_to_key (int c)
4091 if (c < 0 || c >= 0x100)
4094 return one_char_symbol[c];
4098 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4103 /*** @addtogroup m17nInputMethod */
4108 @name Variables: Predefined symbols for callback commands.
4110 These are the predefined symbols that are used as the @c COMMAND
4111 argument of callback functions of an input method driver (see
4112 #MInputDriver::callback_list).
4114 Most of them do not require extra argument nor return any value;
4115 exceptions are these:
4117 Minput_get_surrounding_text: When a callback function assigned for
4118 this command is called, the first element of #MInputContext::plist
4119 has key #Minteger and the value specifies which portion of the
4120 surrounding text should be retrieved. If the value is positive,
4121 it specifies the number of characters following the current cursor
4122 position. If the value is negative, the absolute value specifies
4123 the number of characters preceding the current cursor position.
4124 If the value is zero, it means that the caller just wants to know
4125 if the surrounding text is currently supported or not.
4127 If the surrounding text is currently supported, the callback
4128 function must set the key of this element to #Mtext and the value
4129 to the retrieved M-text. The length of the M-text may be shorter
4130 than the requested number of characters, if the available text is
4131 not that long. The length can be zero in the worst case. Or, the
4132 length may be longer if an application thinks it is more efficient
4133 to return that length.
4135 If the surrounding text is not currently supported, the callback
4136 function should return without changing the first element of
4137 #MInputContext::plist.
4139 Minput_delete_surrounding_text: When a callback function assigned
4140 for this command is called, the first element of
4141 #MInputContext::plist has key #Minteger and the value specifies
4142 which portion of the surrounding text should be deleted in the
4143 same way as the case of Minput_get_surrounding_text. The callback
4144 function must delete the specified text. It should not alter
4145 #MInputContext::plist. */
4147 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4149 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4150 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4152 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4154 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4155 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4156 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4157 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4158 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4159 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4160 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4162 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4163 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4164 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4165 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4166 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4168 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4169 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4171 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4172 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4173 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4174 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4175 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4176 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4180 MSymbol Minput_preedit_start;
4181 MSymbol Minput_preedit_done;
4182 MSymbol Minput_preedit_draw;
4183 MSymbol Minput_status_start;
4184 MSymbol Minput_status_done;
4185 MSymbol Minput_status_draw;
4186 MSymbol Minput_candidates_start;
4187 MSymbol Minput_candidates_done;
4188 MSymbol Minput_candidates_draw;
4189 MSymbol Minput_set_spot;
4190 MSymbol Minput_toggle;
4191 MSymbol Minput_reset;
4192 MSymbol Minput_get_surrounding_text;
4193 MSymbol Minput_delete_surrounding_text;
4199 @name Variables: Predefined symbols for special input events.
4201 These are the predefined symbols that are used as the @c KEY
4202 argument of minput_filter (). */
4204 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4206 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4211 MSymbol Minput_focus_out;
4212 MSymbol Minput_focus_in;
4213 MSymbol Minput_focus_move;
4219 @name Variables: Predefined symbols used in input method information.
4221 These are the predefined symbols describing status of input method
4222 command and variable, and are used in a return value of
4223 minput_get_command () and minput_get_variable (). */
4225 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4227 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4228 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4232 MSymbol Mcustomized;
4233 MSymbol Mconfigured;
4239 @brief The default driver for internal input methods.
4241 The variable #minput_default_driver is the default driver for
4242 internal input methods.
4244 The member MInputDriver::open_im () searches the m17n database for
4245 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4246 $NAME\> and loads it.
4248 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4249 programmers responsibility to set it to a plist of proper callback
4250 functions. Otherwise, no feedback information (e.g. preedit text)
4251 can be shown to users.
4253 The macro M17N_INIT () sets the variable #minput_driver to the
4254 pointer to this driver so that all internal input methods use it.
4256 Therefore, unless @c minput_driver is set differently, the driver
4257 dependent arguments $ARG of the functions whose name begins with
4258 "minput_" are all ignored. */
4260 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4262 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4264 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4265 \< #Minput_method, $LANGUAGE, $NAME\>
4266 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4268 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4269 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4270 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4271 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4273 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4274 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4276 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4277 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4279 MInputDriver minput_default_driver;
4283 @brief The driver for internal input methods.
4285 The variable #minput_driver is a pointer to the input method
4286 driver that is used by internal input methods. The macro
4287 M17N_INIT () initializes it to a pointer to #minput_default_driver
4288 if <m17n<EM></EM>.h> is included. */
4290 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4292 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4293 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4294 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4295 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4297 MInputDriver *minput_driver;
4299 MSymbol Minput_driver;
4314 @brief Open an input method.
4316 The minput_open_im () function opens an input method whose
4317 language and name match $LANGUAGE and $NAME, and returns a pointer
4318 to the input method object newly allocated.
4320 This function at first decides a driver for the input method as
4323 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4324 #minput_driver is used.
4326 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4327 driver pointed to by the property value is used to open the input
4328 method. If $NAME has no such a property, @c NULL is returned.
4330 Then, the member MInputDriver::open_im () of the driver is
4333 $ARG is set in the member @c arg of the structure MInputMethod so
4334 that the driver can refer to it. */
4336 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4338 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4339 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4341 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4343 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4344 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4346 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4347 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4348 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4350 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4352 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4354 @latexonly \IPAlabel{minput_open} @endlatexonly
4359 minput_open_im (MSymbol language, MSymbol name, void *arg)
4362 MInputDriver *driver;
4366 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4367 msymbol_name (language), msymbol_name (name));
4371 MERROR (MERROR_IM, NULL);
4372 driver = minput_driver;
4376 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4378 MERROR (MERROR_IM, NULL);
4381 MSTRUCT_CALLOC (im, MERROR_IM);
4382 im->language = language;
4385 im->driver = *driver;
4386 if ((*im->driver.open_im) (im) < 0)
4388 MDEBUG_PRINT (" failed\n");
4392 MDEBUG_PRINT (" ok\n");
4399 @brief Close an input method.
4401 The minput_close_im () function closes the input method $IM, which
4402 must have been created by minput_open_im (). */
4405 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4407 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4408 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4411 minput_close_im (MInputMethod *im)
4413 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4414 msymbol_name (im->name), msymbol_name (im->language));
4415 (*im->driver.close_im) (im);
4417 MDEBUG_PRINT (" done\n");
4423 @brief Create an input context.
4425 The minput_create_ic () function creates an input context object
4426 associated with input method $IM, and calls callback functions
4427 corresponding to #Minput_preedit_start, #Minput_status_start, and
4428 #Minput_status_draw in this order.
4431 If an input context is successfully created, minput_create_ic ()
4432 returns a pointer to it. Otherwise it returns @c NULL. */
4435 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4437 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4438 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4439 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4440 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4443 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4444 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4448 minput_create_ic (MInputMethod *im, void *arg)
4452 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4453 msymbol_name (im->name), msymbol_name (im->language));
4454 MSTRUCT_CALLOC (ic, MERROR_IM);
4457 ic->preedit = mtext ();
4458 ic->candidate_list = NULL;
4459 ic->produced = mtext ();
4460 ic->spot.x = ic->spot.y = 0;
4462 ic->plist = mplist ();
4463 if ((*im->driver.create_ic) (ic) < 0)
4465 MDEBUG_PRINT (" failed\n");
4466 M17N_OBJECT_UNREF (ic->preedit);
4467 M17N_OBJECT_UNREF (ic->produced);
4468 M17N_OBJECT_UNREF (ic->plist);
4473 if (im->driver.callback_list)
4475 minput_callback (ic, Minput_preedit_start);
4476 minput_callback (ic, Minput_status_start);
4477 minput_callback (ic, Minput_status_draw);
4480 MDEBUG_PRINT (" ok\n");
4487 @brief Destroy an input context.
4489 The minput_destroy_ic () function destroys the input context $IC,
4490 which must have been created by minput_create_ic (). It calls
4491 callback functions corresponding to #Minput_preedit_done,
4492 #Minput_status_done, and #Minput_candidates_done in this order. */
4495 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4497 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4498 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4499 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4500 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4501 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4505 minput_destroy_ic (MInputContext *ic)
4507 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4508 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4509 if (ic->im->driver.callback_list)
4511 minput_callback (ic, Minput_preedit_done);
4512 minput_callback (ic, Minput_status_done);
4513 minput_callback (ic, Minput_candidates_done);
4515 (*ic->im->driver.destroy_ic) (ic);
4516 M17N_OBJECT_UNREF (ic->preedit);
4517 M17N_OBJECT_UNREF (ic->produced);
4518 M17N_OBJECT_UNREF (ic->plist);
4519 MDEBUG_PRINT (" done\n");
4526 @brief Filter an input key.
4528 The minput_filter () function filters input key $KEY according to
4529 input context $IC, and calls callback functions corresponding to
4530 #Minput_preedit_draw, #Minput_status_draw, and
4531 #Minput_candidates_draw if the preedit text, the status, and the
4532 current candidate are changed respectively.
4534 To make the input method commit the current preedit text (if any)
4535 and shift to the initial state, call this function with #Mnil as
4538 To inform the input method about the focus-out event, call this
4539 function with #Minput_focus_out as $KEY.
4541 To inform the input method about the focus-in event, call this
4542 function with #Minput_focus_in as $KEY.
4544 To inform the input method about the focus-move event (i.e. input
4545 spot change within the same input context), call this function
4546 with #Minput_focus_move as $KEY.
4549 If $KEY is filtered out, this function returns 1. In that case,
4550 the caller should discard the key. Otherwise, it returns 0, and
4551 the caller should handle the key, for instance, by calling the
4552 function minput_lookup () with the same key. */
4555 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4557 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4558 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4559 #Minput_preedit_draw, #Minput_status_draw,
4560 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4563 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4564 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4565 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4566 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4568 @latexonly \IPAlabel{minput_filter} @endlatexonly
4572 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4579 if (ic->im->driver.callback_list
4580 && mtext_nchars (ic->preedit) > 0)
4581 minput_callback (ic, Minput_preedit_draw);
4583 ret = (*ic->im->driver.filter) (ic, key, arg);
4585 if (ic->im->driver.callback_list)
4587 if (ic->preedit_changed)
4588 minput_callback (ic, Minput_preedit_draw);
4589 if (ic->status_changed)
4590 minput_callback (ic, Minput_status_draw);
4591 if (ic->candidates_changed)
4592 minput_callback (ic, Minput_candidates_draw);
4601 @brief Look up a text produced in the input context.
4603 The minput_lookup () function looks up a text in the input context
4604 $IC. $KEY must be identical to the one that was used in the previous call of
4607 If a text was produced by the input method, it is concatenated
4610 This function calls #MInputDriver::lookup .
4613 If $KEY was correctly handled by the input method, this function
4614 returns 0. Otherwise, it returns -1, even though some text
4615 might be produced in $MT. */
4618 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4620 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4621 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4623 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4626 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4629 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4630 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4631 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4633 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4636 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4638 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4643 @brief Set the spot of the input context.
4645 The minput_set_spot () function sets the spot of input context $IC
4646 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4647 The semantics of these values depends on the input method driver.
4649 For instance, a driver designed to work in a CUI environment may
4650 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4651 $DESCENT . A driver designed to work in a window system may
4652 interpret $X and $Y as the pixel offsets relative to the origin of the
4653 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4654 descent pixels of the line at ($X . $Y ).
4656 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4658 $MT and $POS are the M-text and the character position at the spot.
4659 $MT may be @c NULL, in which case, the input method cannot get
4660 information about the text around the spot. */
4663 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4665 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4666 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4667 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4669 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4670 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4671 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4672 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4673 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4674 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4676 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4678 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4679 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4683 minput_set_spot (MInputContext *ic, int x, int y,
4684 int ascent, int descent, int fontsize,
4689 ic->spot.ascent = ascent;
4690 ic->spot.descent = descent;
4691 ic->spot.fontsize = fontsize;
4694 if (ic->im->driver.callback_list)
4695 minput_callback (ic, Minput_set_spot);
4700 @brief Toggle input method.
4702 The minput_toggle () function toggles the input method associated
4703 with input context $IC. */
4705 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4707 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4708 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4712 minput_toggle (MInputContext *ic)
4714 if (ic->im->driver.callback_list)
4715 minput_callback (ic, Minput_toggle);
4716 ic->active = ! ic->active;
4722 @brief Reset an input context.
4724 The minput_reset_ic () function resets input context $IC by
4725 calling a callback function corresponding to #Minput_reset. It
4726 resets the status of $IC to its initial one. As the
4727 current preedit text is deleted without commitment, if necessary,
4728 call minput_filter () with the arg @r key #Mnil to force the input
4729 method to commit the preedit in advance. */
4732 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4734 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4735 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4736 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4737 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4738 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4739 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4742 minput_reset_ic (MInputContext *ic)
4744 if (ic->im->driver.callback_list)
4745 minput_callback (ic, Minput_reset);
4751 @brief Get title and icon filename of an input method.
4753 The minput_get_title_icon () function returns a plist containing a
4754 title and icon filename (if any) of an input method specified by
4755 $LANGUAGE and $NAME.
4757 The first element of the plist has key #Mtext and the value is an
4758 M-text of the title for identifying the input method. The second
4759 element (if any) has key #Mtext and the value is an M-text of the
4760 icon image (absolute) filename for the same purpose.
4763 If there exists a specified input method and it defines an title,
4764 a plist is returned. Otherwise, NULL is returned. The caller
4765 must free the plist by m17n_object_unref (). */
4767 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4769 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4770 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4773 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4774 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4775 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4778 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4779 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4780 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4783 minput_get_title_icon (MSymbol language, MSymbol name)
4785 MInputMethodInfo *im_info;
4792 im_info = get_im_info (language, name, Mnil, Mtitle);
4793 if (! im_info || !im_info->title)
4795 mt = mtext_get_prop (im_info->title, 0, Mtext);
4797 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4800 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4803 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4804 (char *) MSYMBOL_NAME (name));
4805 file = mdatabase__find_file (buf);
4806 if (! file && language == Mt)
4808 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4809 file = mdatabase__find_file (buf);
4814 mplist_add (plist, Mtext, im_info->title);
4817 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4819 mplist_add (plist, Mtext, mt);
4820 M17N_OBJECT_UNREF (mt);
4828 @brief Get description text of an input method.
4830 The minput_get_description () function returns an M-text that
4831 describes the input method specified by $LANGUAGE and $NAME.
4834 If the specified input method has a description text, a pointer to
4835 #MText is returned. The caller has to free it by m17n_object_unref ().
4836 If the input method does not have a description text, @c NULL is
4839 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4841 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4842 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4845 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4846 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4847 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4848 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4851 minput_get_description (MSymbol language, MSymbol name)
4853 MInputMethodInfo *im_info;
4861 extra = language, language = Mt;
4863 im_info = get_im_info (language, name, extra, Mdescription);
4864 if (! im_info || ! im_info->description)
4866 M17N_OBJECT_REF (im_info->description);
4867 return im_info->description;
4873 @brief Get information about input method command(s).
4875 The minput_get_command () function returns information about
4876 the command $COMMAND of the input method specified by $LANGUAGE and
4877 $NAME. An input method command is a pseudo key event to which one
4878 or more actual input key sequences are assigned.
4880 There are two kinds of commands, global and local. A global
4881 command has a global definition, and the description and the key
4882 assignment may be inherited by a local command. Each input method
4883 defines a local command which has a local key assignment. It may
4884 also declare a local command that inherits the definition of a
4885 global command of the same name.
4887 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4888 information about a global command. Otherwise information about a
4889 local command is returned.
4891 If $COMMAND is #Mnil, information about all commands is returned.
4893 The return value is a @e well-formed plist (@ref m17nPlist) of this
4896 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4898 @c NAME is a symbol representing the command name.
4900 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4901 command has no description.
4903 @c STATUS is a symbol representing how the key assignment is decided.
4904 The value is #Mnil (the default key assignment), #Mcustomized (the
4905 key assignment is customized by per-user customization file), or
4906 #Mconfigured (the key assignment is set by the call of
4907 minput_config_command ()). For a local command only, it may also
4908 be #Minherited (the key assignment is inherited from the
4909 corresponding global command).
4911 @c KEYSEQ is a plist of one or more symbols representing a key
4912 sequence assigned to the command. If there's no KEYSEQ, the
4913 command is currently disabled (i.e. no key sequence can trigger
4914 actions of the command).
4916 If $COMMAND is not #Mnil, the first element of the returned plist
4917 contains the information about $COMMAND.
4921 If the requested information was found, a pointer to a non-empty
4922 plist is returned. As the plist is kept in the library, the
4923 caller must not modify nor free it.
4925 Otherwise (the specified input method or the specified command
4926 does not exist), @c NULL is returned. */
4928 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4930 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4931 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4932 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4933 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4935 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4936 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4937 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4938 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4939 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4941 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4942 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4945 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4947 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4950 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4952 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4954 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4957 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4958 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4959 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4960 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4961 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4962 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4965 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4966 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4967 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4968 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4970 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4971 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4975 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4976 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4979 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4984 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4986 /* Return a description of the command COMMAND of the input method
4987 specified by LANGUAGE and NAME. */
4988 MPlist *cmd = minput_get_command (langauge, name, command);
4993 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4994 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4995 return (mplist_key (plist) == Mtext
4996 ? (MText *) mplist_value (plist)
5002 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5004 MInputMethodInfo *im_info;
5008 im_info = get_im_info (language, name, Mnil, Mcommand);
5010 || ! im_info->configured_cmds
5011 || MPLIST_TAIL_P (im_info->configured_cmds))
5013 if (command == Mnil)
5014 return im_info->configured_cmds;
5015 return mplist__assq (im_info->configured_cmds, command);
5021 @brief Configure the key sequence of an input method command.
5023 The minput_config_command () function assigns a list of key
5024 sequences $KEYSEQLIST to the command $COMMAND of the input method
5025 specified by $LANGUAGE and $NAME.
5027 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5028 sequences, and each key sequence must be a plist of symbols.
5030 If $KEYSEQLIST is an empty plist, any configuration and
5031 customization of the command are cancelled, and default key
5032 sequences become effective.
5034 If $KEYSEQLIST is NULL, the configuration of the command is
5035 canceled, and the original key sequences (what saved in per-user
5036 customization file, or the default one) become effective.
5038 In the latter two cases, $COMMAND can be #Mnil to make all the
5039 commands of the input method the target of the operation.
5041 If $NAME is #Mnil, this function configures the key assignment of a
5042 global command, not that of a specific input method.
5044 The configuration takes effect for input methods opened or
5045 re-opened later in the current session. In order to make the
5046 configuration take effect for the future session, it must be saved
5047 in a per-user customization file by the function
5048 minput_save_config ().
5051 If the operation was successful, this function returns 0,
5052 otherwise returns -1. The operation fails in these cases:
5054 <li>$KEYSEQLIST is not in a valid form.
5055 <li>$COMMAND is not available for the input method.
5056 <li>$LANGUAGE and $NAME do not specify an existing input method.
5060 minput_get_commands (), minput_save_config ().
5063 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5065 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5066 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5067 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5069 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5070 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5072 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5073 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5075 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5076 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5077 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5079 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5080 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5082 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5083 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5085 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5086 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5087 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5088 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5092 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5094 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5095 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5096 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5100 minput_get_commands (), minput_save_config ().
5104 /* Add "C-x u" to the "start" command of Unicode input method. */
5106 MSymbol start_command = msymbol ("start");
5107 MSymbol unicode = msymbol ("unicode");
5108 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5110 /* At first get the current key-sequence assignment. */
5111 cmd = minput_get_command (Mt, unicode, start_command);
5114 /* The input method does not have the command "start". Here
5115 should come some error handling code. */
5117 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5118 Extract the part (KEY-SEQUENCE ...). */
5119 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5120 /* Copy it because we should not modify it directly. */
5121 key_seq_list = mplist_copy (plist);
5123 key_seq = mplist ();
5124 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5125 mplist_add (key_seq, Msymbol, msymbol ("u"));
5126 mplist_add (key_seq_list, Mplist, key_seq);
5127 m17n_object_unref (key_seq);
5129 minput_config_command (Mt, unicode, start_command, key_seq_list);
5130 m17n_object_unref (key_seq_list);
5135 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5138 MInputMethodInfo *im_info, *config;
5143 im_info = get_im_info (language, name, Mnil, Mcommand);
5145 MERROR (MERROR_IM, -1);
5146 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5148 || ! mplist__assq (im_info->configured_cmds, command)))
5149 MERROR (MERROR_IM, -1);
5150 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5152 MPLIST_DO (plist, keyseqlist)
5153 if (! check_command_keyseq (plist))
5154 MERROR (MERROR_IM, -1);
5157 config = get_config_info (im_info);
5160 if (! im_config_list)
5161 im_config_list = mplist ();
5162 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5163 config->cmds = mplist ();
5164 config->vars = mplist ();
5167 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5168 /* Nothing to do. */
5171 if (command == Mnil)
5175 /* Cancal the configuration. */
5176 if (MPLIST_TAIL_P (config->cmds))
5178 mplist_set (config->cmds, Mnil, NULL);
5182 /* Cancal the customization. */
5183 MInputMethodInfo *custom = get_custom_info (im_info);
5185 if (MPLIST_TAIL_P (config->cmds)
5186 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5187 /* Nothing to do. */
5189 mplist_set (config->cmds, Mnil, NULL);
5190 MPLIST_DO (plist, custom->cmds)
5192 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5194 mplist_add (plist, Msymbol, command);
5195 mplist_push (config->cmds, Mplist, plist);
5196 M17N_OBJECT_UNREF (plist);
5202 plist = mplist__assq (config->cmds, command);
5205 /* Cancel the configuration. */
5208 mplist__pop_unref (plist);
5210 else if (MPLIST_TAIL_P (keyseqlist))
5212 /* Cancel the customization. */
5213 MInputMethodInfo *custom = get_custom_info (im_info);
5214 int no_custom = (! custom || ! custom->cmds
5215 || ! mplist__assq (custom->cmds, command));
5221 mplist_add (config->cmds, Mplist, plist);
5222 M17N_OBJECT_UNREF (plist);
5223 plist = mplist_add (plist, Msymbol, command);
5228 mplist__pop_unref (plist);
5231 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5232 plist = MPLIST_NEXT (plist);
5233 mplist_set (plist, Mnil, NULL);
5243 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5244 if (! MPLIST_TAIL_P (plist))
5245 mplist_set (plist, Mnil, NULL);
5250 mplist_add (config->cmds, Mplist, plist);
5251 M17N_OBJECT_UNREF (plist);
5252 plist = mplist_add (plist, Msymbol, command);
5253 plist = MPLIST_NEXT (plist);
5255 MPLIST_DO (keyseqlist, keyseqlist)
5257 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5258 plist = mplist_add (plist, Mplist, pl);
5259 M17N_OBJECT_UNREF (pl);
5263 config_all_commands (im_info);
5264 im_info->tick = time (NULL);
5271 @brief Get information about input method variable(s).
5273 The minput_get_variable () function returns information about
5274 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5275 An input method variable controls behavior of an input method.
5277 There are two kinds of variables, global and local. A global
5278 variable has a global definition, and the description and the value
5279 may be inherited by a local variable. Each input method defines a
5280 local variable which has local value. It may also declare a
5281 local variable that inherits definition of a global variable of
5284 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5285 variable is returned. Otherwise information about a local variable
5288 If $VARIABLE is #Mnil, information about all variables is
5291 The return value is a @e well-formed plist (@ref m17nPlist) of this
5294 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5296 @c NAME is a symbol representing the variable name.
5298 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5299 variable has no description.
5301 @c STATUS is a symbol representing how the value is decided. The
5302 value is #Mnil (the default value), #Mcustomized (the value is
5303 customized by per-user customization file), or #Mconfigured (the
5304 value is set by the call of minput_config_variable ()). For a
5305 local variable only, it may also be #Minherited (the value is
5306 inherited from the corresponding global variable).
5308 @c VALUE is the initial value of the variable. If the key of this
5309 element is #Mt, the variable has no initial value. Otherwise, the
5310 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5313 @c VALID-VALUEs (if any) specify which values the variable can have.
5314 They have the same type (i.e. having the same key) as @c VALUE except
5315 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5316 may be a plist of two integers specifying the range of possible
5319 If there no @c VALID-VALUE, the variable can have any value as long
5320 as the type is the same as @c VALUE.
5322 If $VARIABLE is not #Mnil, the first element of the returned plist
5323 contains the information about $VARIABLE.
5327 If the requested information was found, a pointer to a non-empty
5328 plist is returned. As the plist is kept in the library, the
5329 caller must not modify nor free it.
5331 Otherwise (the specified input method or the specified variable
5332 does not exist), @c NULL is returned. */
5334 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5336 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5337 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5338 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5340 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5341 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5342 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5343 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5346 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5347 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5349 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5351 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5353 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5356 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5358 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5361 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5362 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5363 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5364 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5365 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5366 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5368 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5369 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5370 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5372 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5373 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5374 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5375 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5377 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5380 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5381 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5385 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5386 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5389 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5393 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5395 MInputMethodInfo *im_info;
5399 im_info = get_im_info (language, name, Mnil, Mvariable);
5400 if (! im_info || ! im_info->configured_vars)
5402 if (variable == Mnil)
5403 return im_info->configured_vars;
5404 return mplist__assq (im_info->configured_vars, variable);
5410 @brief Configure the value of an input method variable.
5412 The minput_config_variable () function assigns $VALUE to the
5413 variable $VARIABLE of the input method specified by $LANGUAGE and
5416 If $VALUE is a non-empty plist, it must be a plist of one element
5417 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5418 the corresponding type. That value is assigned to the variable.
5420 If $VALUE is an empty plist, any configuration and customization
5421 of the variable are canceled, and the default value is assigned to
5424 If $VALUE is NULL, the configuration of the variable is canceled,
5425 and the original value (what saved in per-user customization file,
5426 or the default value) is assigned to the variable.
5428 In the latter two cases, $VARIABLE can be #Mnil to make all the
5429 variables of the input method the target of the operation.
5431 If $NAME is #Mnil, this function configures the value of global
5432 variable, not that of a specific input method.
5434 The configuration takes effect for input methods opened or
5435 re-opened later in the current session. To make the configuration
5436 take effect for the future session, it must be saved in a per-user
5437 customization file by the function minput_save_config ().
5441 If the operation was successful, this function returns 0,
5442 otherwise returns -1. The operation fails in these cases:
5444 <li>$VALUE is not in a valid form, the type does not match the
5445 definition, or the value is our of range.
5446 <li>$VARIABLE is not available for the input method.
5447 <li>$LANGUAGE and $NAME do not specify an existing input method.
5451 minput_get_variable (), minput_save_config (). */
5453 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5455 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5456 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5458 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5459 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5460 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5462 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5463 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5465 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5466 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5468 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5469 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5471 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5472 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5474 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5475 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5476 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5477 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5481 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5483 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5484 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5485 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5489 minput_get_commands (), minput_save_config ().
5492 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5495 MInputMethodInfo *im_info, *config;
5500 im_info = get_im_info (language, name, Mnil, Mvariable);
5502 MERROR (MERROR_IM, -1);
5503 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5505 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5506 MERROR (MERROR_IM, -1);
5508 if (value && ! MPLIST_TAIL_P (value))
5510 plist = MPLIST_PLIST (plist);
5511 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5512 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5513 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5514 if (MPLIST_KEY (plist) != Mt
5515 && ! check_variable_value (value, plist))
5516 MERROR (MERROR_IM, -1);
5519 config = get_config_info (im_info);
5522 if (! im_config_list)
5523 im_config_list = mplist ();
5524 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5525 config->cmds = mplist ();
5526 config->vars = mplist ();
5529 if (! value && MPLIST_TAIL_P (config->vars))
5530 /* Nothing to do. */
5533 if (variable == Mnil)
5537 /* Cancel the configuration. */
5538 if (MPLIST_TAIL_P (config->vars))
5540 mplist_set (config->vars, Mnil, NULL);
5544 /* Cancel the customization. */
5545 MInputMethodInfo *custom = get_custom_info (im_info);
5547 if (MPLIST_TAIL_P (config->vars)
5548 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5549 /* Nothing to do. */
5551 mplist_set (config->vars, Mnil, NULL);
5552 MPLIST_DO (plist, custom->vars)
5554 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5556 mplist_add (plist, Msymbol, variable);
5557 mplist_push (config->vars, Mplist, plist);
5558 M17N_OBJECT_UNREF (plist);
5564 plist = mplist__assq (config->vars, variable);
5567 /* Cancel the configuration. */
5570 mplist__pop_unref (plist);
5572 else if (MPLIST_TAIL_P (value))
5574 /* Cancel the customization. */
5575 MInputMethodInfo *custom = get_custom_info (im_info);
5576 int no_custom = (! custom || ! custom->vars
5577 || ! mplist__assq (custom->vars, variable));
5583 mplist_add (config->vars, Mplist, plist);
5584 M17N_OBJECT_UNREF (plist);
5585 plist = mplist_add (plist, Msymbol, variable);
5590 mplist__pop_unref (plist);
5593 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5594 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5595 mplist_set (plist, Mnil ,NULL);
5603 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5604 if (! MPLIST_TAIL_P (plist))
5605 mplist_set (plist, Mnil, NULL);
5610 mplist_add (config->vars, Mplist, plist);
5611 M17N_OBJECT_UNREF (plist);
5612 plist = mplist_add (plist, Msymbol, variable);
5613 plist = MPLIST_NEXT (plist);
5615 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5618 config_all_variables (im_info);
5619 im_info->tick = time (NULL);
5626 @brief Get the name of per-user customization file.
5628 The minput_config_file () function returns the absolute path name
5629 of per-user customization file into which minput_save_config ()
5630 save configurations. It is usually @c config.mic under the
5631 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5632 directory). It is not assured that the file of the returned name
5633 exists nor is readable/writable. If minput_save_config () fails
5634 and returns -1, an application program might check the file, make
5635 it writable (if possible), and try minput_save_config () again.
5639 This function returns a string. As the string is kept in the
5640 library, the caller must not modify nor free it.
5643 minput_save_config ()
5646 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5648 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5649 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5650 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5651 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5652 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5653 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5654 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5659 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5660 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5663 minput_save_config ()
5667 minput_config_file ()
5671 return mdatabase__file (im_custom_mdb);
5677 @brief Save configurations in per-user customization file.
5679 The minput_save_config () function saves the configurations done
5680 so far in the current session into the per-user customization
5685 If the operation was successful, 1 is returned. If the per-user
5686 customization file is currently locked, 0 is returned. In that
5687 case, the caller may wait for a while and try again. If the
5688 configuration file is not writable, -1 is returned. In that case,
5689 the caller may check the name of the file by calling
5690 minput_config_file (), make it writable if possible, and try
5694 minput_config_file () */
5696 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5698 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5699 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5703 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5704 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5705 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5706 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5710 minput_config_file () */
5713 minput_save_config (void)
5715 MPlist *data, *tail, *plist, *p, *elt;
5719 ret = mdatabase__lock (im_custom_mdb);
5722 if (! im_config_list)
5724 update_custom_info ();
5725 if (! im_custom_list)
5726 im_custom_list = mplist ();
5728 /* At first, reflect configuration in customization. */
5729 MPLIST_DO (plist, im_config_list)
5731 MPlist *pl = MPLIST_PLIST (plist);
5732 MSymbol language, name, extra, command, variable;
5733 MInputMethodInfo *custom, *config;
5735 language = MPLIST_SYMBOL (pl);
5736 pl = MPLIST_NEXT (pl);
5737 name = MPLIST_SYMBOL (pl);
5738 pl = MPLIST_NEXT (pl);
5739 extra = MPLIST_SYMBOL (pl);
5740 pl = MPLIST_NEXT (pl);
5741 config = MPLIST_VAL (pl);
5742 custom = get_custom_info (config);
5744 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5746 MPLIST_DO (pl, config->cmds)
5748 elt = MPLIST_PLIST (pl);
5749 command = MPLIST_SYMBOL (elt);
5751 p = mplist__assq (custom->cmds, command);
5753 custom->cmds = mplist (), p = NULL;
5754 elt = MPLIST_NEXT (elt);
5757 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5758 mplist_set (p, Mnil, NULL);
5763 mplist_add (custom->cmds, Mplist, p);
5764 M17N_OBJECT_UNREF (p);
5765 mplist_add (p, Msymbol, command);
5766 p = mplist_add (p, Msymbol, Mnil);
5767 p = MPLIST_NEXT (p);
5769 mplist__conc (p, elt);
5772 MPLIST_DO (pl, config->vars)
5774 elt = MPLIST_PLIST (pl);
5775 variable = MPLIST_SYMBOL (elt);
5777 p = mplist__assq (custom->vars, variable);
5779 custom->vars = mplist (), p = NULL;
5780 elt = MPLIST_NEXT (elt);
5783 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5784 mplist_set (p, Mnil, NULL);
5789 mplist_add (custom->vars, Mplist, p);
5790 M17N_OBJECT_UNREF (p);
5791 mplist_add (p, Msymbol, variable);
5792 p = mplist_add (p, Msymbol, Mnil);
5793 p = MPLIST_NEXT (p);
5795 mplist__conc (p, elt);
5798 free_im_list (im_config_list);
5799 im_config_list = NULL;
5801 /* Next, reflect customization to the actual plist to be written. */
5802 data = tail = mplist ();
5803 MPLIST_DO (plist, im_custom_list)
5805 MPlist *pl = MPLIST_PLIST (plist);
5806 MSymbol language, name, extra;
5807 MInputMethodInfo *custom, *im_info;
5809 language = MPLIST_SYMBOL (pl);
5810 pl = MPLIST_NEXT (pl);
5811 name = MPLIST_SYMBOL (pl);
5812 pl = MPLIST_NEXT (pl);
5813 extra = MPLIST_SYMBOL (pl);
5814 pl = MPLIST_NEXT (pl);
5815 custom = MPLIST_VAL (pl);
5816 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5817 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5819 im_info = lookup_im_info (im_info_list, language, name, extra);
5823 config_all_commands (im_info);
5825 config_all_variables (im_info);
5829 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5831 MPLIST_DO (p, custom->cmds)
5832 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5834 if (! MPLIST_TAIL_P (p))
5838 mplist_add (elt, Mplist, pl);
5839 M17N_OBJECT_UNREF (pl);
5840 pl = mplist_add (pl, Msymbol, Mcommand);
5841 MPLIST_DO (p, custom->cmds)
5842 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5843 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5846 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5848 MPLIST_DO (p, custom->vars)
5849 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5851 if (! MPLIST_TAIL_P (p))
5856 mplist_add (elt, Mplist, pl);
5857 M17N_OBJECT_UNREF (pl);
5858 pl = mplist_add (pl, Msymbol, Mvariable);
5859 MPLIST_DO (p, custom->vars)
5860 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5861 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5867 mplist_push (elt, Mplist, pl);
5868 M17N_OBJECT_UNREF (pl);
5869 pl = mplist_add (pl, Msymbol, Minput_method);
5870 pl = mplist_add (pl, Msymbol, language);
5871 pl = mplist_add (pl, Msymbol, name);
5873 pl = mplist_add (pl, Msymbol, extra);
5874 tail = mplist_add (tail, Mplist, elt);
5875 M17N_OBJECT_UNREF (elt);
5879 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5880 ret = mdatabase__save (im_custom_mdb, data);
5881 mdatabase__unlock (im_custom_mdb);
5882 M17N_OBJECT_UNREF (data);
5883 return (ret < 0 ? -1 : 1);
5890 @name Obsolete functions
5893 @name Obsolete ¤Ê´Ø¿ô
5899 @brief Get a list of variables of an input method (obsolete).
5901 This function is obsolete. Use minput_get_variable () instead.
5903 The minput_get_variables () function returns a plist (#MPlist) of
5904 variables used to control the behavior of the input method
5905 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5906 (@ref m17nPlist) of the following format:
5909 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5910 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5914 @c VARNAME is a symbol representing the variable name.
5916 @c DOC-MTEXT is an M-text describing the variable.
5918 @c DEFAULT-VALUE is the default value of the variable. It is a
5919 symbol, integer, or M-text.
5921 @c VALUEs (if any) specifies the possible values of the variable.
5922 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5923 @c TO), where @c FROM and @c TO specifies a range of possible
5926 For instance, suppose an input method has the variables:
5928 @li name:intvar, description:"value is an integer",
5929 initial value:0, value-range:0..3,10,20
5931 @li name:symvar, description:"value is a symbol",
5932 initial value:nil, value-range:a, b, c, nil
5934 @li name:txtvar, description:"value is an M-text",
5935 initial value:empty text, no value-range (i.e. any text)
5937 Then, the returned plist is as follows.
5940 (intvar ("value is an integer" 0 (0 3) 10 20)
5941 symvar ("value is a symbol" nil a b c nil)
5942 txtvar ("value is an M-text" ""))
5946 If the input method uses any variables, a pointer to #MPlist is
5947 returned. As the plist is kept in the library, the caller must not
5948 modify nor free it. If the input method does not use any
5949 variable, @c NULL is returned. */
5951 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5953 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5954 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5955 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5959 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5960 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5964 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5966 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5968 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5971 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5972 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5973 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5975 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5977 @li name:intvar, ÀâÌÀ:"value is an integer",
5978 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5980 @li name:symvar, ÀâÌÀ:"value is a symbol",
5981 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5983 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5984 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5986 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5989 (intvar ("value is an integer" 0 (0 3) 10 20)
5990 symvar ("value is a symbol" nil a b c nil)
5991 txtvar ("value is an M-text" ""))
5995 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5996 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5997 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
6000 minput_get_variables (MSymbol language, MSymbol name)
6002 MInputMethodInfo *im_info;
6007 im_info = get_im_info (language, name, Mnil, Mvariable);
6008 if (! im_info || ! im_info->configured_vars)
6011 M17N_OBJECT_UNREF (im_info->bc_vars);
6012 im_info->bc_vars = mplist ();
6013 MPLIST_DO (vars, im_info->configured_vars)
6015 MPlist *plist = MPLIST_PLIST (vars);
6016 MPlist *elt = mplist ();
6018 mplist_push (im_info->bc_vars, Mplist, elt);
6019 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6020 elt = MPLIST_NEXT (elt);
6021 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6022 M17N_OBJECT_UNREF (elt);
6024 return im_info->bc_vars;
6030 @brief Set the initial value of an input method variable.
6032 The minput_set_variable () function sets the initial value of
6033 input method variable $VARIABLE to $VALUE for the input method
6034 specified by $LANGUAGE and $NAME.
6036 By default, the initial value is 0.
6038 This setting gets effective in a newly opened input method.
6041 If the operation was successful, 0 is returned. Otherwise -1 is
6042 returned, and #merror_code is set to #MERROR_IM. */
6044 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6046 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6047 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6048 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6050 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6052 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6055 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6056 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6059 minput_set_variable (MSymbol language, MSymbol name,
6060 MSymbol variable, void *value)
6063 MInputMethodInfo *im_info;
6068 if (variable == Mnil)
6069 MERROR (MERROR_IM, -1);
6070 plist = minput_get_variable (language, name, variable);
6071 plist = MPLIST_PLIST (plist);
6072 plist = MPLIST_NEXT (plist);
6074 mplist_add (pl, MPLIST_KEY (plist), value);
6075 ret = minput_config_variable (language, name, variable, pl);
6076 M17N_OBJECT_UNREF (pl);
6079 im_info = get_im_info (language, name, Mnil, Mvariable);
6088 @brief Get information about input method commands.
6090 The minput_get_commands () function returns information about
6091 input method commands of the input method specified by $LANGUAGE
6092 and $NAME. An input method command is a pseudo key event to which
6093 one or more actual input key sequences are assigned.
6095 There are two kinds of commands, global and local. Global
6096 commands are used by multiple input methods for the same purpose,
6097 and have global key assignments. Local commands are used only by
6098 a specific input method, and have only local key assignments.
6100 Each input method may locally change key assignments for global
6101 commands. The global key assignment for a global command is
6102 effective only when the current input method does not have local
6103 key assignments for that command.
6105 If $NAME is #Mnil, information about global commands is returned.
6106 In this case $LANGUAGE is ignored.
6108 If $NAME is not #Mnil, information about those commands that have
6109 local key assignments in the input method specified by $LANGUAGE
6110 and $NAME is returned.
6113 If no input method commands are found, this function returns @c NULL.
6115 Otherwise, a pointer to a plist is returned. The key of each
6116 element in the plist is a symbol representing a command, and the
6117 value is a plist of the form COMMAND-INFO described below.
6119 The first element of COMMAND-INFO has the key #Mtext, and the
6120 value is an M-text describing the command.
6122 If there are no more elements, that means no key sequences are
6123 assigned to the command. Otherwise, each of the remaining
6124 elements has the key #Mplist, and the value is a plist whose keys are
6125 #Msymbol and values are symbols representing input keys, which are
6126 currently assigned to the command.
6128 As the returned plist is kept in the library, the caller must not
6129 modify nor free it. */
6131 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6133 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6134 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6135 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6136 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6138 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6139 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6140 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6141 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6143 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6144 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6145 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6148 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6149 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6151 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6152 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6156 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6158 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6159 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6160 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6162 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6163 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6164 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6167 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6168 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6169 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6170 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6171 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6173 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6174 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6177 minput_get_commands (MSymbol language, MSymbol name)
6179 MInputMethodInfo *im_info;
6184 im_info = get_im_info (language, name, Mnil, Mcommand);
6185 if (! im_info || ! im_info->configured_vars)
6187 M17N_OBJECT_UNREF (im_info->bc_cmds);
6188 im_info->bc_cmds = mplist ();
6189 MPLIST_DO (cmds, im_info->configured_cmds)
6191 MPlist *plist = MPLIST_PLIST (cmds);
6192 MPlist *elt = mplist ();
6194 mplist_push (im_info->bc_cmds, Mplist, elt);
6195 mplist_add (elt, MPLIST_SYMBOL (plist),
6196 mplist_copy (MPLIST_NEXT (plist)));
6197 M17N_OBJECT_UNREF (elt);
6199 return im_info->bc_cmds;
6205 @brief Assign a key sequence to an input method command (obsolete).
6207 This function is obsolete. Use minput_config_command () instead.
6209 The minput_assign_command_keys () function assigns input key
6210 sequence $KEYSEQ to input method command $COMMAND for the input
6211 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6212 key sequence is assigned globally no matter what $LANGUAGE is.
6213 Otherwise the key sequence is assigned locally.
6215 Each element of $KEYSEQ must have the key $Msymbol and the value
6216 must be a symbol representing an input key.
6218 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6219 globally or locally.
6221 This assignment gets effective in a newly opened input method.
6224 If the operation was successful, 0 is returned. Otherwise -1 is
6225 returned, and #merror_code is set to #MERROR_IM. */
6227 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6229 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6230 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6231 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6232 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6233 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6235 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6236 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6238 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6239 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6241 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6245 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6246 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6249 minput_assign_command_keys (MSymbol language, MSymbol name,
6250 MSymbol command, MPlist *keyseq)
6256 if (command == Mnil)
6257 MERROR (MERROR_IM, -1);
6262 if (! check_command_keyseq (keyseq))
6263 MERROR (MERROR_IM, -1);
6265 mplist_add (plist, Mplist, keyseq);
6270 ret = minput_config_command (language, name, command, keyseq);
6271 M17N_OBJECT_UNREF (keyseq);
6278 @brief Call a callback function
6280 The minput_callback () functions calls a callback function
6281 $COMMAND assigned for the input context $IC. The caller must set
6282 specific elements in $IC->plist if the callback function requires.
6285 If there exists a specified callback function, 0 is returned.
6286 Otherwise -1 is returned. By side effects, $IC->plist may be
6290 minput_callback (MInputContext *ic, MSymbol command)
6292 MInputCallbackFunc func;
6294 if (! ic->im->driver.callback_list)
6296 func = ((MInputCallbackFunc)
6297 mplist_get_func (ic->im->driver.callback_list, command));
6300 (func) (ic, command);
6307 /*** @addtogroup m17nDebug */
6313 @brief Dump an input method.
6315 The mdebug_dump_im () function prints the input method $IM in a
6316 human readable way to the stderr. $INDENT specifies how many
6317 columns to indent the lines but the first one.
6320 This function returns $IM. */
6322 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6324 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6325 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6328 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6331 mdebug_dump_im (MInputMethod *im, int indent)
6333 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6336 prefix = (char *) alloca (indent + 1);
6337 memset (prefix, 32, indent);
6338 prefix[indent] = '\0';
6340 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6341 msymbol_name (im->name));
6342 mdebug_dump_mtext (im_info->title, 0, 0);
6343 if (im->name != Mnil)
6347 MPLIST_DO (state, im_info->states)
6349 fprintf (stderr, "\n%s ", prefix);
6350 dump_im_state (MPLIST_VAL (state), indent + 2);
6353 fprintf (stderr, ")");