1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
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. The plist must
541 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
543 MPlist *plist = mplist__assq (ic_info->vars, var);
547 plist = MPLIST_PLIST (plist);
548 return MPLIST_NEXT (plist);
552 mplist_push (ic_info->vars, Mplist, plist);
553 M17N_OBJECT_UNREF (plist);
554 plist = mplist_add (plist, Msymbol, var);
555 plist = mplist_add (plist, Minteger, (void *) 0);
560 get_surrounding_text (MInputContext *ic, int len)
564 mplist_push (ic->plist, Minteger, (void *) len);
565 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
566 && MPLIST_MTEXT_P (ic->plist))
567 mt = MPLIST_MTEXT (ic->plist);
568 mplist_pop (ic->plist);
573 delete_surrounding_text (MInputContext *ic, int pos)
575 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
577 mplist_push (ic->plist, Minteger, (void *) pos);
578 minput_callback (ic, Minput_delete_surrounding_text);
579 mplist_pop (ic->plist);
582 M17N_OBJECT_UNREF (ic_info->preceding_text);
583 ic_info->preceding_text = NULL;
587 M17N_OBJECT_UNREF (ic_info->following_text);
588 ic_info->following_text = NULL;
593 get_preceding_char (MInputContext *ic, int pos)
595 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
599 if (pos && ic_info->preceding_text)
601 len = mtext_nchars (ic_info->preceding_text);
603 return mtext_ref_char (ic_info->preceding_text, len - pos);
605 mt = get_surrounding_text (ic, - pos);
608 len = mtext_nchars (mt);
609 if (ic_info->preceding_text)
611 if (mtext_nchars (ic_info->preceding_text) < len)
613 M17N_OBJECT_UNREF (ic_info->preceding_text);
614 ic_info->preceding_text = mt;
617 M17N_OBJECT_UNREF (mt);
620 ic_info->preceding_text = mt;
623 return mtext_ref_char (ic_info->preceding_text, len - pos);
627 get_following_char (MInputContext *ic, int pos)
629 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
633 if (ic_info->following_text)
635 len = mtext_nchars (ic_info->following_text);
637 return mtext_ref_char (ic_info->following_text, pos);
639 mt = get_surrounding_text (ic, pos + 1);
642 len = mtext_nchars (mt);
643 if (ic_info->following_text)
645 if (mtext_nchars (ic_info->following_text) < len)
647 M17N_OBJECT_UNREF (ic_info->following_text);
648 ic_info->following_text = mt;
651 M17N_OBJECT_UNREF (mt);
654 ic_info->following_text = mt;
657 return mtext_ref_char (ic_info->following_text, pos);
661 surrounding_pos (MSymbol sym)
667 name = MSYMBOL_NAME (sym);
669 && (name[1] == '-' || name[1] == '+')
670 && name[2] >= '1' && name[2] <= '9')
671 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
676 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
678 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
680 MText *preedit = ic->preedit;
681 int len = mtext_nchars (preedit);
683 if (MPLIST_INTEGER_P (arg))
684 return MPLIST_INTEGER (arg);
686 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
689 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
691 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
694 return ic_info->key_head;
695 if ((code == '-' || code == '+'))
697 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
701 pos = atoi (name + 1);
703 return get_preceding_char (ic, 0);
705 pos = ic->cursor_pos + pos;
707 pos = ic->cursor_pos + pos - 1;
710 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
711 return mtext_ref_char (ic->produced,
712 mtext_len (ic->produced) + pos);
713 return get_preceding_char (ic, - pos);
716 return get_following_char (ic, pos - len);
719 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
721 else if (code >= '0' && code <= '9')
723 else if (code == '=')
724 pos = ic->cursor_pos;
725 else if (code == '[')
726 pos = ic->cursor_pos - 1;
727 else if (code == ']')
728 pos = ic->cursor_pos + 1;
729 else if (code == '<')
731 else if (code == '>')
733 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
737 parse_expression (MPlist *plist)
741 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
743 if (! MPLIST_PLIST_P (plist))
745 plist = MPLIST_PLIST (plist);
746 op = MPLIST_SYMBOL (plist);
747 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
748 && op != Mand && op != Mor && op != Mnot
749 && op != Mless && op != Mgreater && op != Mequal
750 && op != Mless_equal && op != Mgreater_equal)
751 MERROR (MERROR_IM, -1);
752 MPLIST_DO (plist, MPLIST_NEXT (plist))
753 if (parse_expression (plist) < 0)
759 resolve_expression (MInputContext *ic, MPlist *plist)
764 if (MPLIST_INTEGER_P (plist))
765 return MPLIST_INTEGER (plist);
766 if (MPLIST_SYMBOL_P (plist))
767 return integer_value (ic, plist, 1);
768 if (! MPLIST_PLIST_P (plist))
770 plist = MPLIST_PLIST (plist);
771 if (! MPLIST_SYMBOL_P (plist))
773 op = MPLIST_SYMBOL (plist);
774 plist = MPLIST_NEXT (plist);
775 val = resolve_expression (ic, plist);
777 MPLIST_DO (plist, MPLIST_NEXT (plist))
778 val += resolve_expression (ic, plist);
779 else if (op == Mminus)
780 MPLIST_DO (plist, MPLIST_NEXT (plist))
781 val -= resolve_expression (ic, plist);
782 else if (op == Mstar)
783 MPLIST_DO (plist, MPLIST_NEXT (plist))
784 val *= resolve_expression (ic, plist);
785 else if (op == Mslash)
786 MPLIST_DO (plist, MPLIST_NEXT (plist))
787 val /= resolve_expression (ic, plist);
789 MPLIST_DO (plist, MPLIST_NEXT (plist))
790 val &= resolve_expression (ic, plist);
792 MPLIST_DO (plist, MPLIST_NEXT (plist))
793 val |= resolve_expression (ic, plist);
796 else if (op == Mless)
797 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
798 else if (op == Mequal)
799 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
800 else if (op == Mgreater)
801 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
802 else if (op == Mless_equal)
803 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
804 else if (op == Mgreater_equal)
805 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
809 /* Parse PLIST as an action list. PLIST should have this form:
810 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
811 Return 0 if successfully parsed, otherwise return -1. */
814 parse_action_list (MPlist *plist, MPlist *macros)
816 MPLIST_DO (plist, plist)
818 if (MPLIST_MTEXT_P (plist))
820 /* This is a short form of (insert MTEXT). */
821 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
822 MERROR (MERROR_IM, -1); */
824 else if (MPLIST_PLIST_P (plist)
825 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
826 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
830 /* This is a short form of (insert (GROUPS *)). */
831 MPLIST_DO (pl, MPLIST_PLIST (plist))
833 if (MPLIST_PLIST_P (pl))
837 MPLIST_DO (elt, MPLIST_PLIST (pl))
838 if (! MPLIST_MTEXT_P (elt)
839 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
840 MERROR (MERROR_IM, -1);
844 if (! MPLIST_MTEXT_P (pl)
845 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
846 MERROR (MERROR_IM, -1);
850 else if (MPLIST_INTEGER_P (plist))
852 int c = MPLIST_INTEGER (plist);
854 if (c < 0 || c > MCHAR_MAX)
855 MERROR (MERROR_IM, -1);
857 else if (MPLIST_PLIST_P (plist)
858 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
860 MPlist *pl = MPLIST_PLIST (plist);
861 MSymbol action_name = MPLIST_SYMBOL (pl);
863 pl = MPLIST_NEXT (pl);
865 if (action_name == M_candidates)
867 /* This is an already regularised action. */
870 if (action_name == Minsert)
872 if (MPLIST_MTEXT_P (pl))
874 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
875 MERROR (MERROR_IM, -1);
877 else if (MPLIST_INTEGER_P (pl))
879 int c = MPLIST_INTEGER (pl);
881 if (c < 0 || c > MCHAR_MAX)
882 MERROR (MERROR_IM, -1);
884 else if (MPLIST_PLIST_P (pl))
886 MPLIST_DO (pl, MPLIST_PLIST (pl))
888 if (MPLIST_PLIST_P (pl))
892 MPLIST_DO (elt, MPLIST_PLIST (pl))
893 if (! MPLIST_MTEXT_P (elt)
894 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
895 MERROR (MERROR_IM, -1);
899 if (! MPLIST_MTEXT_P (pl)
900 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
901 MERROR (MERROR_IM, -1);
905 else if (! MPLIST_SYMBOL_P (pl))
906 MERROR (MERROR_IM, -1);
908 else if (action_name == Mselect
909 || action_name == Mdelete
910 || action_name == Mmove)
912 if (parse_expression (pl) < 0)
915 else if (action_name == Mmark
916 || action_name == Mcall
917 || action_name == Mshift)
919 if (! MPLIST_SYMBOL_P (pl))
920 MERROR (MERROR_IM, -1);
922 else if (action_name == Mundo)
924 if (! MPLIST_TAIL_P (pl))
926 if (! MPLIST_SYMBOL_P (pl)
927 && ! MPLIST_INTEGER_P (pl))
928 MERROR (MERROR_IM, -1);
931 else if (action_name == Mpushback)
933 if (MPLIST_MTEXT_P (pl))
935 MText *mt = MPLIST_MTEXT (pl);
937 if (mtext_nchars (mt) != mtext_nbytes (mt))
938 MERROR (MERROR_IM, -1);
940 else if (MPLIST_PLIST_P (pl))
944 MPLIST_DO (p, MPLIST_PLIST (pl))
945 if (! MPLIST_SYMBOL_P (p))
946 MERROR (MERROR_IM, -1);
948 else if (! MPLIST_INTEGER_P (pl))
949 MERROR (MERROR_IM, -1);
951 else if (action_name == Mset || action_name == Madd
952 || action_name == Msub || action_name == Mmul
953 || action_name == Mdiv)
955 if (! MPLIST_SYMBOL_P (pl))
956 MERROR (MERROR_IM, -1);
957 if (parse_expression (MPLIST_NEXT (pl)) < 0)
960 else if (action_name == Mequal || action_name == Mless
961 || action_name == Mgreater || action_name == Mless_equal
962 || action_name == Mgreater_equal)
964 if (parse_expression (pl) < 0
965 || parse_expression (MPLIST_NEXT (pl)) < 0)
967 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
968 if (! MPLIST_PLIST_P (pl))
969 MERROR (MERROR_IM, -1);
970 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
971 MERROR (MERROR_IM, -1);
972 pl = MPLIST_NEXT (pl);
973 if (MPLIST_PLIST_P (pl)
974 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
975 MERROR (MERROR_IM, -1);
977 else if (action_name == Mshow || action_name == Mhide
978 || action_name == Mcommit || action_name == Munhandle
979 || action_name == Mpop)
981 else if (action_name == Mcond)
984 if (! MPLIST_PLIST_P (pl))
985 MERROR (MERROR_IM, -1);
987 else if (! macros || ! mplist_get (macros, action_name))
988 MERROR (MERROR_IM, -1);
990 else if (! MPLIST_SYMBOL_P (plist))
991 MERROR (MERROR_IM, -1);
998 resolve_command (MPlist *cmds, MSymbol command)
1002 if (! cmds || ! (plist = mplist__assq (cmds, command)))
1004 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
1005 plist = MPLIST_NEXT (plist);
1006 plist = MPLIST_NEXT (plist);
1007 plist = MPLIST_NEXT (plist);
1011 /* Load a translation into MAP from PLIST.
1012 PLIST has this form:
1013 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
1016 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
1017 MPlist *branch_actions, MPlist *macros)
1022 if (MPLIST_MTEXT_P (keylist))
1024 MText *mt = MPLIST_MTEXT (keylist);
1026 len = mtext_nchars (mt);
1027 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
1029 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1030 for (i = 0; i < len; i++)
1031 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1037 if (MFAILP (MPLIST_PLIST_P (keylist)))
1039 elt = MPLIST_PLIST (keylist);
1040 len = MPLIST_LENGTH (elt);
1041 if (MFAILP (len > 0))
1043 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1044 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1046 if (MPLIST_INTEGER_P (elt))
1048 int c = MPLIST_INTEGER (elt);
1050 if (MFAILP (c >= 0 && c < 0x100))
1052 keyseq[i] = one_char_symbol[c];
1056 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1058 keyseq[i] = MPLIST_SYMBOL (elt);
1063 for (i = 0; i < len; i++)
1065 MIMMap *deeper = NULL;
1068 deeper = mplist_get (map->submaps, keyseq[i]);
1070 map->submaps = mplist ();
1073 /* Fixme: It is better to make all deeper maps at once. */
1074 MSTRUCT_CALLOC (deeper, MERROR_IM);
1075 mplist_put (map->submaps, keyseq[i], deeper);
1080 /* We reach a terminal map. */
1081 if (map->map_actions
1082 || map->branch_actions)
1083 /* This map is already defined. We avoid overriding it. */
1086 if (! MPLIST_TAIL_P (map_actions))
1088 if (parse_action_list (map_actions, macros) < 0)
1089 MERROR (MERROR_IM, -1);
1090 map->map_actions = map_actions;
1094 map->branch_actions = branch_actions;
1095 M17N_OBJECT_REF (branch_actions);
1101 /* Load a branch from PLIST into MAP. PLIST has this form:
1102 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1105 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1108 MPlist *branch_actions;
1110 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1112 map_name = MPLIST_SYMBOL (plist);
1113 plist = MPLIST_NEXT (plist);
1114 if (MPLIST_TAIL_P (plist))
1115 branch_actions = NULL;
1116 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1119 branch_actions = plist;
1120 if (map_name == Mnil)
1122 map->branch_actions = branch_actions;
1124 M17N_OBJECT_REF (branch_actions);
1126 else if (map_name == Mt)
1128 map->map_actions = branch_actions;
1130 M17N_OBJECT_REF (branch_actions);
1132 else if (im_info->maps)
1134 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1135 if (! plist && im_info->configured_vars)
1137 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1139 if (p && MPLIST_PLIST_P (p))
1141 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1142 if (MPLIST_SYMBOL_P (p))
1143 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1148 MPLIST_DO (plist, plist)
1150 MPlist *keylist, *map_actions;
1152 if (! MPLIST_PLIST_P (plist))
1153 MERROR (MERROR_IM, -1);
1154 keylist = MPLIST_PLIST (plist);
1155 map_actions = MPLIST_NEXT (keylist);
1156 if (MPLIST_SYMBOL_P (keylist))
1158 MSymbol command = MPLIST_SYMBOL (keylist);
1161 if (MFAILP (command != Mat_reload))
1163 pl = resolve_command (im_info->configured_cmds, command);
1167 load_translation (map, pl, map_actions, branch_actions,
1171 load_translation (map, keylist, map_actions, branch_actions,
1180 /* Load a macro from PLIST into IM_INFO->macros.
1181 PLIST has this form:
1182 PLIST ::= ( MACRO-NAME ACTION * )
1183 IM_INFO->macros is a plist of macro names vs action list. */
1186 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1191 if (! MPLIST_SYMBOL_P (plist))
1192 MERROR (MERROR_IM, -1);
1193 name = MPLIST_SYMBOL (plist);
1194 plist = MPLIST_NEXT (plist);
1195 if (MFAILP (! MPLIST_TAIL_P (plist)))
1196 MERROR (MERROR_IM, -1);
1197 pl = mplist_get (im_info->macros, name);
1198 M17N_OBJECT_UNREF (pl);
1199 mplist_put (im_info->macros, name, plist);
1200 M17N_OBJECT_REF (plist);
1204 /* Load an external module from PLIST 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 if (im_info->macros)
2385 MPLIST_DO (pl, im_info->macros)
2386 parse_action_list (MPLIST_PLIST (pl), im_info->macros);
2389 im_info->tick = time (NULL);
2394 static int take_action_list (MInputContext *ic, MPlist *action_list);
2395 static void preedit_commit (MInputContext *ic, int need_prefix);
2398 shift_state (MInputContext *ic, MSymbol state_name)
2400 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2401 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2402 MIMState *orig_state = ic_info->state, *state;
2404 /* Find a state to shift to. If not found, shift to the initial
2406 if (state_name == Mt)
2408 if (! ic_info->prev_state)
2410 state = ic_info->prev_state;
2412 else if (state_name == Mnil)
2414 state = (MIMState *) MPLIST_VAL (im_info->states);
2418 state = (MIMState *) mplist_get (im_info->states, state_name);
2420 state = (MIMState *) MPLIST_VAL (im_info->states);
2426 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2427 MSYMBOL_NAME (orig_state->name),
2428 MSYMBOL_NAME (state->name));
2430 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2433 /* Enter the new state. */
2434 ic_info->state = state;
2435 ic_info->map = state->map;
2436 ic_info->state_key_head = ic_info->key_head;
2437 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2439 /* We have shifted to the initial state. */
2440 preedit_commit (ic, 0);
2441 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2442 ic_info->state_pos = ic->cursor_pos;
2443 if (state != orig_state)
2445 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2447 /* Shifted to the initial state. */
2448 ic_info->prev_state = NULL;
2449 M17N_OBJECT_UNREF (ic_info->vars_saved);
2450 ic_info->vars_saved = mplist_copy (ic_info->vars);
2453 ic_info->prev_state = orig_state;
2456 ic->status = state->title;
2458 ic->status = im_info->title;
2459 ic->status_changed = 1;
2460 if (ic_info->map == ic_info->state->map
2461 && ic_info->map->map_actions)
2463 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2464 MSYMBOL_NAME (state->name));
2465 take_action_list (ic, ic_info->map->map_actions);
2470 /* Find a candidate group that contains a candidate number INDEX from
2471 PLIST. Set START_INDEX to the first candidate number of the group,
2472 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2473 candidate group number if they are non-NULL. If INDEX is -1, find
2474 the last candidate group. */
2477 find_candidates_group (MPlist *plist, int index,
2478 int *start_index, int *end_index, int *group_index)
2480 int i = 0, gidx = 0, len;
2482 MPLIST_DO (plist, plist)
2484 if (MPLIST_MTEXT_P (plist))
2485 len = mtext_nchars (MPLIST_MTEXT (plist));
2487 len = mplist_length (MPLIST_PLIST (plist));
2488 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2494 *end_index = i + len;
2496 *group_index = gidx;
2505 /* Adjust markers for the change of preedit text.
2506 If FROM == TO, the change is insertion of INS chars.
2507 If FROM < TO and INS == 0, the change is deletion of the range.
2508 If FROM < TO and INS > 0, the change is replacement. */
2511 adjust_markers (MInputContext *ic, int from, int to, int ins)
2513 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2518 MPLIST_DO (markers, ic_info->markers)
2519 if (MPLIST_INTEGER (markers) > from)
2520 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2521 if (ic->cursor_pos >= from)
2522 ic->cursor_pos += ins;
2526 MPLIST_DO (markers, ic_info->markers)
2528 if (MPLIST_INTEGER (markers) >= to)
2529 MPLIST_VAL (markers)
2530 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2531 else if (MPLIST_INTEGER (markers) > from)
2532 MPLIST_VAL (markers) = (void *) from;
2534 if (ic->cursor_pos >= to)
2535 ic->cursor_pos += ins - (to - from);
2536 else if (ic->cursor_pos > from)
2537 ic->cursor_pos = from;
2543 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2545 int nchars = mt ? mtext_nchars (mt) : 1;
2549 mtext_ins (ic->preedit, pos, mt);
2550 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2554 mtext_ins_char (ic->preedit, pos, c, 1);
2556 MDEBUG_PRINT1 ("('%c')", c);
2558 MDEBUG_PRINT1 ("(U+%04X)", c);
2560 adjust_markers (ic, pos, pos, nchars);
2561 ic->preedit_changed = 1;
2566 preedit_delete (MInputContext *ic, int from, int to)
2568 mtext_del (ic->preedit, from, to);
2569 adjust_markers (ic, from, to, 0);
2570 ic->preedit_changed = 1;
2574 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2578 mtext_del (ic->preedit, from, to);
2581 mtext_ins (ic->preedit, from, mt);
2582 ins = mtext_nchars (mt);
2586 mtext_ins_char (ic->preedit, from, c, 1);
2589 adjust_markers (ic, from, to, ins);
2590 ic->preedit_changed = 1;
2595 preedit_commit (MInputContext *ic, int need_prefix)
2597 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2598 int preedit_len = mtext_nchars (ic->preedit);
2600 if (preedit_len > 0)
2604 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2605 Mcandidate_list, NULL, 0);
2606 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2607 Mcandidate_index, NULL, 0);
2608 mtext_cat (ic->produced, ic->preedit);
2614 MDEBUG_PRINT1 ("\n [IM] [%s]",
2615 MSYMBOL_NAME (ic_info->state->name));
2616 MDEBUG_PRINT (" (commit");
2617 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2618 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2622 mtext_reset (ic->preedit);
2623 mtext_reset (ic_info->preedit_saved);
2624 MPLIST_DO (p, ic_info->markers)
2626 ic->cursor_pos = ic_info->state_pos = 0;
2627 ic->preedit_changed = 1;
2628 ic_info->commit_key_head = ic_info->key_head;
2630 if (ic->candidate_list)
2632 M17N_OBJECT_UNREF (ic->candidate_list);
2633 ic->candidate_list = NULL;
2634 ic->candidate_index = 0;
2635 ic->candidate_from = ic->candidate_to = 0;
2636 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2637 if (ic->candidate_show)
2639 ic->candidate_show = 0;
2640 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2646 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2648 int code = marker_code (sym, 0);
2650 if (mt && (code == '[' || code == ']'))
2654 if (code == '[' && current > 0)
2656 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2660 else if (code == ']' && current < mtext_nchars (mt))
2662 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2668 return (code == '<' ? 0
2669 : code == '>' ? limit
2670 : code == '-' ? current - 1
2671 : code == '+' ? current + 1
2672 : code == '=' ? current
2673 : code - '0' > limit ? limit
2677 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2681 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2683 int from = mtext_property_start (prop);
2684 int to = mtext_property_end (prop);
2686 MPlist *candidate_list = mtext_property_value (prop);
2687 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2689 int ingroup_index = idx - start;
2692 candidate_list = mplist_copy (candidate_list);
2693 if (MPLIST_MTEXT_P (group))
2695 mt = MPLIST_MTEXT (group);
2696 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2704 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2705 i++, plist = MPLIST_NEXT (plist));
2706 mt = MPLIST_MTEXT (plist);
2707 preedit_replace (ic, from, to, mt, 0);
2708 to = from + mtext_nchars (mt);
2710 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2711 M17N_OBJECT_UNREF (candidate_list);
2712 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2713 ic->cursor_pos = to;
2717 get_select_charset (MInputContextInfo * ic_info)
2719 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2722 if (! MPLIST_VAL (plist))
2724 sym = MPLIST_SYMBOL (plist);
2727 return MCHARSET (sym);
2730 /* The returned plist must be UNREFed. */
2733 adjust_candidates (MPlist *plist, MCharset *charset)
2737 /* plist ::= MTEXT ... | PLIST ... */
2738 plist = mplist_copy (plist);
2739 if (MPLIST_MTEXT_P (plist))
2742 while (! MPLIST_TAIL_P (pl))
2744 /* pl ::= MTEXT ... */
2745 MText *mt = MPLIST_MTEXT (pl);
2749 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2751 c = mtext_ref_char (mt, i);
2752 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2756 mt = mtext_dup (mt);
2757 mplist_set (pl, Mtext, mt);
2758 M17N_OBJECT_UNREF (mt);
2761 mtext_del (mt, i, i + 1);
2764 if (mtext_len (mt) > 0)
2765 pl = MPLIST_NEXT (pl);
2769 M17N_OBJECT_UNREF (mt);
2773 else /* MPLIST_PLIST_P (plist) */
2776 while (! MPLIST_TAIL_P (pl))
2778 /* pl ::= (MTEXT ...) ... */
2779 MPlist *p = MPLIST_PLIST (pl);
2781 /* p ::= MTEXT ... */
2785 while (! MPLIST_TAIL_P (p0))
2787 MText *mt = MPLIST_MTEXT (p0);
2790 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2792 c = mtext_ref_char (mt, i);
2793 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2798 p0 = MPLIST_NEXT (p0);
2805 p = mplist_copy (p);
2806 mplist_set (pl, Mplist, p);
2807 M17N_OBJECT_UNREF (p);
2811 p0 = MPLIST_NEXT (p0);
2814 M17N_OBJECT_UNREF (mt);
2817 if (! MPLIST_TAIL_P (p))
2818 pl = MPLIST_NEXT (pl);
2822 M17N_OBJECT_UNREF (p);
2826 if (MPLIST_TAIL_P (plist))
2828 M17N_OBJECT_UNREF (plist);
2834 /* The returned Plist must be UNREFed. */
2837 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2839 MCharset *charset = get_select_charset (ic_info);
2844 plist = resolve_variable (ic_info, Mcandidates_group_size);
2845 column = MPLIST_INTEGER (plist);
2847 plist = MPLIST_PLIST (args);
2852 plist = adjust_candidates (plist, charset);
2857 M17N_OBJECT_REF (plist);
2862 if (MPLIST_MTEXT_P (plist))
2864 MText *mt = MPLIST_MTEXT (plist);
2865 MPlist *next = MPLIST_NEXT (plist);
2867 if (MPLIST_TAIL_P (next))
2868 M17N_OBJECT_REF (mt);
2871 mt = mtext_dup (mt);
2872 while (! MPLIST_TAIL_P (next))
2874 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2875 next = MPLIST_NEXT (next);
2878 M17N_OBJECT_UNREF (plist);
2880 len = mtext_nchars (mt);
2882 mplist_add (plist, Mtext, mt);
2885 for (i = 0; i < len; i += column)
2887 int to = (i + column < len ? i + column : len);
2888 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2890 mplist_add (plist, Mtext, sub);
2891 M17N_OBJECT_UNREF (sub);
2894 M17N_OBJECT_UNREF (mt);
2896 else if (MPLIST_PLIST_P (plist))
2898 MPlist *tail = plist;
2899 MPlist *new = mplist ();
2900 MPlist *this = mplist ();
2903 MPLIST_DO (tail, tail)
2905 MPlist *p = MPLIST_PLIST (tail);
2909 MText *mt = MPLIST_MTEXT (p);
2911 if (count == column)
2913 mplist_add (new, Mplist, this);
2914 M17N_OBJECT_UNREF (this);
2918 mplist_add (this, Mtext, mt);
2922 mplist_add (new, Mplist, this);
2923 M17N_OBJECT_UNREF (this);
2924 mplist_set (plist, Mnil, NULL);
2925 MPLIST_DO (tail, new)
2927 MPlist *elt = MPLIST_PLIST (tail);
2929 mplist_add (plist, Mplist, elt);
2931 M17N_OBJECT_UNREF (new);
2939 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2941 MPlist *action = NULL;
2945 if (MPLIST_SYMBOL_P (action_list))
2947 MSymbol var = MPLIST_SYMBOL (action_list);
2950 MPLIST_DO (p, ic_info->vars)
2951 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2953 if (MPLIST_TAIL_P (p))
2955 action = MPLIST_NEXT (MPLIST_PLIST (p));
2956 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2959 if (MPLIST_PLIST_P (action_list))
2961 action = MPLIST_PLIST (action_list);
2962 if (MPLIST_SYMBOL_P (action))
2964 name = MPLIST_SYMBOL (action);
2965 args = MPLIST_NEXT (action);
2967 && MPLIST_PLIST_P (args))
2968 mplist_set (action, Msymbol, M_candidates);
2970 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2973 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2974 mplist_push (action, Msymbol, M_candidates);
2975 mplist_set (action_list, Mplist, action);
2976 M17N_OBJECT_UNREF (action);
2979 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2982 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2983 mplist_push (action, Msymbol, Minsert);
2984 mplist_set (action_list, Mplist, action);
2985 M17N_OBJECT_UNREF (action);
2990 /* Perform list of actions in ACTION_LIST for the current input
2991 context IC. If unhandle action was not performed, return 0.
2992 Otherwise, return -1. */
2995 take_action_list (MInputContext *ic, MPlist *action_list)
2997 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2998 MPlist *candidate_list = ic->candidate_list;
2999 int candidate_index = ic->candidate_index;
3000 int candidate_show = ic->candidate_show;
3001 MTextProperty *prop;
3003 MPLIST_DO (action_list, action_list)
3005 MPlist *action = regularize_action (action_list, ic_info);
3011 name = MPLIST_SYMBOL (action);
3012 args = MPLIST_NEXT (action);
3014 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
3015 if (name == Minsert)
3017 if (MPLIST_SYMBOL_P (args))
3019 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3020 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3023 if (MPLIST_MTEXT_P (args))
3024 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3025 else /* MPLIST_INTEGER_P (args)) */
3026 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3028 else if (name == M_candidates)
3030 MPlist *plist = get_candidate_list (ic_info, args);
3036 if (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist))
3038 M17N_OBJECT_UNREF (plist);
3041 if (MPLIST_MTEXT_P (plist))
3043 preedit_insert (ic, ic->cursor_pos, NULL,
3044 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3049 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3051 preedit_insert (ic, ic->cursor_pos, mt, 0);
3052 len = mtext_nchars (mt);
3054 pl = mplist_copy (plist);
3055 M17N_OBJECT_UNREF (plist);
3056 mtext_put_prop (ic->preedit,
3057 ic->cursor_pos - len, ic->cursor_pos,
3058 Mcandidate_list, pl);
3059 M17N_OBJECT_UNREF (pl);
3060 mtext_put_prop (ic->preedit,
3061 ic->cursor_pos - len, ic->cursor_pos,
3062 Mcandidate_index, (void *) 0);
3064 else if (name == Mselect)
3067 int code, idx, gindex;
3068 int pos = ic->cursor_pos;
3070 int idx_decided = 0;
3073 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3076 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3077 group = find_candidates_group (mtext_property_value (prop), idx,
3078 &start, &end, &gindex);
3079 if (MPLIST_SYMBOL_P (args))
3081 code = marker_code (MPLIST_SYMBOL (args), 0);
3084 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3085 if (! MPLIST_INTEGER_P (args))
3087 idx = start + MPLIST_INTEGER (args);
3088 if (idx < start || idx >= end)
3096 if (code != '[' && code != ']')
3101 ? new_index (NULL, ic->candidate_index - start,
3102 end - start - 1, MPLIST_SYMBOL (args),
3104 : MPLIST_INTEGER (args)));
3107 find_candidates_group (mtext_property_value (prop), -1,
3112 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3117 int ingroup_index = idx - start;
3120 group = mtext_property_value (prop);
3121 len = mplist_length (group);
3134 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3135 idx += (MPLIST_MTEXT_P (group)
3136 ? mtext_nchars (MPLIST_MTEXT (group))
3137 : mplist_length (MPLIST_PLIST (group)));
3138 len = (MPLIST_MTEXT_P (group)
3139 ? mtext_nchars (MPLIST_MTEXT (group))
3140 : mplist_length (MPLIST_PLIST (group)));
3141 if (ingroup_index >= len)
3142 ingroup_index = len - 1;
3143 idx += ingroup_index;
3145 update_candidate (ic, prop, idx);
3146 MDEBUG_PRINT1 ("(%d)", idx);
3148 else if (name == Mshow)
3149 ic->candidate_show = 1;
3150 else if (name == Mhide)
3151 ic->candidate_show = 0;
3152 else if (name == Mdelete)
3154 int len = mtext_nchars (ic->preedit);
3158 if (MPLIST_SYMBOL_P (args)
3159 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3161 to = ic->cursor_pos + pos;
3164 delete_surrounding_text (ic, to);
3169 delete_surrounding_text (ic, to - len);
3175 to = (MPLIST_SYMBOL_P (args)
3176 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3178 : MPLIST_INTEGER (args));
3183 pos = to - ic->cursor_pos;
3185 MDEBUG_PRINT1 ("(%d)", pos);
3186 if (to < ic->cursor_pos)
3187 preedit_delete (ic, to, ic->cursor_pos);
3188 else if (to > ic->cursor_pos)
3189 preedit_delete (ic, ic->cursor_pos, to);
3191 else if (name == Mmove)
3193 int len = mtext_nchars (ic->preedit);
3195 = (MPLIST_SYMBOL_P (args)
3196 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3198 : MPLIST_INTEGER (args));
3204 if (pos != ic->cursor_pos)
3206 ic->cursor_pos = pos;
3207 ic->preedit_changed = 1;
3209 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3211 else if (name == Mmark)
3213 int code = marker_code (MPLIST_SYMBOL (args), 0);
3217 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3218 (void *) ic->cursor_pos);
3219 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3222 else if (name == Mpushback)
3224 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3228 if (MPLIST_SYMBOL_P (args))
3230 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3231 if (MPLIST_INTEGER_P (args))
3232 num = MPLIST_INTEGER (args);
3237 num = MPLIST_INTEGER (args);
3240 ic_info->key_head -= num;
3242 ic_info->key_head = 0;
3244 ic_info->key_head = - num;
3245 if (ic_info->key_head > ic_info->used)
3246 ic_info->key_head = ic_info->used;
3248 else if (MPLIST_MTEXT_P (args))
3250 MText *mt = MPLIST_MTEXT (args);
3251 int i, len = mtext_nchars (mt);
3254 ic_info->key_head--;
3255 for (i = 0; i < len; i++)
3257 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3258 if (ic_info->key_head + i < ic_info->used)
3259 ic_info->keys[ic_info->key_head + i] = key;
3261 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3266 MPlist *plist = MPLIST_PLIST (args), *pl;
3270 ic_info->key_head--;
3272 MPLIST_DO (pl, plist)
3274 key = MPLIST_SYMBOL (pl);
3275 if (ic_info->key_head < ic_info->used)
3276 ic_info->keys[ic_info->key_head + i] = key;
3278 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3283 else if (name == Mpop)
3285 if (ic_info->key_head < ic_info->used)
3286 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3288 else if (name == Mcall)
3290 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3291 MIMExternalFunc func = NULL;
3292 MSymbol module, func_name;
3293 MPlist *func_args, *val;
3296 module = MPLIST_SYMBOL (args);
3297 args = MPLIST_NEXT (args);
3298 func_name = MPLIST_SYMBOL (args);
3300 if (im_info->externals)
3302 MIMExternalModule *external
3303 = (MIMExternalModule *) mplist_get (im_info->externals,
3306 func = ((MIMExternalFunc)
3307 mplist_get_func (external->func_list, func_name));
3311 func_args = mplist ();
3312 mplist_add (func_args, Mt, ic);
3313 MPLIST_DO (args, MPLIST_NEXT (args))
3317 if (MPLIST_KEY (args) == Msymbol
3318 && MPLIST_KEY (args) != Mnil
3319 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3321 code = new_index (ic, ic->cursor_pos,
3322 mtext_nchars (ic->preedit),
3323 MPLIST_SYMBOL (args), ic->preedit);
3324 mplist_add (func_args, Minteger, (void *) code);
3327 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3329 val = (func) (func_args);
3330 M17N_OBJECT_UNREF (func_args);
3331 if (val && ! MPLIST_TAIL_P (val))
3332 ret = take_action_list (ic, val);
3333 M17N_OBJECT_UNREF (val);
3337 else if (name == Mshift)
3339 shift_state (ic, MPLIST_SYMBOL (args));
3341 else if (name == Mundo)
3343 int intarg = (MPLIST_TAIL_P (args)
3345 : integer_value (ic, args, 0));
3347 mtext_reset (ic->preedit);
3348 mtext_reset (ic_info->preedit_saved);
3349 mtext_reset (ic->produced);
3350 M17N_OBJECT_UNREF (ic_info->vars);
3351 ic_info->vars = mplist_copy (ic_info->vars_saved);
3352 ic->cursor_pos = ic_info->state_pos = 0;
3353 ic_info->state_key_head = ic_info->key_head
3354 = ic_info->commit_key_head = 0;
3356 shift_state (ic, Mnil);
3359 if (MPLIST_TAIL_P (args))
3364 ic_info->used += intarg;
3367 ic_info->used = intarg;
3370 else if (name == Mset || name == Madd || name == Msub
3371 || name == Mmul || name == Mdiv)
3373 MSymbol sym = MPLIST_SYMBOL (args);
3374 MPlist *value = resolve_variable (ic_info, sym);
3378 val1 = MPLIST_INTEGER (value);
3379 args = MPLIST_NEXT (args);
3380 val2 = resolve_expression (ic, args);
3382 val1 = val2, op = "=";
3383 else if (name == Madd)
3384 val1 += val2, op = "+=";
3385 else if (name == Msub)
3386 val1 -= val2, op = "-=";
3387 else if (name == Mmul)
3388 val1 *= val2, op = "*=";
3390 val1 /= val2, op = "/=";
3391 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3392 MSYMBOL_NAME (sym), op, val1, val1);
3393 mplist_set (value, Minteger, (void *) val1);
3395 else if (name == Mequal || name == Mless || name == Mgreater
3396 || name == Mless_equal || name == Mgreater_equal)
3399 MPlist *actions1, *actions2;
3402 val1 = resolve_expression (ic, args);
3403 args = MPLIST_NEXT (args);
3404 val2 = resolve_expression (ic, args);
3405 args = MPLIST_NEXT (args);
3406 actions1 = MPLIST_PLIST (args);
3407 args = MPLIST_NEXT (args);
3408 if (MPLIST_TAIL_P (args))
3411 actions2 = MPLIST_PLIST (args);
3412 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3413 if (name == Mequal ? val1 == val2
3414 : name == Mless ? val1 < val2
3415 : name == Mgreater ? val1 > val2
3416 : name == Mless_equal ? val1 <= val2
3419 MDEBUG_PRINT ("ok");
3420 ret = take_action_list (ic, actions1);
3424 MDEBUG_PRINT ("no");
3426 ret = take_action_list (ic, actions2);
3431 else if (name == Mcond)
3435 MPLIST_DO (args, args)
3440 if (! MPLIST_PLIST (args))
3442 cond = MPLIST_PLIST (args);
3443 if (resolve_expression (ic, cond) != 0)
3445 MDEBUG_PRINT1 ("(%dth)", idx);
3446 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3452 else if (name == Mcommit)
3454 preedit_commit (ic, 0);
3456 else if (name == Munhandle)
3458 preedit_commit (ic, 0);
3463 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3467 && (actions = mplist_get (im_info->macros, name)))
3469 if (take_action_list (ic, actions) < 0)
3475 if (ic->candidate_list)
3477 M17N_OBJECT_UNREF (ic->candidate_list);
3478 ic->candidate_list = NULL;
3480 if (ic->cursor_pos > 0
3481 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3484 ic->candidate_list = mtext_property_value (prop);
3485 M17N_OBJECT_REF (ic->candidate_list);
3487 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3489 ic->candidate_from = mtext_property_start (prop);
3490 ic->candidate_to = mtext_property_end (prop);
3493 if (candidate_list != ic->candidate_list)
3494 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3495 if (candidate_index != ic->candidate_index)
3496 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3497 if (candidate_show != ic->candidate_show)
3498 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3503 /* Handle the input key KEY in the current state and map specified in
3504 the input context IC. If KEY is handled correctly, return 0.
3505 Otherwise, return -1. */
3508 handle_key (MInputContext *ic)
3510 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3511 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3512 MIMMap *map = ic_info->map;
3513 MIMMap *submap = NULL;
3514 MSymbol key = ic_info->keys[ic_info->key_head];
3515 MSymbol alias = Mnil;
3518 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3519 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3523 submap = mplist_get (map->submaps, key);
3526 && (alias = msymbol_get (alias, M_key_alias))
3528 submap = mplist_get (map->submaps, alias);
3533 if (! alias || alias == key)
3534 MDEBUG_PRINT (" submap-found");
3536 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3537 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3538 ic->preedit_changed = 1;
3539 ic->cursor_pos = ic_info->state_pos;
3540 ic_info->key_head++;
3541 ic_info->map = map = submap;
3542 if (map->map_actions)
3544 MDEBUG_PRINT (" map-actions:");
3545 if (take_action_list (ic, map->map_actions) < 0)
3547 MDEBUG_PRINT ("\n");
3551 else if (map->submaps)
3553 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3555 MSymbol key = ic_info->keys[i];
3556 char *name = msymbol_name (key);
3558 if (! name[0] || ! name[1])
3559 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3563 /* If this is the terminal map or we have shifted to another
3564 state, perform branch actions (if any). */
3565 if (! map->submaps || map != ic_info->map)
3567 if (map->branch_actions)
3569 MDEBUG_PRINT (" branch-actions:");
3570 if (take_action_list (ic, map->branch_actions) < 0)
3572 MDEBUG_PRINT ("\n");
3576 /* If MAP is still not the root map, shift to the current
3578 if (ic_info->map != ic_info->state->map)
3579 shift_state (ic, ic_info->state->name);
3584 /* MAP can not handle KEY. */
3586 /* Perform branch actions if any. */
3587 if (map->branch_actions)
3589 MDEBUG_PRINT (" branch-actions:");
3590 if (take_action_list (ic, map->branch_actions) < 0)
3592 MDEBUG_PRINT ("\n");
3597 if (map == ic_info->map)
3599 /* The above branch actions didn't change the state. */
3601 /* If MAP is the root map of the initial state, and there
3602 still exist an unhandled key, it means that the current
3603 input method can not handle it. */
3604 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3605 && ic_info->key_head < ic_info->used)
3607 MDEBUG_PRINT (" unhandled\n");
3611 if (map != ic_info->state->map)
3613 /* MAP is not the root map. Shift to the root map of the
3615 shift_state (ic, ic_info->state->name);
3617 else if (! map->branch_actions)
3619 /* MAP is the root map without any default branch
3620 actions. Shift to the initial state. */
3621 shift_state (ic, Mnil);
3625 MDEBUG_PRINT ("\n");
3629 /* Initialize IC->ic_info. */
3632 init_ic_info (MInputContext *ic)
3634 MInputMethodInfo *im_info = ic->im->info;
3635 MInputContextInfo *ic_info = ic->info;
3638 MLIST_INIT1 (ic_info, keys, 8);;
3640 ic_info->markers = mplist ();
3642 ic_info->vars = mplist ();
3643 if (im_info->configured_vars)
3644 MPLIST_DO (plist, im_info->configured_vars)
3646 MPlist *pl = MPLIST_PLIST (plist);
3647 MSymbol name = MPLIST_SYMBOL (pl);
3649 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3650 if (MPLIST_KEY (pl) != Mt)
3652 MPlist *p = mplist ();
3654 mplist_push (ic_info->vars, Mplist, p);
3655 M17N_OBJECT_UNREF (p);
3656 mplist_add (p, Msymbol, name);
3657 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3660 ic_info->vars_saved = mplist_copy (ic_info->vars);
3662 if (im_info->externals)
3664 MPlist *func_args = mplist (), *plist;
3666 mplist_add (func_args, Mt, ic);
3667 MPLIST_DO (plist, im_info->externals)
3669 MIMExternalModule *external = MPLIST_VAL (plist);
3670 MIMExternalFunc func
3671 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3676 M17N_OBJECT_UNREF (func_args);
3679 ic_info->preedit_saved = mtext ();
3680 ic_info->tick = im_info->tick;
3683 /* Finalize IC->ic_info. */
3686 fini_ic_info (MInputContext *ic)
3688 MInputMethodInfo *im_info = ic->im->info;
3689 MInputContextInfo *ic_info = ic->info;
3691 if (im_info->externals)
3693 MPlist *func_args = mplist (), *plist;
3695 mplist_add (func_args, Mt, ic);
3696 MPLIST_DO (plist, im_info->externals)
3698 MIMExternalModule *external = MPLIST_VAL (plist);
3699 MIMExternalFunc func
3700 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3705 M17N_OBJECT_UNREF (func_args);
3708 MLIST_FREE1 (ic_info, keys);
3709 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3710 M17N_OBJECT_UNREF (ic_info->markers);
3711 M17N_OBJECT_UNREF (ic_info->vars);
3712 M17N_OBJECT_UNREF (ic_info->vars_saved);
3713 M17N_OBJECT_UNREF (ic_info->preceding_text);
3714 M17N_OBJECT_UNREF (ic_info->following_text);
3716 memset (ic_info, 0, sizeof (MInputContextInfo));
3720 re_init_ic (MInputContext *ic, int reload)
3722 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3723 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3724 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3726 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3727 preedit_changed = mtext_nchars (ic->preedit) > 0;
3728 cursor_pos_changed = ic->cursor_pos > 0;
3729 candidates_changed = 0;
3730 if (ic->candidate_list)
3732 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3733 M17N_OBJECT_UNREF (ic->candidate_list);
3734 ic->candidate_list = NULL;
3736 if (ic->candidate_show)
3738 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3739 ic->candidate_show = 0;
3741 if (ic->candidate_index > 0)
3743 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3744 ic->candidate_index = 0;
3745 ic->candidate_from = ic->candidate_to = 0;
3747 if (mtext_nchars (ic->produced) > 0)
3748 mtext_reset (ic->produced);
3749 if (mtext_nchars (ic->preedit) > 0)
3750 mtext_reset (ic->preedit);
3752 M17N_OBJECT_UNREF (ic->plist);
3753 ic->plist = mplist ();
3757 reload_im_info (im_info);
3758 if (! im_info->states)
3760 struct MIMState *state;
3762 M17N_OBJECT (state, free_state, MERROR_IM);
3763 state->name = msymbol ("init");
3764 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3765 MSTRUCT_CALLOC (state->map, MERROR_IM);
3766 im_info->states = mplist ();
3767 mplist_add (im_info->states, state->name, state);
3770 shift_state (ic, Mnil);
3772 ic->status_changed = status_changed;
3773 ic->preedit_changed = preedit_changed;
3774 ic->cursor_pos_changed = cursor_pos_changed;
3775 ic->candidates_changed = candidates_changed;
3779 reset_ic (MInputContext *ic, MSymbol ignore)
3781 MDEBUG_PRINT ("\n [IM] reset\n");
3786 open_im (MInputMethod *im)
3788 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3790 if (! im_info || ! im_info->states)
3791 MERROR (MERROR_IM, -1);
3798 close_im (MInputMethod *im)
3804 create_ic (MInputContext *ic)
3806 MInputContextInfo *ic_info;
3808 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3811 shift_state (ic, Mnil);
3816 destroy_ic (MInputContext *ic)
3823 check_reload (MInputContext *ic, MSymbol key)
3825 MInputMethodInfo *im_info = ic->im->info;
3826 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3830 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3834 MPLIST_DO (plist, plist)
3836 MSymbol this_key, alias;
3838 if (MPLIST_MTEXT_P (plist))
3840 MText *mt = MPLIST_MTEXT (plist);
3841 int c = mtext_ref_char (mt, 0);
3845 this_key = one_char_symbol[c];
3849 MPlist *pl = MPLIST_PLIST (plist);
3851 this_key = MPLIST_SYMBOL (pl);
3855 && (alias = msymbol_get (alias, M_key_alias))
3856 && alias != this_key);
3860 if (MPLIST_TAIL_P (plist))
3863 MDEBUG_PRINT ("\n [IM] reload");
3869 /** Handle the input key KEY in the current state and map of IC->info.
3870 If KEY is handled but no text is produced, return 0, otherwise
3876 filter (MInputContext *ic, MSymbol key, void *arg)
3878 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3879 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3882 if (check_reload (ic, key))
3885 if (! ic_info->state)
3887 ic_info->key_unhandled = 1;
3890 mtext_reset (ic->produced);
3891 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3892 M17N_OBJECT_UNREF (ic_info->preceding_text);
3893 M17N_OBJECT_UNREF (ic_info->following_text);
3894 ic_info->preceding_text = ic_info->following_text = NULL;
3895 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3896 ic_info->key_unhandled = 0;
3899 if (handle_key (ic) < 0)
3901 /* KEY was not handled. Delete it from the current key sequence. */
3902 if (ic_info->used > 0)
3904 memmove (ic_info->keys, ic_info->keys + 1,
3905 sizeof (int) * (ic_info->used - 1));
3907 if (ic_info->state_key_head > 0)
3908 ic_info->state_key_head--;
3909 if (ic_info->commit_key_head > 0)
3910 ic_info->commit_key_head--;
3912 /* This forces returning 1. */
3913 ic_info->key_unhandled = 1;
3919 reset_ic (ic, Mnil);
3920 ic_info->key_unhandled = 1;
3923 /* Break the loop if all keys were handled. */
3924 } while (ic_info->key_head < ic_info->used);
3926 /* If the current map is the root of the initial state, we should
3927 produce any preedit text in ic->produced. */
3928 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3929 preedit_commit (ic, 1);
3931 if (mtext_nchars (ic->produced) > 0)
3935 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3936 MSYMBOL_NAME (ic_info->state->name));
3937 for (i = 0; i < mtext_nchars (ic->produced); i++)
3938 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3942 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3943 Mlanguage, ic->im->language);
3945 if (ic_info->commit_key_head > 0)
3947 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3948 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3949 ic_info->used -= ic_info->commit_key_head;
3950 ic_info->key_head -= ic_info->commit_key_head;
3951 ic_info->state_key_head -= ic_info->commit_key_head;
3952 ic_info->commit_key_head = 0;
3954 if (ic_info->key_unhandled)
3957 ic_info->key_head = ic_info->state_key_head
3958 = ic_info->commit_key_head = 0;
3961 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3965 /** Return 1 if the last event or key was not handled, otherwise
3968 There is no need of looking up because ic->produced should already
3969 contain the produced text (if any).
3974 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3976 mtext_cat (mt, ic->produced);
3977 mtext_reset (ic->produced);
3978 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3982 /* Input method command handler. */
3984 /* List of all (global and local) commands.
3985 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3986 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3987 Global commands are stored as (t (t COMMAND ...)) */
3990 /* Input method variable handler. */
3993 /* Support functions for mdebug_dump_im. */
3996 dump_im_map (MPlist *map_list, int indent)
3999 MSymbol key = MPLIST_KEY (map_list);
4000 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
4002 prefix = (char *) alloca (indent + 1);
4003 memset (prefix, 32, indent);
4004 prefix[indent] = '\0';
4006 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
4007 if (map->map_actions)
4008 mdebug_dump_plist (map->map_actions, indent + 2);
4011 MPLIST_DO (map_list, map->submaps)
4013 fprintf (stderr, "\n%s ", prefix);
4014 dump_im_map (map_list, indent + 2);
4017 if (map->branch_actions)
4019 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
4020 mdebug_dump_plist (map->branch_actions, indent + 4);
4021 fprintf (stderr, ")");
4023 fprintf (stderr, ")");
4028 dump_im_state (MIMState *state, int indent)
4033 prefix = (char *) alloca (indent + 1);
4034 memset (prefix, 32, indent);
4035 prefix[indent] = '\0';
4037 fprintf (stderr, "(%s", msymbol_name (state->name));
4038 if (state->map->submaps)
4040 MPLIST_DO (map_list, state->map->submaps)
4042 fprintf (stderr, "\n%s ", prefix);
4043 dump_im_map (map_list, indent + 2);
4046 fprintf (stderr, ")");
4054 Minput_driver = msymbol ("input-driver");
4056 Minput_preedit_start = msymbol ("input-preedit-start");
4057 Minput_preedit_done = msymbol ("input-preedit-done");
4058 Minput_preedit_draw = msymbol ("input-preedit-draw");
4059 Minput_status_start = msymbol ("input-status-start");
4060 Minput_status_done = msymbol ("input-status-done");
4061 Minput_status_draw = msymbol ("input-status-draw");
4062 Minput_candidates_start = msymbol ("input-candidates-start");
4063 Minput_candidates_done = msymbol ("input-candidates-done");
4064 Minput_candidates_draw = msymbol ("input-candidates-draw");
4065 Minput_set_spot = msymbol ("input-set-spot");
4066 Minput_focus_move = msymbol ("input-focus-move");
4067 Minput_focus_in = msymbol ("input-focus-in");
4068 Minput_focus_out = msymbol ("input-focus-out");
4069 Minput_toggle = msymbol ("input-toggle");
4070 Minput_reset = msymbol ("input-reset");
4071 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4072 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4073 Mcustomized = msymbol ("customized");
4074 Mconfigured = msymbol ("configured");
4075 Minherited = msymbol ("inherited");
4077 minput_default_driver.open_im = open_im;
4078 minput_default_driver.close_im = close_im;
4079 minput_default_driver.create_ic = create_ic;
4080 minput_default_driver.destroy_ic = destroy_ic;
4081 minput_default_driver.filter = filter;
4082 minput_default_driver.lookup = lookup;
4083 minput_default_driver.callback_list = mplist ();
4084 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4085 M17N_FUNC (reset_ic));
4086 minput_driver = &minput_default_driver;
4088 fully_initialized = 0;
4095 if (fully_initialized)
4097 free_im_list (im_info_list);
4099 free_im_list (im_custom_list);
4101 free_im_list (im_config_list);
4102 M17N_OBJECT_UNREF (load_im_info_keys);
4105 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4106 M17N_OBJECT_UNREF (minput_driver->callback_list);
4111 minput__char_to_key (int c)
4113 if (c < 0 || c >= 0x100)
4116 return one_char_symbol[c];
4120 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4125 /*** @addtogroup m17nInputMethod */
4130 @name Variables: Predefined symbols for callback commands.
4132 These are the predefined symbols that are used as the @c COMMAND
4133 argument of callback functions of an input method driver (see
4134 #MInputDriver::callback_list).
4136 Most of them do not require extra argument nor return any value;
4137 exceptions are these:
4139 Minput_get_surrounding_text: When a callback function assigned for
4140 this command is called, the first element of #MInputContext::plist
4141 has key #Minteger and the value specifies which portion of the
4142 surrounding text should be retrieved. If the value is positive,
4143 it specifies the number of characters following the current cursor
4144 position. If the value is negative, the absolute value specifies
4145 the number of characters preceding the current cursor position.
4146 If the value is zero, it means that the caller just wants to know
4147 if the surrounding text is currently supported or not.
4149 If the surrounding text is currently supported, the callback
4150 function must set the key of this element to #Mtext and the value
4151 to the retrieved M-text. The length of the M-text may be shorter
4152 than the requested number of characters, if the available text is
4153 not that long. The length can be zero in the worst case. Or, the
4154 length may be longer if an application thinks it is more efficient
4155 to return that length.
4157 If the surrounding text is not currently supported, the callback
4158 function should return without changing the first element of
4159 #MInputContext::plist.
4161 Minput_delete_surrounding_text: When a callback function assigned
4162 for this command is called, the first element of
4163 #MInputContext::plist has key #Minteger and the value specifies
4164 which portion of the surrounding text should be deleted in the
4165 same way as the case of Minput_get_surrounding_text. The callback
4166 function must delete the specified text. It should not alter
4167 #MInputContext::plist. */
4169 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4171 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4172 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4174 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4176 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4177 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4178 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4179 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4180 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4181 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4182 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4184 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4185 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4186 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4187 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4188 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4190 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4191 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4193 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4194 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4195 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4196 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4197 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4198 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4202 MSymbol Minput_preedit_start;
4203 MSymbol Minput_preedit_done;
4204 MSymbol Minput_preedit_draw;
4205 MSymbol Minput_status_start;
4206 MSymbol Minput_status_done;
4207 MSymbol Minput_status_draw;
4208 MSymbol Minput_candidates_start;
4209 MSymbol Minput_candidates_done;
4210 MSymbol Minput_candidates_draw;
4211 MSymbol Minput_set_spot;
4212 MSymbol Minput_toggle;
4213 MSymbol Minput_reset;
4214 MSymbol Minput_get_surrounding_text;
4215 MSymbol Minput_delete_surrounding_text;
4221 @name Variables: Predefined symbols for special input events.
4223 These are the predefined symbols that are used as the @c KEY
4224 argument of minput_filter (). */
4226 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4228 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4233 MSymbol Minput_focus_out;
4234 MSymbol Minput_focus_in;
4235 MSymbol Minput_focus_move;
4241 @name Variables: Predefined symbols used in input method information.
4243 These are the predefined symbols describing status of input method
4244 command and variable, and are used in a return value of
4245 minput_get_command () and minput_get_variable (). */
4247 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4249 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4250 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4254 MSymbol Mcustomized;
4255 MSymbol Mconfigured;
4261 @brief The default driver for internal input methods.
4263 The variable #minput_default_driver is the default driver for
4264 internal input methods.
4266 The member MInputDriver::open_im () searches the m17n database for
4267 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4268 $NAME\> and loads it.
4270 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4271 programmers responsibility to set it to a plist of proper callback
4272 functions. Otherwise, no feedback information (e.g. preedit text)
4273 can be shown to users.
4275 The macro M17N_INIT () sets the variable #minput_driver to the
4276 pointer to this driver so that all internal input methods use it.
4278 Therefore, unless @c minput_driver is set differently, the driver
4279 dependent arguments $ARG of the functions whose name begins with
4280 "minput_" are all ignored. */
4282 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4284 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4286 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4287 \< #Minput_method, $LANGUAGE, $NAME\>
4288 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4290 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4291 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4292 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4293 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4295 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4296 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4298 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4299 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4301 MInputDriver minput_default_driver;
4305 @brief The driver for internal input methods.
4307 The variable #minput_driver is a pointer to the input method
4308 driver that is used by internal input methods. The macro
4309 M17N_INIT () initializes it to a pointer to #minput_default_driver
4310 if <m17n<EM></EM>.h> is included. */
4312 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4314 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4315 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4316 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4317 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4319 MInputDriver *minput_driver;
4321 MSymbol Minput_driver;
4336 @brief Open an input method.
4338 The minput_open_im () function opens an input method whose
4339 language and name match $LANGUAGE and $NAME, and returns a pointer
4340 to the input method object newly allocated.
4342 This function at first decides a driver for the input method as
4345 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4346 #minput_driver is used.
4348 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4349 driver pointed to by the property value is used to open the input
4350 method. If $NAME has no such a property, @c NULL is returned.
4352 Then, the member MInputDriver::open_im () of the driver is
4355 $ARG is set in the member @c arg of the structure MInputMethod so
4356 that the driver can refer to it. */
4358 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4360 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4361 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4363 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4365 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4366 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4368 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4369 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4370 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4372 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4374 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4376 @latexonly \IPAlabel{minput_open} @endlatexonly
4381 minput_open_im (MSymbol language, MSymbol name, void *arg)
4384 MInputDriver *driver;
4388 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4389 msymbol_name (language), msymbol_name (name));
4393 MERROR (MERROR_IM, NULL);
4394 driver = minput_driver;
4398 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4400 MERROR (MERROR_IM, NULL);
4403 MSTRUCT_CALLOC (im, MERROR_IM);
4404 im->language = language;
4407 im->driver = *driver;
4408 if ((*im->driver.open_im) (im) < 0)
4410 MDEBUG_PRINT (" failed\n");
4414 MDEBUG_PRINT (" ok\n");
4421 @brief Close an input method.
4423 The minput_close_im () function closes the input method $IM, which
4424 must have been created by minput_open_im (). */
4427 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4429 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4430 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4433 minput_close_im (MInputMethod *im)
4435 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4436 msymbol_name (im->name), msymbol_name (im->language));
4437 (*im->driver.close_im) (im);
4439 MDEBUG_PRINT (" done\n");
4445 @brief Create an input context.
4447 The minput_create_ic () function creates an input context object
4448 associated with input method $IM, and calls callback functions
4449 corresponding to #Minput_preedit_start, #Minput_status_start, and
4450 #Minput_status_draw in this order.
4453 If an input context is successfully created, minput_create_ic ()
4454 returns a pointer to it. Otherwise it returns @c NULL. */
4457 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4459 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4460 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4461 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4462 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4465 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4466 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4470 minput_create_ic (MInputMethod *im, void *arg)
4474 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4475 msymbol_name (im->name), msymbol_name (im->language));
4476 MSTRUCT_CALLOC (ic, MERROR_IM);
4479 ic->preedit = mtext ();
4480 ic->candidate_list = NULL;
4481 ic->produced = mtext ();
4482 ic->spot.x = ic->spot.y = 0;
4484 ic->plist = mplist ();
4485 if ((*im->driver.create_ic) (ic) < 0)
4487 MDEBUG_PRINT (" failed\n");
4488 M17N_OBJECT_UNREF (ic->preedit);
4489 M17N_OBJECT_UNREF (ic->produced);
4490 M17N_OBJECT_UNREF (ic->plist);
4495 if (im->driver.callback_list)
4497 minput_callback (ic, Minput_preedit_start);
4498 minput_callback (ic, Minput_status_start);
4499 minput_callback (ic, Minput_status_draw);
4502 MDEBUG_PRINT (" ok\n");
4509 @brief Destroy an input context.
4511 The minput_destroy_ic () function destroys the input context $IC,
4512 which must have been created by minput_create_ic (). It calls
4513 callback functions corresponding to #Minput_preedit_done,
4514 #Minput_status_done, and #Minput_candidates_done in this order. */
4517 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4519 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4520 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4521 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4522 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4523 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4527 minput_destroy_ic (MInputContext *ic)
4529 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4530 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4531 if (ic->im->driver.callback_list)
4533 minput_callback (ic, Minput_preedit_done);
4534 minput_callback (ic, Minput_status_done);
4535 minput_callback (ic, Minput_candidates_done);
4537 (*ic->im->driver.destroy_ic) (ic);
4538 M17N_OBJECT_UNREF (ic->preedit);
4539 M17N_OBJECT_UNREF (ic->produced);
4540 M17N_OBJECT_UNREF (ic->plist);
4541 MDEBUG_PRINT (" done\n");
4548 @brief Filter an input key.
4550 The minput_filter () function filters input key $KEY according to
4551 input context $IC, and calls callback functions corresponding to
4552 #Minput_preedit_draw, #Minput_status_draw, and
4553 #Minput_candidates_draw if the preedit text, the status, and the
4554 current candidate are changed respectively.
4556 To make the input method commit the current preedit text (if any)
4557 and shift to the initial state, call this function with #Mnil as
4560 To inform the input method about the focus-out event, call this
4561 function with #Minput_focus_out as $KEY.
4563 To inform the input method about the focus-in event, call this
4564 function with #Minput_focus_in as $KEY.
4566 To inform the input method about the focus-move event (i.e. input
4567 spot change within the same input context), call this function
4568 with #Minput_focus_move as $KEY.
4571 If $KEY is filtered out, this function returns 1. In that case,
4572 the caller should discard the key. Otherwise, it returns 0, and
4573 the caller should handle the key, for instance, by calling the
4574 function minput_lookup () with the same key. */
4577 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4579 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4580 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4581 #Minput_preedit_draw, #Minput_status_draw,
4582 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4585 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4586 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4587 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4588 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4590 @latexonly \IPAlabel{minput_filter} @endlatexonly
4594 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4601 if (ic->im->driver.callback_list
4602 && mtext_nchars (ic->preedit) > 0)
4603 minput_callback (ic, Minput_preedit_draw);
4605 ret = (*ic->im->driver.filter) (ic, key, arg);
4607 if (ic->im->driver.callback_list)
4609 if (ic->preedit_changed)
4610 minput_callback (ic, Minput_preedit_draw);
4611 if (ic->status_changed)
4612 minput_callback (ic, Minput_status_draw);
4613 if (ic->candidates_changed)
4614 minput_callback (ic, Minput_candidates_draw);
4623 @brief Look up a text produced in the input context.
4625 The minput_lookup () function looks up a text in the input context
4626 $IC. $KEY must be identical to the one that was used in the previous call of
4629 If a text was produced by the input method, it is concatenated
4632 This function calls #MInputDriver::lookup .
4635 If $KEY was correctly handled by the input method, this function
4636 returns 0. Otherwise, it returns -1, even though some text
4637 might be produced in $MT. */
4640 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4642 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4643 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4645 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4648 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4651 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4652 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4653 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4655 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4658 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4660 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4665 @brief Set the spot of the input context.
4667 The minput_set_spot () function sets the spot of input context $IC
4668 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4669 The semantics of these values depends on the input method driver.
4671 For instance, a driver designed to work in a CUI environment may
4672 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4673 $DESCENT . A driver designed to work in a window system may
4674 interpret $X and $Y as the pixel offsets relative to the origin of the
4675 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4676 descent pixels of the line at ($X . $Y ).
4678 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4680 $MT and $POS are the M-text and the character position at the spot.
4681 $MT may be @c NULL, in which case, the input method cannot get
4682 information about the text around the spot. */
4685 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4687 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4688 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4689 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4691 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4692 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4693 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4694 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4695 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4696 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4698 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4700 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4701 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4705 minput_set_spot (MInputContext *ic, int x, int y,
4706 int ascent, int descent, int fontsize,
4711 ic->spot.ascent = ascent;
4712 ic->spot.descent = descent;
4713 ic->spot.fontsize = fontsize;
4716 if (ic->im->driver.callback_list)
4717 minput_callback (ic, Minput_set_spot);
4722 @brief Toggle input method.
4724 The minput_toggle () function toggles the input method associated
4725 with input context $IC. */
4727 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4729 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4730 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4734 minput_toggle (MInputContext *ic)
4736 if (ic->im->driver.callback_list)
4737 minput_callback (ic, Minput_toggle);
4738 ic->active = ! ic->active;
4744 @brief Reset an input context.
4746 The minput_reset_ic () function resets input context $IC by
4747 calling a callback function corresponding to #Minput_reset. It
4748 resets the status of $IC to its initial one. As the
4749 current preedit text is deleted without commitment, if necessary,
4750 call minput_filter () with the arg @r key #Mnil to force the input
4751 method to commit the preedit in advance. */
4754 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4756 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4757 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4758 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4759 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4760 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4761 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4764 minput_reset_ic (MInputContext *ic)
4766 if (ic->im->driver.callback_list)
4767 minput_callback (ic, Minput_reset);
4773 @brief Get title and icon filename of an input method.
4775 The minput_get_title_icon () function returns a plist containing a
4776 title and icon filename (if any) of an input method specified by
4777 $LANGUAGE and $NAME.
4779 The first element of the plist has key #Mtext and the value is an
4780 M-text of the title for identifying the input method. The second
4781 element (if any) has key #Mtext and the value is an M-text of the
4782 icon image (absolute) filename for the same purpose.
4785 If there exists a specified input method and it defines an title,
4786 a plist is returned. Otherwise, NULL is returned. The caller
4787 must free the plist by m17n_object_unref (). */
4789 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4791 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4792 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4795 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4796 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4797 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4800 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4801 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4802 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4805 minput_get_title_icon (MSymbol language, MSymbol name)
4807 MInputMethodInfo *im_info;
4814 im_info = get_im_info (language, name, Mnil, Mtitle);
4815 if (! im_info || !im_info->title)
4817 mt = mtext_get_prop (im_info->title, 0, Mtext);
4819 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4822 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4825 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4826 (char *) MSYMBOL_NAME (name));
4827 file = mdatabase__find_file (buf);
4828 if (! file && language == Mt)
4830 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4831 file = mdatabase__find_file (buf);
4836 mplist_add (plist, Mtext, im_info->title);
4839 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4841 mplist_add (plist, Mtext, mt);
4842 M17N_OBJECT_UNREF (mt);
4850 @brief Get description text of an input method.
4852 The minput_get_description () function returns an M-text that
4853 describes the input method specified by $LANGUAGE and $NAME.
4856 If the specified input method has a description text, a pointer to
4857 #MText is returned. The caller has to free it by m17n_object_unref ().
4858 If the input method does not have a description text, @c NULL is
4861 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4863 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4864 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4867 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4868 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4869 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4870 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4873 minput_get_description (MSymbol language, MSymbol name)
4875 MInputMethodInfo *im_info;
4883 extra = language, language = Mt;
4885 im_info = get_im_info (language, name, extra, Mdescription);
4886 if (! im_info || ! im_info->description)
4888 M17N_OBJECT_REF (im_info->description);
4889 return im_info->description;
4895 @brief Get information about input method command(s).
4897 The minput_get_command () function returns information about
4898 the command $COMMAND of the input method specified by $LANGUAGE and
4899 $NAME. An input method command is a pseudo key event to which one
4900 or more actual input key sequences are assigned.
4902 There are two kinds of commands, global and local. A global
4903 command has a global definition, and the description and the key
4904 assignment may be inherited by a local command. Each input method
4905 defines a local command which has a local key assignment. It may
4906 also declare a local command that inherits the definition of a
4907 global command of the same name.
4909 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4910 information about a global command. Otherwise information about a
4911 local command is returned.
4913 If $COMMAND is #Mnil, information about all commands is returned.
4915 The return value is a @e well-formed plist (@ref m17nPlist) of this
4918 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4920 @c NAME is a symbol representing the command name.
4922 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4923 command has no description.
4925 @c STATUS is a symbol representing how the key assignment is decided.
4926 The value is #Mnil (the default key assignment), #Mcustomized (the
4927 key assignment is customized by per-user customization file), or
4928 #Mconfigured (the key assignment is set by the call of
4929 minput_config_command ()). For a local command only, it may also
4930 be #Minherited (the key assignment is inherited from the
4931 corresponding global command).
4933 @c KEYSEQ is a plist of one or more symbols representing a key
4934 sequence assigned to the command. If there's no KEYSEQ, the
4935 command is currently disabled (i.e. no key sequence can trigger
4936 actions of the command).
4938 If $COMMAND is not #Mnil, the first element of the returned plist
4939 contains the information about $COMMAND.
4943 If the requested information was found, a pointer to a non-empty
4944 plist is returned. As the plist is kept in the library, the
4945 caller must not modify nor free it.
4947 Otherwise (the specified input method or the specified command
4948 does not exist), @c NULL is returned. */
4950 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4952 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4953 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4954 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4955 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4957 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4958 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4959 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4960 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4961 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4963 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4964 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4967 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4969 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4972 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4974 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4976 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4979 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4980 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4981 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4982 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4983 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4984 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4987 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4988 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4989 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4990 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4992 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4993 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4997 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4998 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5001 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5006 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
5008 /* Return a description of the command COMMAND of the input method
5009 specified by LANGUAGE and NAME. */
5010 MPlist *cmd = minput_get_command (langauge, name, command);
5015 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
5016 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
5017 return (mplist_key (plist) == Mtext
5018 ? (MText *) mplist_value (plist)
5024 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5026 MInputMethodInfo *im_info;
5030 im_info = get_im_info (language, name, Mnil, Mcommand);
5032 || ! im_info->configured_cmds
5033 || MPLIST_TAIL_P (im_info->configured_cmds))
5035 if (command == Mnil)
5036 return im_info->configured_cmds;
5037 return mplist__assq (im_info->configured_cmds, command);
5043 @brief Configure the key sequence of an input method command.
5045 The minput_config_command () function assigns a list of key
5046 sequences $KEYSEQLIST to the command $COMMAND of the input method
5047 specified by $LANGUAGE and $NAME.
5049 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5050 sequences, and each key sequence must be a plist of symbols.
5052 If $KEYSEQLIST is an empty plist, any configuration and
5053 customization of the command are cancelled, and default key
5054 sequences become effective.
5056 If $KEYSEQLIST is NULL, the configuration of the command is
5057 canceled, and the original key sequences (what saved in per-user
5058 customization file, or the default one) become effective.
5060 In the latter two cases, $COMMAND can be #Mnil to make all the
5061 commands of the input method the target of the operation.
5063 If $NAME is #Mnil, this function configures the key assignment of a
5064 global command, not that of a specific input method.
5066 The configuration takes effect for input methods opened or
5067 re-opened later in the current session. In order to make the
5068 configuration take effect for the future session, it must be saved
5069 in a per-user customization file by the function
5070 minput_save_config ().
5073 If the operation was successful, this function returns 0,
5074 otherwise returns -1. The operation fails in these cases:
5076 <li>$KEYSEQLIST is not in a valid form.
5077 <li>$COMMAND is not available for the input method.
5078 <li>$LANGUAGE and $NAME do not specify an existing input method.
5082 minput_get_commands (), minput_save_config ().
5085 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5087 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5088 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5089 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5091 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5092 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5094 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5095 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5097 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5098 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5099 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5101 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5102 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5104 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5105 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5107 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5108 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5109 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5110 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5114 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5116 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5117 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5118 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5122 minput_get_commands (), minput_save_config ().
5126 /* Add "C-x u" to the "start" command of Unicode input method. */
5128 MSymbol start_command = msymbol ("start");
5129 MSymbol unicode = msymbol ("unicode");
5130 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5132 /* At first get the current key-sequence assignment. */
5133 cmd = minput_get_command (Mt, unicode, start_command);
5136 /* The input method does not have the command "start". Here
5137 should come some error handling code. */
5139 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5140 Extract the part (KEY-SEQUENCE ...). */
5141 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5142 /* Copy it because we should not modify it directly. */
5143 key_seq_list = mplist_copy (plist);
5145 key_seq = mplist ();
5146 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5147 mplist_add (key_seq, Msymbol, msymbol ("u"));
5148 mplist_add (key_seq_list, Mplist, key_seq);
5149 m17n_object_unref (key_seq);
5151 minput_config_command (Mt, unicode, start_command, key_seq_list);
5152 m17n_object_unref (key_seq_list);
5157 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5160 MInputMethodInfo *im_info, *config;
5165 im_info = get_im_info (language, name, Mnil, Mcommand);
5167 MERROR (MERROR_IM, -1);
5168 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5170 || ! mplist__assq (im_info->configured_cmds, command)))
5171 MERROR (MERROR_IM, -1);
5172 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5174 MPLIST_DO (plist, keyseqlist)
5175 if (! check_command_keyseq (plist))
5176 MERROR (MERROR_IM, -1);
5179 config = get_config_info (im_info);
5182 if (! im_config_list)
5183 im_config_list = mplist ();
5184 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5185 config->cmds = mplist ();
5186 config->vars = mplist ();
5189 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5190 /* Nothing to do. */
5193 if (command == Mnil)
5197 /* Cancal the configuration. */
5198 if (MPLIST_TAIL_P (config->cmds))
5200 mplist_set (config->cmds, Mnil, NULL);
5204 /* Cancal the customization. */
5205 MInputMethodInfo *custom = get_custom_info (im_info);
5207 if (MPLIST_TAIL_P (config->cmds)
5208 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5209 /* Nothing to do. */
5211 mplist_set (config->cmds, Mnil, NULL);
5212 MPLIST_DO (plist, custom->cmds)
5214 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5216 mplist_add (plist, Msymbol, command);
5217 mplist_push (config->cmds, Mplist, plist);
5218 M17N_OBJECT_UNREF (plist);
5224 plist = mplist__assq (config->cmds, command);
5227 /* Cancel the configuration. */
5230 mplist__pop_unref (plist);
5232 else if (MPLIST_TAIL_P (keyseqlist))
5234 /* Cancel the customization. */
5235 MInputMethodInfo *custom = get_custom_info (im_info);
5236 int no_custom = (! custom || ! custom->cmds
5237 || ! mplist__assq (custom->cmds, command));
5243 mplist_add (config->cmds, Mplist, plist);
5244 M17N_OBJECT_UNREF (plist);
5245 plist = mplist_add (plist, Msymbol, command);
5250 mplist__pop_unref (plist);
5253 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5254 plist = MPLIST_NEXT (plist);
5255 mplist_set (plist, Mnil, NULL);
5265 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5266 if (! MPLIST_TAIL_P (plist))
5267 mplist_set (plist, Mnil, NULL);
5272 mplist_add (config->cmds, Mplist, plist);
5273 M17N_OBJECT_UNREF (plist);
5274 plist = mplist_add (plist, Msymbol, command);
5275 plist = MPLIST_NEXT (plist);
5277 MPLIST_DO (keyseqlist, keyseqlist)
5279 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5280 plist = mplist_add (plist, Mplist, pl);
5281 M17N_OBJECT_UNREF (pl);
5285 config_all_commands (im_info);
5286 im_info->tick = time (NULL);
5293 @brief Get information about input method variable(s).
5295 The minput_get_variable () function returns information about
5296 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5297 An input method variable controls behavior of an input method.
5299 There are two kinds of variables, global and local. A global
5300 variable has a global definition, and the description and the value
5301 may be inherited by a local variable. Each input method defines a
5302 local variable which has local value. It may also declare a
5303 local variable that inherits definition of a global variable of
5306 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5307 variable is returned. Otherwise information about a local variable
5310 If $VARIABLE is #Mnil, information about all variables is
5313 The return value is a @e well-formed plist (@ref m17nPlist) of this
5316 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5318 @c NAME is a symbol representing the variable name.
5320 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5321 variable has no description.
5323 @c STATUS is a symbol representing how the value is decided. The
5324 value is #Mnil (the default value), #Mcustomized (the value is
5325 customized by per-user customization file), or #Mconfigured (the
5326 value is set by the call of minput_config_variable ()). For a
5327 local variable only, it may also be #Minherited (the value is
5328 inherited from the corresponding global variable).
5330 @c VALUE is the initial value of the variable. If the key of this
5331 element is #Mt, the variable has no initial value. Otherwise, the
5332 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5335 @c VALID-VALUEs (if any) specify which values the variable can have.
5336 They have the same type (i.e. having the same key) as @c VALUE except
5337 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5338 may be a plist of two integers specifying the range of possible
5341 If there no @c VALID-VALUE, the variable can have any value as long
5342 as the type is the same as @c VALUE.
5344 If $VARIABLE is not #Mnil, the first element of the returned plist
5345 contains the information about $VARIABLE.
5349 If the requested information was found, a pointer to a non-empty
5350 plist is returned. As the plist is kept in the library, the
5351 caller must not modify nor free it.
5353 Otherwise (the specified input method or the specified variable
5354 does not exist), @c NULL is returned. */
5356 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5358 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5359 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5360 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5362 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5363 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5364 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5365 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5368 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5369 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5371 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5373 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5375 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5378 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5380 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5383 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5384 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5385 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5386 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5387 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5388 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5390 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5391 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5392 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5394 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5395 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5396 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5397 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5399 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5402 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5403 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5407 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5408 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5411 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5415 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5417 MInputMethodInfo *im_info;
5421 im_info = get_im_info (language, name, Mnil, Mvariable);
5422 if (! im_info || ! im_info->configured_vars)
5424 if (variable == Mnil)
5425 return im_info->configured_vars;
5426 return mplist__assq (im_info->configured_vars, variable);
5432 @brief Configure the value of an input method variable.
5434 The minput_config_variable () function assigns $VALUE to the
5435 variable $VARIABLE of the input method specified by $LANGUAGE and
5438 If $VALUE is a non-empty plist, it must be a plist of one element
5439 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5440 the corresponding type. That value is assigned to the variable.
5442 If $VALUE is an empty plist, any configuration and customization
5443 of the variable are canceled, and the default value is assigned to
5446 If $VALUE is NULL, the configuration of the variable is canceled,
5447 and the original value (what saved in per-user customization file,
5448 or the default value) is assigned to the variable.
5450 In the latter two cases, $VARIABLE can be #Mnil to make all the
5451 variables of the input method the target of the operation.
5453 If $NAME is #Mnil, this function configures the value of global
5454 variable, not that of a specific input method.
5456 The configuration takes effect for input methods opened or
5457 re-opened later in the current session. To make the configuration
5458 take effect for the future session, it must be saved in a per-user
5459 customization file by the function minput_save_config ().
5463 If the operation was successful, this function returns 0,
5464 otherwise returns -1. The operation fails in these cases:
5466 <li>$VALUE is not in a valid form, the type does not match the
5467 definition, or the value is our of range.
5468 <li>$VARIABLE is not available for the input method.
5469 <li>$LANGUAGE and $NAME do not specify an existing input method.
5473 minput_get_variable (), minput_save_config (). */
5475 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5477 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5478 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5480 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5481 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5482 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5484 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5485 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5487 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5488 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5490 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5491 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5493 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5494 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5496 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5497 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5498 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5499 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5503 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5505 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5506 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5507 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5511 minput_get_commands (), minput_save_config ().
5514 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5517 MInputMethodInfo *im_info, *config;
5522 im_info = get_im_info (language, name, Mnil, Mvariable);
5524 MERROR (MERROR_IM, -1);
5525 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5527 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5528 MERROR (MERROR_IM, -1);
5530 if (value && ! MPLIST_TAIL_P (value))
5532 plist = MPLIST_PLIST (plist);
5533 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5534 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5535 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5536 if (MPLIST_KEY (plist) != Mt
5537 && ! check_variable_value (value, plist))
5538 MERROR (MERROR_IM, -1);
5541 config = get_config_info (im_info);
5544 if (! im_config_list)
5545 im_config_list = mplist ();
5546 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5547 config->cmds = mplist ();
5548 config->vars = mplist ();
5551 if (! value && MPLIST_TAIL_P (config->vars))
5552 /* Nothing to do. */
5555 if (variable == Mnil)
5559 /* Cancel the configuration. */
5560 if (MPLIST_TAIL_P (config->vars))
5562 mplist_set (config->vars, Mnil, NULL);
5566 /* Cancel the customization. */
5567 MInputMethodInfo *custom = get_custom_info (im_info);
5569 if (MPLIST_TAIL_P (config->vars)
5570 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5571 /* Nothing to do. */
5573 mplist_set (config->vars, Mnil, NULL);
5574 MPLIST_DO (plist, custom->vars)
5576 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5578 mplist_add (plist, Msymbol, variable);
5579 mplist_push (config->vars, Mplist, plist);
5580 M17N_OBJECT_UNREF (plist);
5586 plist = mplist__assq (config->vars, variable);
5589 /* Cancel the configuration. */
5592 mplist__pop_unref (plist);
5594 else if (MPLIST_TAIL_P (value))
5596 /* Cancel the customization. */
5597 MInputMethodInfo *custom = get_custom_info (im_info);
5598 int no_custom = (! custom || ! custom->vars
5599 || ! mplist__assq (custom->vars, variable));
5605 mplist_add (config->vars, Mplist, plist);
5606 M17N_OBJECT_UNREF (plist);
5607 plist = mplist_add (plist, Msymbol, variable);
5612 mplist__pop_unref (plist);
5615 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5616 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5617 mplist_set (plist, Mnil ,NULL);
5625 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5626 if (! MPLIST_TAIL_P (plist))
5627 mplist_set (plist, Mnil, NULL);
5632 mplist_add (config->vars, Mplist, plist);
5633 M17N_OBJECT_UNREF (plist);
5634 plist = mplist_add (plist, Msymbol, variable);
5635 plist = MPLIST_NEXT (plist);
5637 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5640 config_all_variables (im_info);
5641 im_info->tick = time (NULL);
5648 @brief Get the name of per-user customization file.
5650 The minput_config_file () function returns the absolute path name
5651 of per-user customization file into which minput_save_config ()
5652 save configurations. It is usually @c config.mic under the
5653 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5654 directory). It is not assured that the file of the returned name
5655 exists nor is readable/writable. If minput_save_config () fails
5656 and returns -1, an application program might check the file, make
5657 it writable (if possible), and try minput_save_config () again.
5661 This function returns a string. As the string is kept in the
5662 library, the caller must not modify nor free it.
5665 minput_save_config ()
5668 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5670 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5671 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5672 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5673 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5674 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5675 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5676 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5681 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5682 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5685 minput_save_config ()
5689 minput_config_file ()
5693 return mdatabase__file (im_custom_mdb);
5699 @brief Save configurations in per-user customization file.
5701 The minput_save_config () function saves the configurations done
5702 so far in the current session into the per-user customization
5707 If the operation was successful, 1 is returned. If the per-user
5708 customization file is currently locked, 0 is returned. In that
5709 case, the caller may wait for a while and try again. If the
5710 configuration file is not writable, -1 is returned. In that case,
5711 the caller may check the name of the file by calling
5712 minput_config_file (), make it writable if possible, and try
5716 minput_config_file () */
5718 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5720 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5721 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5725 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5726 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5727 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5728 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5732 minput_config_file () */
5735 minput_save_config (void)
5737 MPlist *data, *tail, *plist, *p, *elt;
5741 ret = mdatabase__lock (im_custom_mdb);
5744 if (! im_config_list)
5746 update_custom_info ();
5747 if (! im_custom_list)
5748 im_custom_list = mplist ();
5750 /* At first, reflect configuration in customization. */
5751 MPLIST_DO (plist, im_config_list)
5753 MPlist *pl = MPLIST_PLIST (plist);
5754 MSymbol language, name, extra, command, variable;
5755 MInputMethodInfo *custom, *config;
5757 language = MPLIST_SYMBOL (pl);
5758 pl = MPLIST_NEXT (pl);
5759 name = MPLIST_SYMBOL (pl);
5760 pl = MPLIST_NEXT (pl);
5761 extra = MPLIST_SYMBOL (pl);
5762 pl = MPLIST_NEXT (pl);
5763 config = MPLIST_VAL (pl);
5764 custom = get_custom_info (config);
5766 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5768 MPLIST_DO (pl, config->cmds)
5770 elt = MPLIST_PLIST (pl);
5771 command = MPLIST_SYMBOL (elt);
5773 p = mplist__assq (custom->cmds, command);
5775 custom->cmds = mplist (), p = NULL;
5776 elt = MPLIST_NEXT (elt);
5779 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5780 mplist_set (p, Mnil, NULL);
5785 mplist_add (custom->cmds, Mplist, p);
5786 M17N_OBJECT_UNREF (p);
5787 mplist_add (p, Msymbol, command);
5788 p = mplist_add (p, Msymbol, Mnil);
5789 p = MPLIST_NEXT (p);
5791 mplist__conc (p, elt);
5794 MPLIST_DO (pl, config->vars)
5796 elt = MPLIST_PLIST (pl);
5797 variable = MPLIST_SYMBOL (elt);
5799 p = mplist__assq (custom->vars, variable);
5801 custom->vars = mplist (), p = NULL;
5802 elt = MPLIST_NEXT (elt);
5805 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5806 mplist_set (p, Mnil, NULL);
5811 mplist_add (custom->vars, Mplist, p);
5812 M17N_OBJECT_UNREF (p);
5813 mplist_add (p, Msymbol, variable);
5814 p = mplist_add (p, Msymbol, Mnil);
5815 p = MPLIST_NEXT (p);
5817 mplist__conc (p, elt);
5820 free_im_list (im_config_list);
5821 im_config_list = NULL;
5823 /* Next, reflect customization to the actual plist to be written. */
5824 data = tail = mplist ();
5825 MPLIST_DO (plist, im_custom_list)
5827 MPlist *pl = MPLIST_PLIST (plist);
5828 MSymbol language, name, extra;
5829 MInputMethodInfo *custom, *im_info;
5831 language = MPLIST_SYMBOL (pl);
5832 pl = MPLIST_NEXT (pl);
5833 name = MPLIST_SYMBOL (pl);
5834 pl = MPLIST_NEXT (pl);
5835 extra = MPLIST_SYMBOL (pl);
5836 pl = MPLIST_NEXT (pl);
5837 custom = MPLIST_VAL (pl);
5838 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5839 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5841 im_info = lookup_im_info (im_info_list, language, name, extra);
5845 config_all_commands (im_info);
5847 config_all_variables (im_info);
5851 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5853 MPLIST_DO (p, custom->cmds)
5854 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5856 if (! MPLIST_TAIL_P (p))
5860 mplist_add (elt, Mplist, pl);
5861 M17N_OBJECT_UNREF (pl);
5862 pl = mplist_add (pl, Msymbol, Mcommand);
5863 MPLIST_DO (p, custom->cmds)
5864 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5865 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5868 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5870 MPLIST_DO (p, custom->vars)
5871 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5873 if (! MPLIST_TAIL_P (p))
5878 mplist_add (elt, Mplist, pl);
5879 M17N_OBJECT_UNREF (pl);
5880 pl = mplist_add (pl, Msymbol, Mvariable);
5881 MPLIST_DO (p, custom->vars)
5882 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5883 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5889 mplist_push (elt, Mplist, pl);
5890 M17N_OBJECT_UNREF (pl);
5891 pl = mplist_add (pl, Msymbol, Minput_method);
5892 pl = mplist_add (pl, Msymbol, language);
5893 pl = mplist_add (pl, Msymbol, name);
5895 pl = mplist_add (pl, Msymbol, extra);
5896 tail = mplist_add (tail, Mplist, elt);
5897 M17N_OBJECT_UNREF (elt);
5901 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5902 ret = mdatabase__save (im_custom_mdb, data);
5903 mdatabase__unlock (im_custom_mdb);
5904 M17N_OBJECT_UNREF (data);
5905 return (ret < 0 ? -1 : 1);
5912 @name Obsolete functions
5915 @name Obsolete ¤Ê´Ø¿ô
5921 @brief Get a list of variables of an input method (obsolete).
5923 This function is obsolete. Use minput_get_variable () instead.
5925 The minput_get_variables () function returns a plist (#MPlist) of
5926 variables used to control the behavior of the input method
5927 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5928 (@ref m17nPlist) of the following format:
5931 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5932 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5936 @c VARNAME is a symbol representing the variable name.
5938 @c DOC-MTEXT is an M-text describing the variable.
5940 @c DEFAULT-VALUE is the default value of the variable. It is a
5941 symbol, integer, or M-text.
5943 @c VALUEs (if any) specifies the possible values of the variable.
5944 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5945 @c TO), where @c FROM and @c TO specifies a range of possible
5948 For instance, suppose an input method has the variables:
5950 @li name:intvar, description:"value is an integer",
5951 initial value:0, value-range:0..3,10,20
5953 @li name:symvar, description:"value is a symbol",
5954 initial value:nil, value-range:a, b, c, nil
5956 @li name:txtvar, description:"value is an M-text",
5957 initial value:empty text, no value-range (i.e. any text)
5959 Then, the returned plist is as follows.
5962 (intvar ("value is an integer" 0 (0 3) 10 20)
5963 symvar ("value is a symbol" nil a b c nil)
5964 txtvar ("value is an M-text" ""))
5968 If the input method uses any variables, a pointer to #MPlist is
5969 returned. As the plist is kept in the library, the caller must not
5970 modify nor free it. If the input method does not use any
5971 variable, @c NULL is returned. */
5973 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5975 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5976 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5977 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5981 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5982 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5986 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5988 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5990 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5993 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5994 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5995 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5997 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5999 @li name:intvar, ÀâÌÀ:"value is an integer",
6000 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
6002 @li name:symvar, ÀâÌÀ:"value is a symbol",
6003 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
6005 @li name:txtvar, ÀâÌÀ:"value is an M-text",
6006 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
6008 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
6011 (intvar ("value is an integer" 0 (0 3) 10 20)
6012 symvar ("value is a symbol" nil a b c nil)
6013 txtvar ("value is an M-text" ""))
6017 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
6018 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6019 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
6022 minput_get_variables (MSymbol language, MSymbol name)
6024 MInputMethodInfo *im_info;
6029 im_info = get_im_info (language, name, Mnil, Mvariable);
6030 if (! im_info || ! im_info->configured_vars)
6033 M17N_OBJECT_UNREF (im_info->bc_vars);
6034 im_info->bc_vars = mplist ();
6035 MPLIST_DO (vars, im_info->configured_vars)
6037 MPlist *plist = MPLIST_PLIST (vars);
6038 MPlist *elt = mplist ();
6040 mplist_push (im_info->bc_vars, Mplist, elt);
6041 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6042 elt = MPLIST_NEXT (elt);
6043 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6044 M17N_OBJECT_UNREF (elt);
6046 return im_info->bc_vars;
6052 @brief Set the initial value of an input method variable.
6054 The minput_set_variable () function sets the initial value of
6055 input method variable $VARIABLE to $VALUE for the input method
6056 specified by $LANGUAGE and $NAME.
6058 By default, the initial value is 0.
6060 This setting gets effective in a newly opened input method.
6063 If the operation was successful, 0 is returned. Otherwise -1 is
6064 returned, and #merror_code is set to #MERROR_IM. */
6066 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6068 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6069 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6070 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6072 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6074 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6077 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6078 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6081 minput_set_variable (MSymbol language, MSymbol name,
6082 MSymbol variable, void *value)
6085 MInputMethodInfo *im_info;
6090 if (variable == Mnil)
6091 MERROR (MERROR_IM, -1);
6092 plist = minput_get_variable (language, name, variable);
6093 plist = MPLIST_PLIST (plist);
6094 plist = MPLIST_NEXT (plist);
6096 mplist_add (pl, MPLIST_KEY (plist), value);
6097 ret = minput_config_variable (language, name, variable, pl);
6098 M17N_OBJECT_UNREF (pl);
6101 im_info = get_im_info (language, name, Mnil, Mvariable);
6110 @brief Get information about input method commands.
6112 The minput_get_commands () function returns information about
6113 input method commands of the input method specified by $LANGUAGE
6114 and $NAME. An input method command is a pseudo key event to which
6115 one or more actual input key sequences are assigned.
6117 There are two kinds of commands, global and local. Global
6118 commands are used by multiple input methods for the same purpose,
6119 and have global key assignments. Local commands are used only by
6120 a specific input method, and have only local key assignments.
6122 Each input method may locally change key assignments for global
6123 commands. The global key assignment for a global command is
6124 effective only when the current input method does not have local
6125 key assignments for that command.
6127 If $NAME is #Mnil, information about global commands is returned.
6128 In this case $LANGUAGE is ignored.
6130 If $NAME is not #Mnil, information about those commands that have
6131 local key assignments in the input method specified by $LANGUAGE
6132 and $NAME is returned.
6135 If no input method commands are found, this function returns @c NULL.
6137 Otherwise, a pointer to a plist is returned. The key of each
6138 element in the plist is a symbol representing a command, and the
6139 value is a plist of the form COMMAND-INFO described below.
6141 The first element of COMMAND-INFO has the key #Mtext, and the
6142 value is an M-text describing the command.
6144 If there are no more elements, that means no key sequences are
6145 assigned to the command. Otherwise, each of the remaining
6146 elements has the key #Mplist, and the value is a plist whose keys are
6147 #Msymbol and values are symbols representing input keys, which are
6148 currently assigned to the command.
6150 As the returned plist is kept in the library, the caller must not
6151 modify nor free it. */
6153 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6155 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6156 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6157 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6158 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6160 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6161 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6162 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6163 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6165 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6166 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6167 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6170 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6171 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6173 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6174 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6178 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6180 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6181 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6182 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6184 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6185 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6186 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6189 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6190 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6191 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6192 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6193 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6195 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6196 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6199 minput_get_commands (MSymbol language, MSymbol name)
6201 MInputMethodInfo *im_info;
6206 im_info = get_im_info (language, name, Mnil, Mcommand);
6207 if (! im_info || ! im_info->configured_vars)
6209 M17N_OBJECT_UNREF (im_info->bc_cmds);
6210 im_info->bc_cmds = mplist ();
6211 MPLIST_DO (cmds, im_info->configured_cmds)
6213 MPlist *plist = MPLIST_PLIST (cmds);
6214 MPlist *elt = mplist ();
6216 mplist_push (im_info->bc_cmds, Mplist, elt);
6217 mplist_add (elt, MPLIST_SYMBOL (plist),
6218 mplist_copy (MPLIST_NEXT (plist)));
6219 M17N_OBJECT_UNREF (elt);
6221 return im_info->bc_cmds;
6227 @brief Assign a key sequence to an input method command (obsolete).
6229 This function is obsolete. Use minput_config_command () instead.
6231 The minput_assign_command_keys () function assigns input key
6232 sequence $KEYSEQ to input method command $COMMAND for the input
6233 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6234 key sequence is assigned globally no matter what $LANGUAGE is.
6235 Otherwise the key sequence is assigned locally.
6237 Each element of $KEYSEQ must have the key $Msymbol and the value
6238 must be a symbol representing an input key.
6240 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6241 globally or locally.
6243 This assignment gets effective in a newly opened input method.
6246 If the operation was successful, 0 is returned. Otherwise -1 is
6247 returned, and #merror_code is set to #MERROR_IM. */
6249 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6251 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6252 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6253 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6254 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6255 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6257 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6258 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6260 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6261 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6263 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6267 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6268 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6271 minput_assign_command_keys (MSymbol language, MSymbol name,
6272 MSymbol command, MPlist *keyseq)
6278 if (command == Mnil)
6279 MERROR (MERROR_IM, -1);
6284 if (! check_command_keyseq (keyseq))
6285 MERROR (MERROR_IM, -1);
6287 mplist_add (plist, Mplist, keyseq);
6292 ret = minput_config_command (language, name, command, keyseq);
6293 M17N_OBJECT_UNREF (keyseq);
6300 @brief Call a callback function
6302 The minput_callback () functions calls a callback function
6303 $COMMAND assigned for the input context $IC. The caller must set
6304 specific elements in $IC->plist if the callback function requires.
6307 If there exists a specified callback function, 0 is returned.
6308 Otherwise -1 is returned. By side effects, $IC->plist may be
6312 minput_callback (MInputContext *ic, MSymbol command)
6314 MInputCallbackFunc func;
6316 if (! ic->im->driver.callback_list)
6318 func = ((MInputCallbackFunc)
6319 mplist_get_func (ic->im->driver.callback_list, command));
6322 (func) (ic, command);
6329 /*** @addtogroup m17nDebug */
6335 @brief Dump an input method.
6337 The mdebug_dump_im () function prints the input method $IM in a
6338 human readable way to the stderr. $INDENT specifies how many
6339 columns to indent the lines but the first one.
6342 This function returns $IM. */
6344 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6346 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6347 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6350 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6353 mdebug_dump_im (MInputMethod *im, int indent)
6355 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6358 prefix = (char *) alloca (indent + 1);
6359 memset (prefix, 32, indent);
6360 prefix[indent] = '\0';
6362 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6363 msymbol_name (im->name));
6364 mdebug_dump_mtext (im_info->title, 0, 0);
6365 if (im->name != Mnil)
6369 MPLIST_DO (state, im_info->states)
6371 fprintf (stderr, "\n%s ", prefix);
6372 dump_im_state (MPLIST_VAL (state), indent + 2);
6375 fprintf (stderr, ")");