1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32], buf3[2];
284 /* Maximum case: '\215', C-M-m, C-M-M, M-Return, C-A-m, C-A-M, A-Return. */
287 M_key_alias = msymbol (" key-alias");
289 /* Aliases for 0x00-0x1F */
293 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
296 alias[j++] = one_char_symbol[i] = msymbol (buf);
297 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
312 /* Establish cyclic alias chain. */
315 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 /* Aliases for 0x20-0x7E */
320 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
322 one_char_symbol[i] = msymbol (buf + 2);
323 if (i >= 'A' && i <= 'Z')
325 /* Ex: `A' == `S-A' == `S-a'. */
326 alias[0] = alias[3] = one_char_symbol[i];
327 alias[1] = msymbol (buf);
329 alias[2] = msymbol (buf);
331 for (j = 0; j < 3; j++)
332 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
336 /* Aliases for 0x7F */
337 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
338 alias[1] = msymbol ("C-?");
339 for (j = 0; j < 2; j++)
340 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
342 /* Aliases for 0x80-0x9F */
344 /* buf[1] = '-'; -- already done */
349 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
353 alias[j++] = msymbol (buf3);
354 /* `C-M-a' == `C-A-a' */
356 alias[j++] = one_char_symbol[i] = msymbol (buf);
358 alias[j++] = msymbol (buf);
359 if (key_names[i - 128])
361 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
363 strcpy (buf2 + 2, key_names[i - 128]);
364 alias[j++] = msymbol (buf2);
366 alias[j++] = msymbol (buf2);
368 if (buf[4] >= 'A' && buf[4] <= 'Z')
370 /* Ex: `C-M-a' == `C-M-A'. */
373 alias[j++] = msymbol (buf);
375 alias[j++] = msymbol (buf);
378 /* Establish cyclic alias chain. */
381 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
384 /* Aliases for 0xA0-0xFF */
385 for (i = 160, buf[4] = ' '; i < 255; i++, buf[4]++)
388 alias[j++] = msymbol (buf3);
390 alias[j++] = one_char_symbol[i] = msymbol (buf + 2);
392 alias[j++] = msymbol (buf + 2);
395 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
396 if (buf[4] < 'A' || (buf[4] > 'Z' && buf[4] < 'a') || buf[4] > 'z')
399 alias[0] = alias[2] = msymbol (buf);
401 alias[1] = msymbol (buf);
402 for (j = 0; j < 2; j++)
403 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
408 alias[0] = alias[5] = msymbol (buf);
409 alias[1] = one_char_symbol[255] = msymbol ("M-Delete");
410 alias[2] = msymbol ("A-Delete");
411 alias[3] = msymbol ("C-M-?");
412 alias[4] = msymbol ("C-A-?");
413 for (j = 0; j < 5; j++)
414 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
416 Minput_method = msymbol ("input-method");
417 Mtitle = msymbol ("title");
418 Mmacro = msymbol ("macro");
419 Mmodule = msymbol ("module");
420 Mmap = msymbol ("map");
421 Mstate = msymbol ("state");
422 Minclude = msymbol ("include");
423 Minsert = msymbol ("insert");
424 M_candidates = msymbol (" candidates");
425 Mdelete = msymbol ("delete");
426 Mmove = msymbol ("move");
427 Mmark = msymbol ("mark");
428 Mpushback = msymbol ("pushback");
429 Mpop = msymbol ("pop");
430 Mundo = msymbol ("undo");
431 Mcall = msymbol ("call");
432 Mshift = msymbol ("shift");
433 Mselect = msymbol ("select");
434 Mshow = msymbol ("show");
435 Mhide = msymbol ("hide");
436 Mcommit = msymbol ("commit");
437 Munhandle = msymbol ("unhandle");
438 Mset = msymbol ("set");
439 Madd = msymbol ("add");
440 Msub = msymbol ("sub");
441 Mmul = msymbol ("mul");
442 Mdiv = msymbol ("div");
443 Mequal = msymbol ("=");
444 Mless = msymbol ("<");
445 Mgreater = msymbol (">");
446 Mless_equal = msymbol ("<=");
447 Mgreater_equal = msymbol (">=");
448 Mcond = msymbol ("cond");
449 Mplus = msymbol ("+");
450 Mminus = msymbol ("-");
451 Mstar = msymbol ("*");
452 Mslash = msymbol ("/");
453 Mand = msymbol ("&");
455 Mnot = msymbol ("!");
457 Mat_reload = msymbol ("@reload");
459 Mcandidates_group_size = msymbol ("candidates-group-size");
460 Mcandidates_charset = msymbol ("candidates-charset");
462 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
463 Mcandidate_index = msymbol (" candidate-index");
465 Minit = msymbol ("init");
466 Mfini = msymbol ("fini");
468 Mdescription = msymbol ("description");
469 Mcommand = msymbol ("command");
470 Mvariable = msymbol ("variable");
471 Mglobal = msymbol ("global");
472 Mconfig = msymbol ("config");
473 M_gettext = msymbol ("_");
475 load_im_info_keys = mplist ();
476 mplist_add (load_im_info_keys, Mstate, Mnil);
477 mplist_push (load_im_info_keys, Mmap, Mnil);
479 im_info_list = mplist ();
480 im_config_list = im_custom_list = NULL;
481 im_custom_mdb = NULL;
482 update_custom_info ();
484 update_global_info ();
486 fully_initialized = 1;
489 #define MINPUT__INIT() \
491 if (! fully_initialized) \
492 fully_initialize (); \
497 marker_code (MSymbol sym, int surrounding)
503 name = MSYMBOL_NAME (sym);
504 return (name[0] != '@' ? -1
505 : (((name[1] >= '0' && name[1] <= '9')
506 || name[1] == '<' || name[1] == '>' || name[1] == '='
507 || name[1] == '[' || name[1] == ']'
509 && name[2] == '\0') ? name[1]
510 : (name[1] != '+' && name[1] != '-') ? -1
511 : (name[2] == '\0' || surrounding) ? name[1]
516 /* Return a plist containing an integer value of VAR. */
519 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
521 MPlist *plist = mplist__assq (ic_info->vars, var);
525 plist = MPLIST_PLIST (plist);
526 return MPLIST_NEXT (plist);
530 mplist_push (ic_info->vars, Mplist, plist);
531 M17N_OBJECT_UNREF (plist);
532 plist = mplist_add (plist, Msymbol, var);
533 plist = mplist_add (plist, Minteger, (void *) 0);
538 get_surrounding_text (MInputContext *ic, int len)
542 mplist_push (ic->plist, Minteger, (void *) len);
543 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
544 && MPLIST_MTEXT_P (ic->plist))
545 mt = MPLIST_MTEXT (ic->plist);
546 mplist_pop (ic->plist);
551 delete_surrounding_text (MInputContext *ic, int pos)
553 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
555 mplist_push (ic->plist, Minteger, (void *) pos);
556 minput_callback (ic, Minput_delete_surrounding_text);
557 mplist_pop (ic->plist);
560 M17N_OBJECT_UNREF (ic_info->preceding_text);
561 ic_info->preceding_text = NULL;
565 M17N_OBJECT_UNREF (ic_info->following_text);
566 ic_info->following_text = NULL;
571 get_preceding_char (MInputContext *ic, int pos)
573 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
577 if (pos && ic_info->preceding_text)
579 len = mtext_nchars (ic_info->preceding_text);
581 return mtext_ref_char (ic_info->preceding_text, len - pos);
583 mt = get_surrounding_text (ic, - pos);
586 len = mtext_nchars (mt);
587 if (ic_info->preceding_text)
589 if (mtext_nchars (ic_info->preceding_text) < len)
591 M17N_OBJECT_UNREF (ic_info->preceding_text);
592 ic_info->preceding_text = mt;
595 M17N_OBJECT_UNREF (mt);
598 ic_info->preceding_text = mt;
601 return mtext_ref_char (ic_info->preceding_text, len - pos);
605 get_following_char (MInputContext *ic, int pos)
607 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
611 if (ic_info->following_text)
613 len = mtext_nchars (ic_info->following_text);
615 return mtext_ref_char (ic_info->following_text, pos);
617 mt = get_surrounding_text (ic, pos + 1);
620 len = mtext_nchars (mt);
621 if (ic_info->following_text)
623 if (mtext_nchars (ic_info->following_text) < len)
625 M17N_OBJECT_UNREF (ic_info->following_text);
626 ic_info->following_text = mt;
629 M17N_OBJECT_UNREF (mt);
632 ic_info->following_text = mt;
635 return mtext_ref_char (ic_info->following_text, pos);
639 surrounding_pos (MSymbol sym)
645 name = MSYMBOL_NAME (sym);
647 && (name[1] == '-' || name[1] == '+')
648 && name[2] >= '1' && name[2] <= '9')
649 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
654 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
656 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
658 MText *preedit = ic->preedit;
659 int len = mtext_nchars (preedit);
661 if (MPLIST_INTEGER_P (arg))
662 return MPLIST_INTEGER (arg);
664 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
667 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
669 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
672 return ic_info->key_head;
673 if ((code == '-' || code == '+'))
675 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
679 pos = atoi (name + 1);
681 return get_preceding_char (ic, 0);
683 pos = ic->cursor_pos + pos;
685 pos = ic->cursor_pos + pos - 1;
688 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
689 return mtext_ref_char (ic->produced,
690 mtext_len (ic->produced) + pos);
691 return get_preceding_char (ic, - pos);
694 return get_following_char (ic, pos - len);
697 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
699 else if (code >= '0' && code <= '9')
701 else if (code == '=')
702 pos = ic->cursor_pos;
703 else if (code == '[')
704 pos = ic->cursor_pos - 1;
705 else if (code == ']')
706 pos = ic->cursor_pos + 1;
707 else if (code == '<')
709 else if (code == '>')
711 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
715 parse_expression (MPlist *plist)
719 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
721 if (! MPLIST_PLIST_P (plist))
723 plist = MPLIST_PLIST (plist);
724 op = MPLIST_SYMBOL (plist);
725 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
726 && op != Mand && op != Mor && op != Mnot
727 && op != Mless && op != Mgreater && op != Mequal
728 && op != Mless_equal && op != Mgreater_equal)
729 MERROR (MERROR_IM, -1);
730 MPLIST_DO (plist, MPLIST_NEXT (plist))
731 if (parse_expression (plist) < 0)
737 resolve_expression (MInputContext *ic, MPlist *plist)
742 if (MPLIST_INTEGER_P (plist))
743 return MPLIST_INTEGER (plist);
744 if (MPLIST_SYMBOL_P (plist))
745 return integer_value (ic, plist, 1);
746 if (! MPLIST_PLIST_P (plist))
748 plist = MPLIST_PLIST (plist);
749 if (! MPLIST_SYMBOL_P (plist))
751 op = MPLIST_SYMBOL (plist);
752 plist = MPLIST_NEXT (plist);
753 val = resolve_expression (ic, plist);
755 MPLIST_DO (plist, MPLIST_NEXT (plist))
756 val += resolve_expression (ic, plist);
757 else if (op == Mminus)
758 MPLIST_DO (plist, MPLIST_NEXT (plist))
759 val -= resolve_expression (ic, plist);
760 else if (op == Mstar)
761 MPLIST_DO (plist, MPLIST_NEXT (plist))
762 val *= resolve_expression (ic, plist);
763 else if (op == Mslash)
764 MPLIST_DO (plist, MPLIST_NEXT (plist))
765 val /= resolve_expression (ic, plist);
767 MPLIST_DO (plist, MPLIST_NEXT (plist))
768 val &= resolve_expression (ic, plist);
770 MPLIST_DO (plist, MPLIST_NEXT (plist))
771 val |= resolve_expression (ic, plist);
774 else if (op == Mless)
775 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
776 else if (op == Mequal)
777 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
778 else if (op == Mgreater)
779 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
780 else if (op == Mless_equal)
781 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
782 else if (op == Mgreater_equal)
783 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
787 /* Parse PLIST as an action list. PLIST should have this form:
788 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
789 Return 0 if successfully parsed, otherwise return -1. */
792 parse_action_list (MPlist *plist, MPlist *macros)
794 MPLIST_DO (plist, plist)
796 if (MPLIST_MTEXT_P (plist))
798 /* This is a short form of (insert MTEXT). */
799 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
800 MERROR (MERROR_IM, -1); */
802 else if (MPLIST_PLIST_P (plist)
803 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
804 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
808 /* This is a short form of (insert (GROUPS *)). */
809 MPLIST_DO (pl, MPLIST_PLIST (plist))
811 if (MPLIST_PLIST_P (pl))
815 MPLIST_DO (elt, MPLIST_PLIST (pl))
816 if (! MPLIST_MTEXT_P (elt)
817 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
818 MERROR (MERROR_IM, -1);
822 if (! MPLIST_MTEXT_P (pl)
823 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
824 MERROR (MERROR_IM, -1);
828 else if (MPLIST_INTEGER_P (plist))
830 int c = MPLIST_INTEGER (plist);
832 if (c < 0 || c > MCHAR_MAX)
833 MERROR (MERROR_IM, -1);
835 else if (MPLIST_PLIST_P (plist)
836 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
838 MPlist *pl = MPLIST_PLIST (plist);
839 MSymbol action_name = MPLIST_SYMBOL (pl);
841 pl = MPLIST_NEXT (pl);
843 if (action_name == M_candidates)
845 /* This is an already regularised action. */
848 if (action_name == Minsert)
850 if (MPLIST_MTEXT_P (pl))
852 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
853 MERROR (MERROR_IM, -1);
855 else if (MPLIST_INTEGER_P (pl))
857 int c = MPLIST_INTEGER (pl);
859 if (c < 0 || c > MCHAR_MAX)
860 MERROR (MERROR_IM, -1);
862 else if (MPLIST_PLIST_P (pl))
864 MPLIST_DO (pl, MPLIST_PLIST (pl))
866 if (MPLIST_PLIST_P (pl))
870 MPLIST_DO (elt, MPLIST_PLIST (pl))
871 if (! MPLIST_MTEXT_P (elt)
872 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
873 MERROR (MERROR_IM, -1);
877 if (! MPLIST_MTEXT_P (pl)
878 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
879 MERROR (MERROR_IM, -1);
883 else if (! MPLIST_SYMBOL_P (pl))
884 MERROR (MERROR_IM, -1);
886 else if (action_name == Mselect
887 || action_name == Mdelete
888 || action_name == Mmove)
890 if (parse_expression (pl) < 0)
893 else if (action_name == Mmark
894 || action_name == Mcall
895 || action_name == Mshift)
897 if (! MPLIST_SYMBOL_P (pl))
898 MERROR (MERROR_IM, -1);
900 else if (action_name == Mundo)
902 if (! MPLIST_TAIL_P (pl))
904 if (! MPLIST_SYMBOL_P (pl)
905 && ! MPLIST_INTEGER_P (pl))
906 MERROR (MERROR_IM, -1);
909 else if (action_name == Mpushback)
911 if (MPLIST_MTEXT_P (pl))
913 MText *mt = MPLIST_MTEXT (pl);
915 if (mtext_nchars (mt) != mtext_nbytes (mt))
916 MERROR (MERROR_IM, -1);
918 else if (MPLIST_PLIST_P (pl))
922 MPLIST_DO (p, MPLIST_PLIST (pl))
923 if (! MPLIST_SYMBOL_P (p))
924 MERROR (MERROR_IM, -1);
926 else if (! MPLIST_INTEGER_P (pl))
927 MERROR (MERROR_IM, -1);
929 else if (action_name == Mset || action_name == Madd
930 || action_name == Msub || action_name == Mmul
931 || action_name == Mdiv)
933 if (! MPLIST_SYMBOL_P (pl))
934 MERROR (MERROR_IM, -1);
935 if (parse_expression (MPLIST_NEXT (pl)) < 0)
938 else if (action_name == Mequal || action_name == Mless
939 || action_name == Mgreater || action_name == Mless_equal
940 || action_name == Mgreater_equal)
942 if (parse_expression (pl) < 0
943 || parse_expression (MPLIST_NEXT (pl)) < 0)
945 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
946 if (! MPLIST_PLIST_P (pl))
947 MERROR (MERROR_IM, -1);
948 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
949 MERROR (MERROR_IM, -1);
950 pl = MPLIST_NEXT (pl);
951 if (MPLIST_PLIST_P (pl)
952 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
953 MERROR (MERROR_IM, -1);
955 else if (action_name == Mshow || action_name == Mhide
956 || action_name == Mcommit || action_name == Munhandle
957 || action_name == Mpop)
959 else if (action_name == Mcond)
962 if (! MPLIST_PLIST_P (pl))
963 MERROR (MERROR_IM, -1);
965 else if (! macros || ! mplist_get (macros, action_name))
966 MERROR (MERROR_IM, -1);
968 else if (! MPLIST_SYMBOL_P (plist))
969 MERROR (MERROR_IM, -1);
976 resolve_command (MPlist *cmds, MSymbol command)
980 if (! cmds || ! (plist = mplist__assq (cmds, command)))
982 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
983 plist = MPLIST_NEXT (plist);
984 plist = MPLIST_NEXT (plist);
985 plist = MPLIST_NEXT (plist);
989 /* Load a translation into MAP from PLIST.
991 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
994 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
995 MPlist *branch_actions, MPlist *macros)
1000 if (MPLIST_MTEXT_P (keylist))
1002 MText *mt = MPLIST_MTEXT (keylist);
1004 len = mtext_nchars (mt);
1005 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
1007 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1008 for (i = 0; i < len; i++)
1009 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1015 if (MFAILP (MPLIST_PLIST_P (keylist)))
1017 elt = MPLIST_PLIST (keylist);
1018 len = MPLIST_LENGTH (elt);
1019 if (MFAILP (len > 0))
1021 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1022 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1024 if (MPLIST_INTEGER_P (elt))
1026 int c = MPLIST_INTEGER (elt);
1028 if (MFAILP (c >= 0 && c < 0x100))
1030 keyseq[i] = one_char_symbol[c];
1034 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1036 keyseq[i] = MPLIST_SYMBOL (elt);
1041 for (i = 0; i < len; i++)
1043 MIMMap *deeper = NULL;
1046 deeper = mplist_get (map->submaps, keyseq[i]);
1048 map->submaps = mplist ();
1051 /* Fixme: It is better to make all deeper maps at once. */
1052 MSTRUCT_CALLOC (deeper, MERROR_IM);
1053 mplist_put (map->submaps, keyseq[i], deeper);
1058 /* We reach a terminal map. */
1059 if (map->map_actions
1060 || map->branch_actions)
1061 /* This map is already defined. We avoid overriding it. */
1064 if (! MPLIST_TAIL_P (map_actions))
1066 if (parse_action_list (map_actions, macros) < 0)
1067 MERROR (MERROR_IM, -1);
1068 map->map_actions = map_actions;
1072 map->branch_actions = branch_actions;
1073 M17N_OBJECT_REF (branch_actions);
1079 /* Load a branch from PLIST into MAP. PLIST has this form:
1080 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1083 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1086 MPlist *branch_actions;
1088 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1090 map_name = MPLIST_SYMBOL (plist);
1091 plist = MPLIST_NEXT (plist);
1092 if (MPLIST_TAIL_P (plist))
1093 branch_actions = NULL;
1094 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1097 branch_actions = plist;
1098 if (map_name == Mnil)
1100 map->branch_actions = branch_actions;
1102 M17N_OBJECT_REF (branch_actions);
1104 else if (map_name == Mt)
1106 map->map_actions = branch_actions;
1108 M17N_OBJECT_REF (branch_actions);
1110 else if (im_info->maps)
1112 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1113 if (! plist && im_info->configured_vars)
1115 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1117 if (p && MPLIST_PLIST_P (p))
1119 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1120 if (MPLIST_SYMBOL_P (p))
1121 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1126 MPLIST_DO (plist, plist)
1128 MPlist *keylist, *map_actions;
1130 if (! MPLIST_PLIST_P (plist))
1131 MERROR (MERROR_IM, -1);
1132 keylist = MPLIST_PLIST (plist);
1133 map_actions = MPLIST_NEXT (keylist);
1134 if (MPLIST_SYMBOL_P (keylist))
1136 MSymbol command = MPLIST_SYMBOL (keylist);
1139 if (MFAILP (command != Mat_reload))
1141 pl = resolve_command (im_info->configured_cmds, command);
1145 load_translation (map, pl, map_actions, branch_actions,
1149 load_translation (map, keylist, map_actions, branch_actions,
1158 /* Load a macro from PLIST into IM_INFO->macros.
1159 PLIST has this from:
1160 PLIST ::= ( MACRO-NAME ACTION * )
1161 IM_INFO->macros is a plist of macro names vs action list. */
1164 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1169 if (! MPLIST_SYMBOL_P (plist))
1170 MERROR (MERROR_IM, -1);
1171 name = MPLIST_SYMBOL (plist);
1172 plist = MPLIST_NEXT (plist);
1173 if (MPLIST_TAIL_P (plist)
1174 || parse_action_list (plist, im_info->macros) < 0)
1175 MERROR (MERROR_IM, -1);
1176 pl = mplist_get (im_info->macros, name);
1177 M17N_OBJECT_UNREF (pl);
1178 mplist_put (im_info->macros, name, plist);
1179 M17N_OBJECT_REF (plist);
1183 /* Load an external module from PLIST into IM_INFO->externals.
1184 PLIST has this form:
1185 PLIST ::= ( MODULE-NAME FUNCTION * )
1186 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1189 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1194 MIMExternalModule *external;
1198 if (MPLIST_MTEXT_P (plist))
1199 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1200 else if (MPLIST_SYMBOL_P (plist))
1201 module = MPLIST_SYMBOL (plist);
1202 module_file = alloca (strlen (MSYMBOL_NAME (module))
1203 + strlen (DLOPEN_SHLIB_EXT) + 1);
1204 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1206 handle = dlopen (module_file, RTLD_NOW);
1207 if (MFAILP (handle))
1209 fprintf (stderr, "%s\n", dlerror ());
1212 func_list = mplist ();
1213 MPLIST_DO (plist, MPLIST_NEXT (plist))
1215 if (! MPLIST_SYMBOL_P (plist))
1216 MERROR_GOTO (MERROR_IM, err_label);
1217 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1220 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1223 MSTRUCT_MALLOC (external, MERROR_IM);
1224 external->handle = handle;
1225 external->func_list = func_list;
1226 mplist_add (im_info->externals, module, external);
1231 M17N_OBJECT_UNREF (func_list);
1236 free_map (MIMMap *map, int top)
1241 M17N_OBJECT_UNREF (map->map_actions);
1244 MPLIST_DO (plist, map->submaps)
1245 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1246 M17N_OBJECT_UNREF (map->submaps);
1248 M17N_OBJECT_UNREF (map->branch_actions);
1253 free_state (void *object)
1255 MIMState *state = object;
1257 M17N_OBJECT_UNREF (state->title);
1259 free_map (state->map, 1);
1263 /** Load a state from PLIST into a newly allocated state object.
1264 PLIST has this form:
1265 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1266 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1267 Return the state object. */
1270 load_state (MInputMethodInfo *im_info, MPlist *plist)
1274 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1276 M17N_OBJECT (state, free_state, MERROR_IM);
1277 state->name = MPLIST_SYMBOL (plist);
1278 plist = MPLIST_NEXT (plist);
1279 if (MPLIST_MTEXT_P (plist))
1281 state->title = MPLIST_MTEXT (plist);
1282 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1283 Mlanguage, im_info->language);
1284 M17N_OBJECT_REF (state->title);
1285 plist = MPLIST_NEXT (plist);
1287 MSTRUCT_CALLOC (state->map, MERROR_IM);
1288 MPLIST_DO (plist, plist)
1290 if (MFAILP (MPLIST_PLIST_P (plist)))
1292 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1297 /* Return a newly created IM_INFO for an input method specified by
1298 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1300 static MInputMethodInfo *
1301 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1304 MInputMethodInfo *im_info;
1307 if (name == Mnil && extra == Mnil)
1308 language = Mt, extra = Mglobal;
1309 MSTRUCT_CALLOC (im_info, MERROR_IM);
1311 im_info->language = language;
1312 im_info->name = name;
1313 im_info->extra = extra;
1316 mplist_add (plist, Mplist, elt);
1317 M17N_OBJECT_UNREF (elt);
1318 elt = mplist_add (elt, Msymbol, language);
1319 elt = mplist_add (elt, Msymbol, name);
1320 elt = mplist_add (elt, Msymbol, extra);
1321 mplist_add (elt, Mt, im_info);
1327 fini_im_info (MInputMethodInfo *im_info)
1331 M17N_OBJECT_UNREF (im_info->cmds);
1332 M17N_OBJECT_UNREF (im_info->configured_cmds);
1333 M17N_OBJECT_UNREF (im_info->bc_cmds);
1334 M17N_OBJECT_UNREF (im_info->vars);
1335 M17N_OBJECT_UNREF (im_info->configured_vars);
1336 M17N_OBJECT_UNREF (im_info->bc_vars);
1337 M17N_OBJECT_UNREF (im_info->description);
1338 M17N_OBJECT_UNREF (im_info->title);
1339 if (im_info->states)
1341 MPLIST_DO (plist, im_info->states)
1343 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1345 M17N_OBJECT_UNREF (state);
1347 M17N_OBJECT_UNREF (im_info->states);
1350 if (im_info->macros)
1352 MPLIST_DO (plist, im_info->macros)
1353 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1354 M17N_OBJECT_UNREF (im_info->macros);
1357 if (im_info->externals)
1359 MPLIST_DO (plist, im_info->externals)
1361 MIMExternalModule *external = MPLIST_VAL (plist);
1363 dlclose (external->handle);
1364 M17N_OBJECT_UNREF (external->func_list);
1366 MPLIST_KEY (plist) = Mt;
1368 M17N_OBJECT_UNREF (im_info->externals);
1372 MPLIST_DO (plist, im_info->maps)
1374 MPlist *p = MPLIST_PLIST (plist);
1376 M17N_OBJECT_UNREF (p);
1378 M17N_OBJECT_UNREF (im_info->maps);
1385 free_im_info (MInputMethodInfo *im_info)
1387 fini_im_info (im_info);
1392 free_im_list (MPlist *plist)
1396 MPLIST_DO (pl, plist)
1398 MInputMethodInfo *im_info;
1400 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1401 im_info = MPLIST_VAL (elt);
1402 free_im_info (im_info);
1404 M17N_OBJECT_UNREF (plist);
1407 static MInputMethodInfo *
1408 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1410 if (name == Mnil && extra == Mnil)
1411 language = Mt, extra = Mglobal;
1412 while ((plist = mplist__assq (plist, language)))
1414 MPlist *elt = MPLIST_PLIST (plist);
1416 plist = MPLIST_NEXT (plist);
1417 elt = MPLIST_NEXT (elt);
1418 if (MPLIST_SYMBOL (elt) != name)
1420 elt = MPLIST_NEXT (elt);
1421 if (MPLIST_SYMBOL (elt) != extra)
1423 elt = MPLIST_NEXT (elt);
1424 return MPLIST_VAL (elt);
1429 static void load_im_info (MPlist *, MInputMethodInfo *);
1431 #define get_custom_info(im_info) \
1433 ? lookup_im_info (im_custom_list, (im_info)->language, \
1434 (im_info)->name, (im_info)->extra) \
1437 #define get_config_info(im_info) \
1439 ? lookup_im_info (im_config_list, (im_info)->language, \
1440 (im_info)->name, (im_info)->extra) \
1444 update_custom_info (void)
1450 if (mdatabase__check (im_custom_mdb) > 0)
1455 MDatabaseInfo *custom_dir_info;
1456 char custom_path[PATH_MAX + 1];
1458 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1459 if (! custom_dir_info->filename
1460 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1462 strcpy (custom_path, custom_dir_info->filename);
1463 strcat (custom_path, CUSTOM_FILE);
1464 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1470 free_im_list (im_custom_list);
1471 im_custom_list = NULL;
1473 plist = mdatabase_load (im_custom_mdb);
1476 im_custom_list = mplist ();
1478 MPLIST_DO (pl, plist)
1480 MSymbol language, name, extra;
1481 MInputMethodInfo *im_info;
1482 MPlist *im_data, *p;
1484 if (! MPLIST_PLIST_P (pl))
1486 p = MPLIST_PLIST (pl);
1487 im_data = MPLIST_NEXT (p);
1488 if (! MPLIST_PLIST_P (p))
1490 p = MPLIST_PLIST (p);
1491 if (! MPLIST_SYMBOL_P (p)
1492 || MPLIST_SYMBOL (p) != Minput_method)
1494 p = MPLIST_NEXT (p);
1495 if (! MPLIST_SYMBOL_P (p))
1497 language = MPLIST_SYMBOL (p);
1498 p = MPLIST_NEXT (p);
1499 if (! MPLIST_SYMBOL_P (p))
1501 name = MPLIST_SYMBOL (p);
1502 p = MPLIST_NEXT (p);
1503 if (MPLIST_TAIL_P (p))
1505 else if (MPLIST_SYMBOL_P (p))
1506 extra = MPLIST_SYMBOL (p);
1507 if (language == Mnil || (name == Mnil && extra == Mnil))
1509 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1510 load_im_info (im_data, im_info);
1512 M17N_OBJECT_UNREF (plist);
1517 update_global_info (void)
1523 int ret = mdatabase__check (global_info->mdb);
1527 fini_im_info (global_info);
1531 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1535 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1537 if (! global_info->mdb
1538 || ! (plist = mdatabase_load (global_info->mdb)))
1541 load_im_info (plist, global_info);
1542 M17N_OBJECT_UNREF (plist);
1547 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1548 and EXTRA. KEY, if not Mnil, tells which kind of information about
1549 the input method is necessary, and the returned IM_INFO may contain
1550 only that information. */
1552 static MInputMethodInfo *
1553 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1556 MInputMethodInfo *im_info;
1559 if (name == Mnil && extra == Mnil)
1560 language = Mt, extra = Mglobal;
1561 im_info = lookup_im_info (im_info_list, language, name, extra);
1564 if (key == Mnil ? im_info->states != NULL
1565 : key == Mcommand ? im_info->cmds != NULL
1566 : key == Mvariable ? im_info->vars != NULL
1567 : key == Mtitle ? im_info->title != NULL
1568 : key == Mdescription ? im_info->description != NULL
1570 /* IM_INFO already contains required information. */
1572 /* We have not yet loaded required information. */
1576 mdb = mdatabase_find (Minput_method, language, name, extra);
1579 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1584 plist = mdatabase_load (im_info->mdb);
1588 mplist_push (load_im_info_keys, key, Mt);
1589 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1590 mplist_pop (load_im_info_keys);
1594 MERROR (MERROR_IM, im_info);
1595 update_global_info ();
1596 load_im_info (plist, im_info);
1597 M17N_OBJECT_UNREF (plist);
1600 if (! im_info->cmds)
1601 im_info->cmds = mplist ();
1602 if (! im_info->vars)
1603 im_info->vars = mplist ();
1604 if (! im_info->states)
1605 im_info->states = mplist ();
1607 if (! im_info->title
1608 && (key == Mnil || key == Mtitle))
1609 im_info->title = (name == Mnil ? mtext ()
1610 : mtext_from_data (MSYMBOL_NAME (name),
1611 MSYMBOL_NAMELEN (name),
1612 MTEXT_FORMAT_US_ASCII));
1616 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1617 If updated, but got unloadable, return -1. Otherwise, update
1618 contents of IM_INFO from the new database, and return 1. */
1621 reload_im_info (MInputMethodInfo *im_info)
1626 update_custom_info ();
1627 update_global_info ();
1628 check = mdatabase__check (im_info->mdb);
1631 plist = mdatabase_load (im_info->mdb);
1634 fini_im_info (im_info);
1635 load_im_info (plist, im_info);
1636 M17N_OBJECT_UNREF (plist);
1637 if (! im_info->cmds)
1638 im_info->cmds = mplist ();
1639 if (! im_info->vars)
1640 im_info->vars = mplist ();
1641 if (! im_info->title)
1643 MSymbol name = im_info->name;
1645 im_info->title = (name == Mnil ? mtext ()
1646 : mtext_from_data (MSYMBOL_NAME (name),
1647 MSYMBOL_NAMELEN (name),
1648 MTEXT_FORMAT_US_ASCII));
1653 static MInputMethodInfo *
1654 get_im_info_by_tags (MPlist *plist)
1659 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1660 i++, plist = MPLIST_NEXT (plist))
1661 tag[i] = MPLIST_SYMBOL (plist);
1666 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1671 check_description (MPlist *plist)
1675 if (MPLIST_MTEXT_P (plist))
1677 if (MPLIST_PLIST_P (plist))
1679 MPlist *pl = MPLIST_PLIST (plist);
1681 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1683 pl =MPLIST_NEXT (pl);
1684 if (MFAILP (MPLIST_MTEXT_P (pl)))
1686 mt = MPLIST_MTEXT (pl);
1687 M17N_OBJECT_REF (mt);
1690 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1692 if (translated == (char *) MTEXT_DATA (mt))
1693 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1694 if (translated != (char *) MTEXT_DATA (mt))
1696 M17N_OBJECT_UNREF (mt);
1697 mt = mtext__from_data (translated, strlen (translated),
1698 MTEXT_FORMAT_UTF_8, 1);
1702 mplist_set (plist, Mtext, mt);
1703 M17N_OBJECT_UNREF (mt);
1706 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1712 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1716 check_command_keyseq (MPlist *keyseq)
1718 if (MPLIST_PLIST_P (keyseq))
1720 MPlist *p = MPLIST_PLIST (keyseq);
1723 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1727 if (MPLIST_MTEXT_P (keyseq))
1729 MText *mt = MPLIST_MTEXT (keyseq);
1732 for (i = 0; i < mtext_nchars (mt); i++)
1733 if (mtext_ref_char (mt, i) >= 256)
1740 /* Load command defitions from PLIST into IM_INFO->cmds.
1742 PLIST is well-formed and has this form;
1743 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1744 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1745 M-text or a plist of symbols.
1747 The returned list has the same form, but for each element...
1749 (1) If DESCRIPTION and the rest are omitted, the element is not
1750 stored in the returned list.
1752 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1753 description in global_info->cmds (if any). */
1756 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1760 im_info->cmds = tail = mplist ();
1762 MPLIST_DO (plist, MPLIST_NEXT (plist))
1764 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1767 if (MFAILP (MPLIST_PLIST_P (plist)))
1769 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1770 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1772 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1773 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1775 if (MFAILP (im_info != global_info))
1776 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1780 if (! check_description (p))
1781 mplist_set (p, Msymbol, Mnil);
1782 p = MPLIST_NEXT (p);
1783 while (! MPLIST_TAIL_P (p))
1785 if (MFAILP (check_command_keyseq (p)))
1786 mplist__pop_unref (p);
1788 p = MPLIST_NEXT (p);
1791 tail = mplist_add (tail, Mplist, pl);
1796 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1797 MPlist *config_cmds)
1799 MPlist *global = NULL, *custom = NULL, *config = NULL;
1800 MSymbol name = MPLIST_SYMBOL (plist);
1802 MPlist *description, *keyseq;
1804 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1805 global = MPLIST_NEXT (MPLIST_PLIST (global));
1807 plist = MPLIST_NEXT (plist);
1808 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1810 description = plist;
1811 plist = MPLIST_NEXT (plist);
1815 description = global;
1816 if (! MPLIST_TAIL_P (plist))
1817 plist = MPLIST_NEXT (plist);
1819 if (MPLIST_TAIL_P (plist) && global)
1821 keyseq = MPLIST_NEXT (global);
1822 status = Minherited;
1830 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1832 status = Mconfigured;
1833 config = MPLIST_NEXT (MPLIST_PLIST (config));
1834 if (! MPLIST_TAIL_P (config))
1837 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1839 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1841 if (MPLIST_TAIL_P (this_keyseq))
1842 mplist__pop_unref (custom);
1845 status = Mcustomized;
1846 keyseq = this_keyseq;
1851 mplist_add (plist, Msymbol, name);
1853 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1855 mplist_add (plist, Msymbol, Mnil);
1856 mplist_add (plist, Msymbol, status);
1857 mplist__conc (plist, keyseq);
1862 config_all_commands (MInputMethodInfo *im_info)
1864 MPlist *global_cmds, *custom_cmds, *config_cmds;
1865 MInputMethodInfo *temp;
1866 MPlist *tail, *plist;
1868 M17N_OBJECT_UNREF (im_info->configured_cmds);
1870 if (MPLIST_TAIL_P (im_info->cmds)
1874 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1875 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1876 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1878 im_info->configured_cmds = tail = mplist ();
1879 MPLIST_DO (plist, im_info->cmds)
1881 MPlist *pl = config_command (MPLIST_PLIST (plist),
1882 global_cmds, custom_cmds, config_cmds);
1885 tail = mplist_add (tail, Mplist, pl);
1886 M17N_OBJECT_UNREF (pl);
1891 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1892 valid, return 0 if not. */
1895 check_variable_value (MPlist *val, MPlist *global)
1897 MSymbol type = MPLIST_KEY (val);
1898 MPlist *valids = MPLIST_NEXT (val);
1900 if (type != Minteger && type != Mtext && type != Msymbol)
1904 if (MPLIST_KEY (global) != Mt
1905 && MPLIST_KEY (global) != MPLIST_KEY (val))
1907 if (MPLIST_TAIL_P (valids))
1908 valids = MPLIST_NEXT (global);
1910 if (MPLIST_TAIL_P (valids))
1913 if (type == Minteger)
1915 int n = MPLIST_INTEGER (val);
1917 MPLIST_DO (valids, valids)
1919 if (MPLIST_INTEGER_P (valids))
1921 if (n == MPLIST_INTEGER (valids))
1924 else if (MPLIST_PLIST_P (valids))
1926 MPlist *p = MPLIST_PLIST (valids);
1927 int min_bound, max_bound;
1929 if (! MPLIST_INTEGER_P (p))
1930 MERROR (MERROR_IM, 0);
1931 min_bound = MPLIST_INTEGER (p);
1932 p = MPLIST_NEXT (p);
1933 if (! MPLIST_INTEGER_P (p))
1934 MERROR (MERROR_IM, 0);
1935 max_bound = MPLIST_INTEGER (p);
1936 if (n >= min_bound && n <= max_bound)
1941 else if (type == Msymbol)
1943 MSymbol sym = MPLIST_SYMBOL (val);
1945 MPLIST_DO (valids, valids)
1947 if (! MPLIST_SYMBOL_P (valids))
1948 MERROR (MERROR_IM, 0);
1949 if (sym == MPLIST_SYMBOL (valids))
1955 MText *mt = MPLIST_MTEXT (val);
1957 MPLIST_DO (valids, valids)
1959 if (! MPLIST_MTEXT_P (valids))
1960 MERROR (MERROR_IM, 0);
1961 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1966 return (! MPLIST_TAIL_P (valids));
1969 /* Load variable defitions from PLIST into IM_INFO->vars.
1971 PLIST is well-formed and has this form;
1972 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1974 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1976 The returned list has the same form, but for each element...
1978 (1) If DESCRIPTION and the rest are omitted, the element is not
1979 stored in the returned list.
1981 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1982 description in global_info->vars (if any). */
1985 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1987 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1988 ? global_info->vars : NULL);
1991 im_info->vars = tail = mplist ();
1992 MPLIST_DO (plist, MPLIST_NEXT (plist))
1996 if (MFAILP (MPLIST_PLIST_P (plist)))
1998 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1999 if (MFAILP (MPLIST_SYMBOL_P (pl)))
2001 if (im_info == global_info)
2003 /* Loading a global variable. */
2004 p = MPLIST_NEXT (pl);
2005 if (MPLIST_TAIL_P (p))
2006 mplist_add (p, Msymbol, Mnil);
2009 if (! check_description (p))
2010 mplist_set (p, Msymbol, Mnil);
2011 p = MPLIST_NEXT (p);
2012 if (MFAILP (! MPLIST_TAIL_P (p)
2013 && check_variable_value (p, NULL)))
2014 mplist_set (p, Mt, NULL);
2017 else if (im_info->mdb)
2019 /* Loading a local variable. */
2020 MSymbol name = MPLIST_SYMBOL (pl);
2021 MPlist *global = NULL;
2024 && (p = mplist__assq (global_vars, name)))
2026 /* P ::= ((NAME DESC ...) ...) */
2027 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2028 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2029 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2032 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2033 if (! MPLIST_TAIL_P (p))
2035 if (! check_description (p))
2036 mplist_set (p, Msymbol, Mnil);
2037 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2038 if (MFAILP (! MPLIST_TAIL_P (p)))
2039 mplist_set (p, Mt, NULL);
2042 MPlist *valid_values = MPLIST_NEXT (p);
2044 if (! MPLIST_TAIL_P (valid_values)
2045 ? MFAILP (check_variable_value (p, NULL))
2046 : global && MFAILP (check_variable_value (p, global)))
2047 mplist_set (p, Mt, NULL);
2053 /* Loading a variable customization. */
2054 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2055 if (MFAILP (! MPLIST_TAIL_P (p)))
2057 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2058 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2059 || MPLIST_MTEXT_P (p)))
2062 tail = mplist_add (tail, Mplist, pl);
2067 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2068 MPlist *config_vars)
2070 MPlist *global = NULL, *custom = NULL, *config = NULL;
2071 MSymbol name = MPLIST_SYMBOL (plist);
2073 MPlist *description = NULL, *value, *valids;
2077 global = mplist__assq (global_vars, name);
2079 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2082 plist = MPLIST_NEXT (plist);
2083 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2084 description = plist;
2086 description = global;
2088 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2090 if (MPLIST_TAIL_P (plist))
2092 /* Inherit from global (if any). */
2096 if (MPLIST_KEY (value) == Mt)
2098 valids = MPLIST_NEXT (global);
2099 status = Minherited;
2111 value = plist = MPLIST_NEXT (plist);
2112 valids = MPLIST_NEXT (value);
2113 if (MPLIST_KEY (value) == Mt)
2115 if (! MPLIST_TAIL_P (valids))
2118 valids = MPLIST_NEXT (global);
2122 if (config_vars && (config = mplist__assq (config_vars, name)))
2124 status = Mconfigured;
2125 config = MPLIST_NEXT (MPLIST_PLIST (config));
2126 if (! MPLIST_TAIL_P (config))
2129 if (MFAILP (check_variable_value (value, global ? global : plist)))
2133 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2135 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2137 if (MPLIST_TAIL_P (this_value))
2138 mplist__pop_unref (custom);
2142 if (MFAILP (check_variable_value (value, global ? global : plist)))
2144 status = Mcustomized;
2149 mplist_add (plist, Msymbol, name);
2151 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2153 mplist_add (plist, Msymbol, Mnil);
2154 mplist_add (plist, Msymbol, status);
2156 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2158 mplist_add (plist, Mt, NULL);
2159 if (valids && ! MPLIST_TAIL_P (valids))
2160 mplist__conc (plist, valids);
2164 /* Return a configured variable definition list based on
2165 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2166 get it from global_info->vars. */
2169 config_all_variables (MInputMethodInfo *im_info)
2171 MPlist *global_vars, *custom_vars, *config_vars;
2172 MInputMethodInfo *temp;
2173 MPlist *tail, *plist;
2175 M17N_OBJECT_UNREF (im_info->configured_vars);
2177 if (MPLIST_TAIL_P (im_info->vars)
2181 global_vars = im_info != global_info ? global_info->vars : NULL;
2182 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2183 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2185 im_info->configured_vars = tail = mplist ();
2186 MPLIST_DO (plist, im_info->vars)
2188 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2189 global_vars, custom_vars, config_vars);
2192 tail = mplist_add (tail, Mplist, pl);
2193 M17N_OBJECT_UNREF (pl);
2198 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2199 CONFIG contains configuration information of the input method. */
2202 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2206 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2208 load_commands (im_info, MPLIST_PLIST (pl));
2209 config_all_commands (im_info);
2210 pl = mplist_pop (pl);
2211 M17N_OBJECT_UNREF (pl);
2214 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2216 load_variables (im_info, MPLIST_PLIST (pl));
2217 config_all_variables (im_info);
2218 pl = mplist_pop (pl);
2219 M17N_OBJECT_UNREF (pl);
2222 MPLIST_DO (plist, plist)
2223 if (MPLIST_PLIST_P (plist))
2225 MPlist *elt = MPLIST_PLIST (plist);
2228 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2230 key = MPLIST_SYMBOL (elt);
2235 elt = MPLIST_NEXT (elt);
2236 if (MFAILP (MPLIST_MTEXT_P (elt)))
2238 im_info->title = MPLIST_MTEXT (elt);
2239 M17N_OBJECT_REF (im_info->title);
2241 else if (key == Mmap)
2243 pl = mplist__from_alist (MPLIST_NEXT (elt));
2246 if (! im_info->maps)
2250 mplist__conc (im_info->maps, pl);
2251 M17N_OBJECT_UNREF (pl);
2254 else if (key == Mmacro)
2256 if (! im_info->macros)
2257 im_info->macros = mplist ();
2258 MPLIST_DO (elt, MPLIST_NEXT (elt))
2260 if (MFAILP (MPLIST_PLIST_P (elt)))
2262 load_macros (im_info, MPLIST_PLIST (elt));
2265 else if (key == Mmodule)
2267 if (! im_info->externals)
2268 im_info->externals = mplist ();
2269 MPLIST_DO (elt, MPLIST_NEXT (elt))
2271 if (MFAILP (MPLIST_PLIST_P (elt)))
2273 load_external_module (im_info, MPLIST_PLIST (elt));
2276 else if (key == Mstate)
2278 MPLIST_DO (elt, MPLIST_NEXT (elt))
2282 if (MFAILP (MPLIST_PLIST_P (elt)))
2284 pl = MPLIST_PLIST (elt);
2285 if (! im_info->states)
2286 im_info->states = mplist ();
2287 state = load_state (im_info, MPLIST_PLIST (elt));
2290 mplist_put (im_info->states, state->name, state);
2293 else if (key == Minclude)
2295 /* elt ::= include (tag1 tag2 ...) key item ... */
2297 MInputMethodInfo *temp;
2299 elt = MPLIST_NEXT (elt);
2300 if (MFAILP (MPLIST_PLIST_P (elt)))
2302 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2305 elt = MPLIST_NEXT (elt);
2306 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2308 key = MPLIST_SYMBOL (elt);
2309 elt = MPLIST_NEXT (elt);
2312 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2314 if (! im_info->maps)
2315 im_info->maps = mplist ();
2316 MPLIST_DO (pl, temp->maps)
2318 p = MPLIST_VAL (pl);
2319 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2320 M17N_OBJECT_REF (p);
2323 else if (key == Mmacro)
2325 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2327 if (! im_info->macros)
2328 im_info->macros = mplist ();
2329 MPLIST_DO (pl, temp->macros)
2331 p = MPLIST_VAL (pl);
2332 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2333 M17N_OBJECT_REF (p);
2336 else if (key == Mstate)
2338 if (! temp->states || MPLIST_TAIL_P (temp->states))
2340 if (! im_info->states)
2341 im_info->states = mplist ();
2342 MPLIST_DO (pl, temp->states)
2344 MIMState *state = MPLIST_VAL (pl);
2346 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2347 M17N_OBJECT_REF (state);
2351 else if (key == Mdescription)
2353 if (im_info->description)
2355 elt = MPLIST_NEXT (elt);
2356 if (! check_description (elt))
2358 im_info->description = MPLIST_MTEXT (elt);
2359 M17N_OBJECT_REF (im_info->description);
2362 im_info->tick = time (NULL);
2367 static int take_action_list (MInputContext *ic, MPlist *action_list);
2368 static void preedit_commit (MInputContext *ic, int need_prefix);
2371 shift_state (MInputContext *ic, MSymbol state_name)
2373 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2374 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2375 MIMState *orig_state = ic_info->state, *state;
2377 /* Find a state to shift to. If not found, shift to the initial
2379 if (state_name == Mt)
2381 if (! ic_info->prev_state)
2383 state = ic_info->prev_state;
2385 else if (state_name == Mnil)
2387 state = (MIMState *) MPLIST_VAL (im_info->states);
2391 state = (MIMState *) mplist_get (im_info->states, state_name);
2393 state = (MIMState *) MPLIST_VAL (im_info->states);
2399 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2400 MSYMBOL_NAME (orig_state->name),
2401 MSYMBOL_NAME (state->name));
2403 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2406 /* Enter the new state. */
2407 ic_info->state = state;
2408 ic_info->map = state->map;
2409 ic_info->state_key_head = ic_info->key_head;
2410 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2412 /* We have shifted to the initial state. */
2413 preedit_commit (ic, 0);
2414 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2415 ic_info->state_pos = ic->cursor_pos;
2416 if (state != orig_state)
2418 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2420 /* Shifted to the initial state. */
2421 ic_info->prev_state = NULL;
2422 M17N_OBJECT_UNREF (ic_info->vars_saved);
2423 ic_info->vars_saved = mplist_copy (ic_info->vars);
2426 ic_info->prev_state = orig_state;
2429 ic->status = state->title;
2431 ic->status = im_info->title;
2432 ic->status_changed = 1;
2433 if (ic_info->map == ic_info->state->map
2434 && ic_info->map->map_actions)
2436 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2437 MSYMBOL_NAME (state->name));
2438 take_action_list (ic, ic_info->map->map_actions);
2443 /* Find a candidate group that contains a candidate number INDEX from
2444 PLIST. Set START_INDEX to the first candidate number of the group,
2445 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2446 candidate group number if they are non-NULL. If INDEX is -1, find
2447 the last candidate group. */
2450 find_candidates_group (MPlist *plist, int index,
2451 int *start_index, int *end_index, int *group_index)
2453 int i = 0, gidx = 0, len;
2455 MPLIST_DO (plist, plist)
2457 if (MPLIST_MTEXT_P (plist))
2458 len = mtext_nchars (MPLIST_MTEXT (plist));
2460 len = mplist_length (MPLIST_PLIST (plist));
2461 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2467 *end_index = i + len;
2469 *group_index = gidx;
2478 /* Adjust markers for the change of preedit text.
2479 If FROM == TO, the change is insertion of INS chars.
2480 If FROM < TO and INS == 0, the change is deletion of the range.
2481 If FROM < TO and INS > 0, the change is replacement. */
2484 adjust_markers (MInputContext *ic, int from, int to, int ins)
2486 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2491 MPLIST_DO (markers, ic_info->markers)
2492 if (MPLIST_INTEGER (markers) > from)
2493 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2494 if (ic->cursor_pos >= from)
2495 ic->cursor_pos += ins;
2499 MPLIST_DO (markers, ic_info->markers)
2501 if (MPLIST_INTEGER (markers) >= to)
2502 MPLIST_VAL (markers)
2503 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2504 else if (MPLIST_INTEGER (markers) > from)
2505 MPLIST_VAL (markers) = (void *) from;
2507 if (ic->cursor_pos >= to)
2508 ic->cursor_pos += ins - (to - from);
2509 else if (ic->cursor_pos > from)
2510 ic->cursor_pos = from;
2516 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2518 int nchars = mt ? mtext_nchars (mt) : 1;
2522 mtext_ins (ic->preedit, pos, mt);
2523 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2527 mtext_ins_char (ic->preedit, pos, c, 1);
2529 MDEBUG_PRINT1 ("('%c')", c);
2531 MDEBUG_PRINT1 ("(U+%04X)", c);
2533 adjust_markers (ic, pos, pos, nchars);
2534 ic->preedit_changed = 1;
2539 preedit_delete (MInputContext *ic, int from, int to)
2541 mtext_del (ic->preedit, from, to);
2542 adjust_markers (ic, from, to, 0);
2543 ic->preedit_changed = 1;
2547 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2551 mtext_del (ic->preedit, from, to);
2554 mtext_ins (ic->preedit, from, mt);
2555 ins = mtext_nchars (mt);
2559 mtext_ins_char (ic->preedit, from, c, 1);
2562 adjust_markers (ic, from, to, ins);
2563 ic->preedit_changed = 1;
2568 preedit_commit (MInputContext *ic, int need_prefix)
2570 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2571 int preedit_len = mtext_nchars (ic->preedit);
2573 if (preedit_len > 0)
2577 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2578 Mcandidate_list, NULL, 0);
2579 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2580 Mcandidate_index, NULL, 0);
2581 mtext_cat (ic->produced, ic->preedit);
2587 MDEBUG_PRINT1 ("\n [IM] [%s]",
2588 MSYMBOL_NAME (ic_info->state->name));
2589 MDEBUG_PRINT (" (commit");
2590 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2591 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2595 mtext_reset (ic->preedit);
2596 mtext_reset (ic_info->preedit_saved);
2597 MPLIST_DO (p, ic_info->markers)
2599 ic->cursor_pos = ic_info->state_pos = 0;
2600 ic->preedit_changed = 1;
2601 ic_info->commit_key_head = ic_info->key_head;
2603 if (ic->candidate_list)
2605 M17N_OBJECT_UNREF (ic->candidate_list);
2606 ic->candidate_list = NULL;
2607 ic->candidate_index = 0;
2608 ic->candidate_from = ic->candidate_to = 0;
2609 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2610 if (ic->candidate_show)
2612 ic->candidate_show = 0;
2613 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2619 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2621 int code = marker_code (sym, 0);
2623 if (mt && (code == '[' || code == ']'))
2627 if (code == '[' && current > 0)
2629 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2633 else if (code == ']' && current < mtext_nchars (mt))
2635 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2641 return (code == '<' ? 0
2642 : code == '>' ? limit
2643 : code == '-' ? current - 1
2644 : code == '+' ? current + 1
2645 : code == '=' ? current
2646 : code - '0' > limit ? limit
2650 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2654 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2656 int from = mtext_property_start (prop);
2657 int to = mtext_property_end (prop);
2659 MPlist *candidate_list = mtext_property_value (prop);
2660 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2662 int ingroup_index = idx - start;
2665 candidate_list = mplist_copy (candidate_list);
2666 if (MPLIST_MTEXT_P (group))
2668 mt = MPLIST_MTEXT (group);
2669 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2677 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2678 i++, plist = MPLIST_NEXT (plist));
2679 mt = MPLIST_MTEXT (plist);
2680 preedit_replace (ic, from, to, mt, 0);
2681 to = from + mtext_nchars (mt);
2683 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2684 M17N_OBJECT_UNREF (candidate_list);
2685 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2686 ic->cursor_pos = to;
2690 get_select_charset (MInputContextInfo * ic_info)
2692 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2695 if (! MPLIST_VAL (plist))
2697 sym = MPLIST_SYMBOL (plist);
2700 return MCHARSET (sym);
2704 adjust_candidates (MPlist *plist, MCharset *charset)
2708 /* plist ::= MTEXT ... | PLIST ... */
2709 plist = mplist_copy (plist);
2710 if (MPLIST_MTEXT_P (plist))
2713 while (! MPLIST_TAIL_P (pl))
2715 /* pl ::= MTEXT ... */
2716 MText *mt = MPLIST_MTEXT (pl);
2720 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2722 c = mtext_ref_char (mt, i);
2723 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2727 mt = mtext_dup (mt);
2728 mplist_set (pl, Mtext, mt);
2729 M17N_OBJECT_UNREF (mt);
2732 mtext_del (mt, i, i + 1);
2735 if (mtext_len (mt) > 0)
2736 pl = MPLIST_NEXT (pl);
2740 M17N_OBJECT_UNREF (mt);
2744 else /* MPLIST_PLIST_P (plist) */
2747 while (! MPLIST_TAIL_P (pl))
2749 /* pl ::= (MTEXT ...) ... */
2750 MPlist *p = MPLIST_PLIST (pl);
2752 /* p ::= MTEXT ... */
2756 while (! MPLIST_TAIL_P (p0))
2758 MText *mt = MPLIST_MTEXT (p0);
2761 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2763 c = mtext_ref_char (mt, i);
2764 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2769 p0 = MPLIST_NEXT (p0);
2776 p = mplist_copy (p);
2777 mplist_set (pl, Mplist, p);
2778 M17N_OBJECT_UNREF (p);
2782 p0 = MPLIST_NEXT (p0);
2785 M17N_OBJECT_UNREF (mt);
2788 if (! MPLIST_TAIL_P (p))
2789 pl = MPLIST_NEXT (pl);
2793 M17N_OBJECT_UNREF (p);
2797 if (MPLIST_TAIL_P (plist))
2799 M17N_OBJECT_UNREF (plist);
2806 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2808 MCharset *charset = get_select_charset (ic_info);
2813 plist = resolve_variable (ic_info, Mcandidates_group_size);
2814 column = MPLIST_INTEGER (plist);
2816 plist = MPLIST_PLIST (args);
2818 plist = adjust_candidates (plist, charset);
2820 if (plist && column > 0)
2822 if (MPLIST_MTEXT_P (plist))
2824 MText *mt = MPLIST_MTEXT (plist);
2825 MPlist *next = MPLIST_NEXT (plist);
2827 if (MPLIST_TAIL_P (next))
2828 M17N_OBJECT_REF (mt);
2831 mt = mtext_dup (mt);
2832 while (! MPLIST_TAIL_P (next))
2834 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2835 next = MPLIST_NEXT (next);
2839 M17N_OBJECT_UNREF (plist);
2841 len = mtext_nchars (mt);
2843 mplist_add (plist, Mtext, mt);
2846 for (i = 0; i < len; i += column)
2848 int to = (i + column < len ? i + column : len);
2849 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2851 mplist_add (plist, Mtext, sub);
2852 M17N_OBJECT_UNREF (sub);
2855 M17N_OBJECT_UNREF (mt);
2857 else if (! MPLIST_TAIL_P (plist))
2859 MPlist *tail = plist;
2860 MPlist *new = mplist ();
2861 MPlist *this = mplist ();
2864 MPLIST_DO (tail, tail)
2866 MPlist *p = MPLIST_PLIST (tail);
2870 MText *mt = MPLIST_MTEXT (p);
2872 if (count == column)
2874 mplist_add (new, Mplist, this);
2875 M17N_OBJECT_UNREF (this);
2879 mplist_add (this, Mtext, mt);
2883 mplist_add (new, Mplist, this);
2884 M17N_OBJECT_UNREF (this);
2885 mplist_set (plist, Mnil, NULL);
2886 MPLIST_DO (tail, new)
2888 MPlist *elt = MPLIST_PLIST (tail);
2890 mplist_add (plist, Mplist, elt);
2892 M17N_OBJECT_UNREF (new);
2901 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2903 MPlist *action = NULL;
2907 if (MPLIST_SYMBOL_P (action_list))
2909 MSymbol var = MPLIST_SYMBOL (action_list);
2912 MPLIST_DO (p, ic_info->vars)
2913 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2915 if (MPLIST_TAIL_P (p))
2917 action = MPLIST_NEXT (MPLIST_PLIST (p));
2918 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2921 if (MPLIST_PLIST_P (action_list))
2923 action = MPLIST_PLIST (action_list);
2924 if (MPLIST_SYMBOL_P (action))
2926 name = MPLIST_SYMBOL (action);
2927 args = MPLIST_NEXT (action);
2929 && MPLIST_PLIST_P (args))
2930 mplist_set (action, Msymbol, M_candidates);
2932 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2935 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2936 mplist_push (action, Msymbol, M_candidates);
2937 mplist_set (action_list, Mplist, action);
2938 M17N_OBJECT_UNREF (action);
2941 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2944 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2945 mplist_push (action, Msymbol, Minsert);
2946 mplist_set (action_list, Mplist, action);
2947 M17N_OBJECT_UNREF (action);
2952 /* Perform list of actions in ACTION_LIST for the current input
2953 context IC. If unhandle action was not performed, return 0.
2954 Otherwise, return -1. */
2957 take_action_list (MInputContext *ic, MPlist *action_list)
2959 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2960 MPlist *candidate_list = ic->candidate_list;
2961 int candidate_index = ic->candidate_index;
2962 int candidate_show = ic->candidate_show;
2963 MTextProperty *prop;
2965 MPLIST_DO (action_list, action_list)
2967 MPlist *action = regularize_action (action_list, ic_info);
2973 name = MPLIST_SYMBOL (action);
2974 args = MPLIST_NEXT (action);
2976 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2977 if (name == Minsert)
2979 if (MPLIST_SYMBOL_P (args))
2981 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2982 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2985 if (MPLIST_MTEXT_P (args))
2986 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2987 else /* MPLIST_INTEGER_P (args)) */
2988 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2990 else if (name == M_candidates)
2992 MPlist *plist = get_candidate_list (ic_info, args);
2995 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2997 if (MPLIST_MTEXT_P (plist))
2999 preedit_insert (ic, ic->cursor_pos, NULL,
3000 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3003 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
3007 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3009 preedit_insert (ic, ic->cursor_pos, mt, 0);
3010 len = mtext_nchars (mt);
3012 plist = mplist_copy (plist);
3013 mtext_put_prop (ic->preedit,
3014 ic->cursor_pos - len, ic->cursor_pos,
3015 Mcandidate_list, plist);
3016 M17N_OBJECT_UNREF (plist);
3017 mtext_put_prop (ic->preedit,
3018 ic->cursor_pos - len, ic->cursor_pos,
3019 Mcandidate_index, (void *) 0);
3021 else if (name == Mselect)
3024 int code, idx, gindex;
3025 int pos = ic->cursor_pos;
3027 int idx_decided = 0;
3030 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3033 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3034 group = find_candidates_group (mtext_property_value (prop), idx,
3035 &start, &end, &gindex);
3036 if (MPLIST_SYMBOL_P (args))
3038 code = marker_code (MPLIST_SYMBOL (args), 0);
3041 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3042 if (! MPLIST_INTEGER_P (args))
3044 idx = start + MPLIST_INTEGER (args);
3045 if (idx < start || idx >= end)
3053 if (code != '[' && code != ']')
3058 ? new_index (NULL, ic->candidate_index - start,
3059 end - start - 1, MPLIST_SYMBOL (args),
3061 : MPLIST_INTEGER (args)));
3064 find_candidates_group (mtext_property_value (prop), -1,
3069 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3074 int ingroup_index = idx - start;
3077 group = mtext_property_value (prop);
3078 len = mplist_length (group);
3091 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3092 idx += (MPLIST_MTEXT_P (group)
3093 ? mtext_nchars (MPLIST_MTEXT (group))
3094 : mplist_length (MPLIST_PLIST (group)));
3095 len = (MPLIST_MTEXT_P (group)
3096 ? mtext_nchars (MPLIST_MTEXT (group))
3097 : mplist_length (MPLIST_PLIST (group)));
3098 if (ingroup_index >= len)
3099 ingroup_index = len - 1;
3100 idx += ingroup_index;
3102 update_candidate (ic, prop, idx);
3103 MDEBUG_PRINT1 ("(%d)", idx);
3105 else if (name == Mshow)
3106 ic->candidate_show = 1;
3107 else if (name == Mhide)
3108 ic->candidate_show = 0;
3109 else if (name == Mdelete)
3111 int len = mtext_nchars (ic->preedit);
3115 if (MPLIST_SYMBOL_P (args)
3116 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3118 to = ic->cursor_pos + pos;
3121 delete_surrounding_text (ic, to);
3126 delete_surrounding_text (ic, to - len);
3132 to = (MPLIST_SYMBOL_P (args)
3133 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3135 : MPLIST_INTEGER (args));
3140 pos = to - ic->cursor_pos;
3142 MDEBUG_PRINT1 ("(%d)", pos);
3143 if (to < ic->cursor_pos)
3144 preedit_delete (ic, to, ic->cursor_pos);
3145 else if (to > ic->cursor_pos)
3146 preedit_delete (ic, ic->cursor_pos, to);
3148 else if (name == Mmove)
3150 int len = mtext_nchars (ic->preedit);
3152 = (MPLIST_SYMBOL_P (args)
3153 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3155 : MPLIST_INTEGER (args));
3161 if (pos != ic->cursor_pos)
3163 ic->cursor_pos = pos;
3164 ic->preedit_changed = 1;
3166 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3168 else if (name == Mmark)
3170 int code = marker_code (MPLIST_SYMBOL (args), 0);
3174 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3175 (void *) ic->cursor_pos);
3176 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3179 else if (name == Mpushback)
3181 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3185 if (MPLIST_SYMBOL_P (args))
3187 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3188 if (MPLIST_INTEGER_P (args))
3189 num = MPLIST_INTEGER (args);
3194 num = MPLIST_INTEGER (args);
3197 ic_info->key_head -= num;
3199 ic_info->key_head = 0;
3201 ic_info->key_head = - num;
3202 if (ic_info->key_head > ic_info->used)
3203 ic_info->key_head = ic_info->used;
3205 else if (MPLIST_MTEXT_P (args))
3207 MText *mt = MPLIST_MTEXT (args);
3208 int i, len = mtext_nchars (mt);
3211 ic_info->key_head--;
3212 for (i = 0; i < len; i++)
3214 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3215 if (ic_info->key_head + i < ic_info->used)
3216 ic_info->keys[ic_info->key_head + i] = key;
3218 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3223 MPlist *plist = MPLIST_PLIST (args), *pl;
3227 ic_info->key_head--;
3229 MPLIST_DO (pl, plist)
3231 key = MPLIST_SYMBOL (pl);
3232 if (ic_info->key_head < ic_info->used)
3233 ic_info->keys[ic_info->key_head + i] = key;
3235 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3240 else if (name == Mpop)
3242 if (ic_info->key_head < ic_info->used)
3243 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3245 else if (name == Mcall)
3247 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3248 MIMExternalFunc func = NULL;
3249 MSymbol module, func_name;
3250 MPlist *func_args, *val;
3253 module = MPLIST_SYMBOL (args);
3254 args = MPLIST_NEXT (args);
3255 func_name = MPLIST_SYMBOL (args);
3257 if (im_info->externals)
3259 MIMExternalModule *external
3260 = (MIMExternalModule *) mplist_get (im_info->externals,
3263 func = ((MIMExternalFunc)
3264 mplist_get_func (external->func_list, func_name));
3268 func_args = mplist ();
3269 mplist_add (func_args, Mt, ic);
3270 MPLIST_DO (args, MPLIST_NEXT (args))
3274 if (MPLIST_KEY (args) == Msymbol
3275 && MPLIST_KEY (args) != Mnil
3276 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3278 code = new_index (ic, ic->cursor_pos,
3279 mtext_nchars (ic->preedit),
3280 MPLIST_SYMBOL (args), ic->preedit);
3281 mplist_add (func_args, Minteger, (void *) code);
3284 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3286 val = (func) (func_args);
3287 M17N_OBJECT_UNREF (func_args);
3288 if (val && ! MPLIST_TAIL_P (val))
3289 ret = take_action_list (ic, val);
3290 M17N_OBJECT_UNREF (val);
3294 else if (name == Mshift)
3296 shift_state (ic, MPLIST_SYMBOL (args));
3298 else if (name == Mundo)
3300 int intarg = (MPLIST_TAIL_P (args)
3302 : integer_value (ic, args, 0));
3304 mtext_reset (ic->preedit);
3305 mtext_reset (ic_info->preedit_saved);
3306 mtext_reset (ic->produced);
3307 M17N_OBJECT_UNREF (ic_info->vars);
3308 ic_info->vars = mplist_copy (ic_info->vars_saved);
3309 ic->cursor_pos = ic_info->state_pos = 0;
3310 ic_info->state_key_head = ic_info->key_head
3311 = ic_info->commit_key_head = 0;
3313 shift_state (ic, Mnil);
3316 if (MPLIST_TAIL_P (args))
3321 ic_info->used += intarg;
3324 ic_info->used = intarg;
3327 else if (name == Mset || name == Madd || name == Msub
3328 || name == Mmul || name == Mdiv)
3330 MSymbol sym = MPLIST_SYMBOL (args);
3331 MPlist *value = resolve_variable (ic_info, sym);
3335 val1 = MPLIST_INTEGER (value);
3336 args = MPLIST_NEXT (args);
3337 val2 = resolve_expression (ic, args);
3339 val1 = val2, op = "=";
3340 else if (name == Madd)
3341 val1 += val2, op = "+=";
3342 else if (name == Msub)
3343 val1 -= val2, op = "-=";
3344 else if (name == Mmul)
3345 val1 *= val2, op = "*=";
3347 val1 /= val2, op = "/=";
3348 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3349 MSYMBOL_NAME (sym), op, val1, val1);
3350 mplist_set (value, Minteger, (void *) val1);
3352 else if (name == Mequal || name == Mless || name == Mgreater
3353 || name == Mless_equal || name == Mgreater_equal)
3356 MPlist *actions1, *actions2;
3359 val1 = resolve_expression (ic, args);
3360 args = MPLIST_NEXT (args);
3361 val2 = resolve_expression (ic, args);
3362 args = MPLIST_NEXT (args);
3363 actions1 = MPLIST_PLIST (args);
3364 args = MPLIST_NEXT (args);
3365 if (MPLIST_TAIL_P (args))
3368 actions2 = MPLIST_PLIST (args);
3369 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3370 if (name == Mequal ? val1 == val2
3371 : name == Mless ? val1 < val2
3372 : name == Mgreater ? val1 > val2
3373 : name == Mless_equal ? val1 <= val2
3376 MDEBUG_PRINT ("ok");
3377 ret = take_action_list (ic, actions1);
3381 MDEBUG_PRINT ("no");
3383 ret = take_action_list (ic, actions2);
3388 else if (name == Mcond)
3392 MPLIST_DO (args, args)
3397 if (! MPLIST_PLIST (args))
3399 cond = MPLIST_PLIST (args);
3400 if (resolve_expression (ic, cond) != 0)
3402 MDEBUG_PRINT1 ("(%dth)", idx);
3403 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3409 else if (name == Mcommit)
3411 preedit_commit (ic, 0);
3413 else if (name == Munhandle)
3415 preedit_commit (ic, 0);
3420 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3424 && (actions = mplist_get (im_info->macros, name)))
3426 if (take_action_list (ic, actions) < 0)
3432 if (ic->candidate_list)
3434 M17N_OBJECT_UNREF (ic->candidate_list);
3435 ic->candidate_list = NULL;
3437 if (ic->cursor_pos > 0
3438 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3441 ic->candidate_list = mtext_property_value (prop);
3442 M17N_OBJECT_REF (ic->candidate_list);
3444 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3446 ic->candidate_from = mtext_property_start (prop);
3447 ic->candidate_to = mtext_property_end (prop);
3450 if (candidate_list != ic->candidate_list)
3451 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3452 if (candidate_index != ic->candidate_index)
3453 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3454 if (candidate_show != ic->candidate_show)
3455 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3460 /* Handle the input key KEY in the current state and map specified in
3461 the input context IC. If KEY is handled correctly, return 0.
3462 Otherwise, return -1. */
3465 handle_key (MInputContext *ic)
3467 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3468 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3469 MIMMap *map = ic_info->map;
3470 MIMMap *submap = NULL;
3471 MSymbol key = ic_info->keys[ic_info->key_head];
3472 MSymbol alias = Mnil;
3475 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3476 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3480 submap = mplist_get (map->submaps, key);
3483 && (alias = msymbol_get (alias, M_key_alias))
3485 submap = mplist_get (map->submaps, alias);
3490 if (! alias || alias == key)
3491 MDEBUG_PRINT (" submap-found");
3493 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3494 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3495 ic->preedit_changed = 1;
3496 ic->cursor_pos = ic_info->state_pos;
3497 ic_info->key_head++;
3498 ic_info->map = map = submap;
3499 if (map->map_actions)
3501 MDEBUG_PRINT (" map-actions:");
3502 if (take_action_list (ic, map->map_actions) < 0)
3504 MDEBUG_PRINT ("\n");
3508 else if (map->submaps)
3510 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3512 MSymbol key = ic_info->keys[i];
3513 char *name = msymbol_name (key);
3515 if (! name[0] || ! name[1])
3516 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3520 /* If this is the terminal map or we have shifted to another
3521 state, perform branch actions (if any). */
3522 if (! map->submaps || map != ic_info->map)
3524 if (map->branch_actions)
3526 MDEBUG_PRINT (" branch-actions:");
3527 if (take_action_list (ic, map->branch_actions) < 0)
3529 MDEBUG_PRINT ("\n");
3533 /* If MAP is still not the root map, shift to the current
3535 if (ic_info->map != ic_info->state->map)
3536 shift_state (ic, ic_info->state->name);
3541 /* MAP can not handle KEY. */
3543 /* Perform branch actions if any. */
3544 if (map->branch_actions)
3546 MDEBUG_PRINT (" branch-actions:");
3547 if (take_action_list (ic, map->branch_actions) < 0)
3549 MDEBUG_PRINT ("\n");
3554 if (map == ic_info->map)
3556 /* The above branch actions didn't change the state. */
3558 /* If MAP is the root map of the initial state, and there
3559 still exist an unhandled key, it means that the current
3560 input method can not handle it. */
3561 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3562 && ic_info->key_head < ic_info->used)
3564 MDEBUG_PRINT (" unhandled\n");
3568 if (map != ic_info->state->map)
3570 /* MAP is not the root map. Shift to the root map of the
3572 shift_state (ic, ic_info->state->name);
3574 else if (! map->branch_actions)
3576 /* MAP is the root map without any default branch
3577 actions. Shift to the initial state. */
3578 shift_state (ic, Mnil);
3582 MDEBUG_PRINT ("\n");
3586 /* Initialize IC->ic_info. */
3589 init_ic_info (MInputContext *ic)
3591 MInputMethodInfo *im_info = ic->im->info;
3592 MInputContextInfo *ic_info = ic->info;
3595 MLIST_INIT1 (ic_info, keys, 8);;
3597 ic_info->markers = mplist ();
3599 ic_info->vars = mplist ();
3600 if (im_info->configured_vars)
3601 MPLIST_DO (plist, im_info->configured_vars)
3603 MPlist *pl = MPLIST_PLIST (plist);
3604 MSymbol name = MPLIST_SYMBOL (pl);
3606 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3607 if (MPLIST_KEY (pl) != Mt)
3609 MPlist *p = mplist ();
3611 mplist_push (ic_info->vars, Mplist, p);
3612 M17N_OBJECT_UNREF (p);
3613 mplist_add (p, Msymbol, name);
3614 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3617 ic_info->vars_saved = mplist_copy (ic_info->vars);
3619 if (im_info->externals)
3621 MPlist *func_args = mplist (), *plist;
3623 mplist_add (func_args, Mt, ic);
3624 MPLIST_DO (plist, im_info->externals)
3626 MIMExternalModule *external = MPLIST_VAL (plist);
3627 MIMExternalFunc func
3628 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3633 M17N_OBJECT_UNREF (func_args);
3636 ic_info->preedit_saved = mtext ();
3637 ic_info->tick = im_info->tick;
3640 /* Finalize IC->ic_info. */
3643 fini_ic_info (MInputContext *ic)
3645 MInputMethodInfo *im_info = ic->im->info;
3646 MInputContextInfo *ic_info = ic->info;
3648 if (im_info->externals)
3650 MPlist *func_args = mplist (), *plist;
3652 mplist_add (func_args, Mt, ic);
3653 MPLIST_DO (plist, im_info->externals)
3655 MIMExternalModule *external = MPLIST_VAL (plist);
3656 MIMExternalFunc func
3657 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3662 M17N_OBJECT_UNREF (func_args);
3665 MLIST_FREE1 (ic_info, keys);
3666 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3667 M17N_OBJECT_UNREF (ic_info->markers);
3668 M17N_OBJECT_UNREF (ic_info->vars);
3669 M17N_OBJECT_UNREF (ic_info->vars_saved);
3670 M17N_OBJECT_UNREF (ic_info->preceding_text);
3671 M17N_OBJECT_UNREF (ic_info->following_text);
3673 memset (ic_info, 0, sizeof (MInputContextInfo));
3677 re_init_ic (MInputContext *ic, int reload)
3679 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3680 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3681 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3683 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3684 preedit_changed = mtext_nchars (ic->preedit) > 0;
3685 cursor_pos_changed = ic->cursor_pos > 0;
3686 candidates_changed = 0;
3687 if (ic->candidate_list)
3689 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3690 M17N_OBJECT_UNREF (ic->candidate_list);
3691 ic->candidate_list = NULL;
3693 if (ic->candidate_show)
3695 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3696 ic->candidate_show = 0;
3698 if (ic->candidate_index > 0)
3700 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3701 ic->candidate_index = 0;
3702 ic->candidate_from = ic->candidate_to = 0;
3704 if (mtext_nchars (ic->produced) > 0)
3705 mtext_reset (ic->produced);
3706 if (mtext_nchars (ic->preedit) > 0)
3707 mtext_reset (ic->preedit);
3709 M17N_OBJECT_UNREF (ic->plist);
3710 ic->plist = mplist ();
3714 reload_im_info (im_info);
3715 if (! im_info->states)
3717 struct MIMState *state;
3719 M17N_OBJECT (state, free_state, MERROR_IM);
3720 state->name = msymbol ("init");
3721 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3722 MSTRUCT_CALLOC (state->map, MERROR_IM);
3723 im_info->states = mplist ();
3724 mplist_add (im_info->states, state->name, state);
3727 shift_state (ic, Mnil);
3729 ic->status_changed = status_changed;
3730 ic->preedit_changed = preedit_changed;
3731 ic->cursor_pos_changed = cursor_pos_changed;
3732 ic->candidates_changed = candidates_changed;
3736 reset_ic (MInputContext *ic, MSymbol ignore)
3738 MDEBUG_PRINT ("\n [IM] reset\n");
3743 open_im (MInputMethod *im)
3745 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3747 if (! im_info || ! im_info->states)
3748 MERROR (MERROR_IM, -1);
3755 close_im (MInputMethod *im)
3761 create_ic (MInputContext *ic)
3763 MInputContextInfo *ic_info;
3765 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3768 shift_state (ic, Mnil);
3773 destroy_ic (MInputContext *ic)
3780 check_reload (MInputContext *ic, MSymbol key)
3782 MInputMethodInfo *im_info = ic->im->info;
3783 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3787 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3791 MPLIST_DO (plist, plist)
3793 MSymbol this_key, alias;
3795 if (MPLIST_MTEXT_P (plist))
3797 MText *mt = MPLIST_MTEXT (plist);
3798 int c = mtext_ref_char (mt, 0);
3802 this_key = one_char_symbol[c];
3806 MPlist *pl = MPLIST_PLIST (plist);
3808 this_key = MPLIST_SYMBOL (pl);
3812 && (alias = msymbol_get (alias, M_key_alias))
3813 && alias != this_key);
3817 if (MPLIST_TAIL_P (plist))
3820 MDEBUG_PRINT ("\n [IM] reload");
3826 /** Handle the input key KEY in the current state and map of IC->info.
3827 If KEY is handled but no text is produced, return 0, otherwise
3833 filter (MInputContext *ic, MSymbol key, void *arg)
3835 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3836 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3839 if (check_reload (ic, key))
3842 if (! ic_info->state)
3844 ic_info->key_unhandled = 1;
3847 mtext_reset (ic->produced);
3848 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3849 M17N_OBJECT_UNREF (ic_info->preceding_text);
3850 M17N_OBJECT_UNREF (ic_info->following_text);
3851 ic_info->preceding_text = ic_info->following_text = NULL;
3852 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3853 ic_info->key_unhandled = 0;
3856 if (handle_key (ic) < 0)
3858 /* KEY was not handled. Delete it from the current key sequence. */
3859 if (ic_info->used > 0)
3861 memmove (ic_info->keys, ic_info->keys + 1,
3862 sizeof (int) * (ic_info->used - 1));
3864 if (ic_info->state_key_head > 0)
3865 ic_info->state_key_head--;
3866 if (ic_info->commit_key_head > 0)
3867 ic_info->commit_key_head--;
3869 /* This forces returning 1. */
3870 ic_info->key_unhandled = 1;
3876 reset_ic (ic, Mnil);
3877 ic_info->key_unhandled = 1;
3880 /* Break the loop if all keys were handled. */
3881 } while (ic_info->key_head < ic_info->used);
3883 /* If the current map is the root of the initial state, we should
3884 produce any preedit text in ic->produced. */
3885 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3886 preedit_commit (ic, 1);
3888 if (mtext_nchars (ic->produced) > 0)
3892 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3893 MSYMBOL_NAME (ic_info->state->name));
3894 for (i = 0; i < mtext_nchars (ic->produced); i++)
3895 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3899 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3900 Mlanguage, ic->im->language);
3902 if (ic_info->commit_key_head > 0)
3904 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3905 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3906 ic_info->used -= ic_info->commit_key_head;
3907 ic_info->key_head -= ic_info->commit_key_head;
3908 ic_info->state_key_head -= ic_info->commit_key_head;
3909 ic_info->commit_key_head = 0;
3911 if (ic_info->key_unhandled)
3914 ic_info->key_head = ic_info->state_key_head
3915 = ic_info->commit_key_head = 0;
3918 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3922 /** Return 1 if the last event or key was not handled, otherwise
3925 There is no need of looking up because ic->produced should already
3926 contain the produced text (if any).
3931 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3933 mtext_cat (mt, ic->produced);
3934 mtext_reset (ic->produced);
3935 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3939 /* Input method command handler. */
3941 /* List of all (global and local) commands.
3942 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3943 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3944 Global commands are stored as (t (t COMMAND ...)) */
3947 /* Input method variable handler. */
3950 /* Support functions for mdebug_dump_im. */
3953 dump_im_map (MPlist *map_list, int indent)
3956 MSymbol key = MPLIST_KEY (map_list);
3957 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3959 prefix = (char *) alloca (indent + 1);
3960 memset (prefix, 32, indent);
3961 prefix[indent] = '\0';
3963 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3964 if (map->map_actions)
3965 mdebug_dump_plist (map->map_actions, indent + 2);
3968 MPLIST_DO (map_list, map->submaps)
3970 fprintf (stderr, "\n%s ", prefix);
3971 dump_im_map (map_list, indent + 2);
3974 if (map->branch_actions)
3976 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3977 mdebug_dump_plist (map->branch_actions, indent + 4);
3978 fprintf (stderr, ")");
3980 fprintf (stderr, ")");
3985 dump_im_state (MIMState *state, int indent)
3990 prefix = (char *) alloca (indent + 1);
3991 memset (prefix, 32, indent);
3992 prefix[indent] = '\0';
3994 fprintf (stderr, "(%s", msymbol_name (state->name));
3995 if (state->map->submaps)
3997 MPLIST_DO (map_list, state->map->submaps)
3999 fprintf (stderr, "\n%s ", prefix);
4000 dump_im_map (map_list, indent + 2);
4003 fprintf (stderr, ")");
4011 Minput_driver = msymbol ("input-driver");
4013 Minput_preedit_start = msymbol ("input-preedit-start");
4014 Minput_preedit_done = msymbol ("input-preedit-done");
4015 Minput_preedit_draw = msymbol ("input-preedit-draw");
4016 Minput_status_start = msymbol ("input-status-start");
4017 Minput_status_done = msymbol ("input-status-done");
4018 Minput_status_draw = msymbol ("input-status-draw");
4019 Minput_candidates_start = msymbol ("input-candidates-start");
4020 Minput_candidates_done = msymbol ("input-candidates-done");
4021 Minput_candidates_draw = msymbol ("input-candidates-draw");
4022 Minput_set_spot = msymbol ("input-set-spot");
4023 Minput_focus_move = msymbol ("input-focus-move");
4024 Minput_focus_in = msymbol ("input-focus-in");
4025 Minput_focus_out = msymbol ("input-focus-out");
4026 Minput_toggle = msymbol ("input-toggle");
4027 Minput_reset = msymbol ("input-reset");
4028 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4029 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4030 Mcustomized = msymbol ("customized");
4031 Mconfigured = msymbol ("configured");
4032 Minherited = msymbol ("inherited");
4034 minput_default_driver.open_im = open_im;
4035 minput_default_driver.close_im = close_im;
4036 minput_default_driver.create_ic = create_ic;
4037 minput_default_driver.destroy_ic = destroy_ic;
4038 minput_default_driver.filter = filter;
4039 minput_default_driver.lookup = lookup;
4040 minput_default_driver.callback_list = mplist ();
4041 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4042 M17N_FUNC (reset_ic));
4043 minput_driver = &minput_default_driver;
4045 fully_initialized = 0;
4052 if (fully_initialized)
4054 free_im_list (im_info_list);
4056 free_im_list (im_custom_list);
4058 free_im_list (im_config_list);
4059 M17N_OBJECT_UNREF (load_im_info_keys);
4062 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4063 M17N_OBJECT_UNREF (minput_driver->callback_list);
4068 minput__char_to_key (int c)
4070 if (c < 0 || c >= 0x100)
4073 return one_char_symbol[c];
4077 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4082 /*** @addtogroup m17nInputMethod */
4087 @name Variables: Predefined symbols for callback commands.
4089 These are the predefined symbols that are used as the @c COMMAND
4090 argument of callback functions of an input method driver (see
4091 #MInputDriver::callback_list).
4093 Most of them do not require extra argument nor return any value;
4094 exceptions are these:
4096 Minput_get_surrounding_text: When a callback function assigned for
4097 this command is called, the first element of #MInputContext::plist
4098 has key #Minteger and the value specifies which portion of the
4099 surrounding text should be retrieved. If the value is positive,
4100 it specifies the number of characters following the current cursor
4101 position. If the value is negative, the absolute value specifies
4102 the number of characters preceding the current cursor position.
4103 If the value is zero, it means that the caller just wants to know
4104 if the surrounding text is currently supported or not.
4106 If the surrounding text is currently supported, the callback
4107 function must set the key of this element to #Mtext and the value
4108 to the retrieved M-text. The length of the M-text may be shorter
4109 than the requested number of characters, if the available text is
4110 not that long. The length can be zero in the worst case. Or, the
4111 length may be longer if an application thinks it is more efficient
4112 to return that length.
4114 If the surrounding text is not currently supported, the callback
4115 function should return without changing the first element of
4116 #MInputContext::plist.
4118 Minput_delete_surrounding_text: When a callback function assigned
4119 for this command is called, the first element of
4120 #MInputContext::plist has key #Minteger and the value specifies
4121 which portion of the surrounding text should be deleted in the
4122 same way as the case of Minput_get_surrounding_text. The callback
4123 function must delete the specified text. It should not alter
4124 #MInputContext::plist. */
4126 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4128 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4129 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4131 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4133 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4134 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4135 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4136 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4137 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4138 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4139 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4141 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4142 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4143 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4144 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4145 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4147 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4148 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4150 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4151 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4152 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4153 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4154 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4155 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4159 MSymbol Minput_preedit_start;
4160 MSymbol Minput_preedit_done;
4161 MSymbol Minput_preedit_draw;
4162 MSymbol Minput_status_start;
4163 MSymbol Minput_status_done;
4164 MSymbol Minput_status_draw;
4165 MSymbol Minput_candidates_start;
4166 MSymbol Minput_candidates_done;
4167 MSymbol Minput_candidates_draw;
4168 MSymbol Minput_set_spot;
4169 MSymbol Minput_toggle;
4170 MSymbol Minput_reset;
4171 MSymbol Minput_get_surrounding_text;
4172 MSymbol Minput_delete_surrounding_text;
4178 @name Variables: Predefined symbols for special input events.
4180 These are the predefined symbols that are used as the @c KEY
4181 argument of minput_filter (). */
4183 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4185 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4190 MSymbol Minput_focus_out;
4191 MSymbol Minput_focus_in;
4192 MSymbol Minput_focus_move;
4198 @name Variables: Predefined symbols used in input method information.
4200 These are the predefined symbols describing status of input method
4201 command and variable, and are used in a return value of
4202 minput_get_command () and minput_get_variable (). */
4204 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4206 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4207 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4211 MSymbol Mcustomized;
4212 MSymbol Mconfigured;
4218 @brief The default driver for internal input methods.
4220 The variable #minput_default_driver is the default driver for
4221 internal input methods.
4223 The member MInputDriver::open_im () searches the m17n database for
4224 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4225 $NAME\> and loads it.
4227 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4228 programmers responsibility to set it to a plist of proper callback
4229 functions. Otherwise, no feedback information (e.g. preedit text)
4230 can be shown to users.
4232 The macro M17N_INIT () sets the variable #minput_driver to the
4233 pointer to this driver so that all internal input methods use it.
4235 Therefore, unless @c minput_driver is set differently, the driver
4236 dependent arguments $ARG of the functions whose name begins with
4237 "minput_" are all ignored. */
4239 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4241 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4243 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4244 \< #Minput_method, $LANGUAGE, $NAME\>
4245 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4247 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4248 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4249 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4250 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4252 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4253 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4255 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4256 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4258 MInputDriver minput_default_driver;
4262 @brief The driver for internal input methods.
4264 The variable #minput_driver is a pointer to the input method
4265 driver that is used by internal input methods. The macro
4266 M17N_INIT () initializes it to a pointer to #minput_default_driver
4267 if <m17n<EM></EM>.h> is included. */
4269 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4271 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4272 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4273 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4274 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4276 MInputDriver *minput_driver;
4278 MSymbol Minput_driver;
4293 @brief Open an input method.
4295 The minput_open_im () function opens an input method whose
4296 language and name match $LANGUAGE and $NAME, and returns a pointer
4297 to the input method object newly allocated.
4299 This function at first decides a driver for the input method as
4302 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4303 #minput_driver is used.
4305 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4306 driver pointed to by the property value is used to open the input
4307 method. If $NAME has no such a property, @c NULL is returned.
4309 Then, the member MInputDriver::open_im () of the driver is
4312 $ARG is set in the member @c arg of the structure MInputMethod so
4313 that the driver can refer to it. */
4315 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4317 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4318 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4320 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4322 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4323 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4325 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4326 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4327 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4329 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4331 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4333 @latexonly \IPAlabel{minput_open} @endlatexonly
4338 minput_open_im (MSymbol language, MSymbol name, void *arg)
4341 MInputDriver *driver;
4345 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4346 msymbol_name (language), msymbol_name (name));
4350 MERROR (MERROR_IM, NULL);
4351 driver = minput_driver;
4355 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4357 MERROR (MERROR_IM, NULL);
4360 MSTRUCT_CALLOC (im, MERROR_IM);
4361 im->language = language;
4364 im->driver = *driver;
4365 if ((*im->driver.open_im) (im) < 0)
4367 MDEBUG_PRINT (" failed\n");
4371 MDEBUG_PRINT (" ok\n");
4378 @brief Close an input method.
4380 The minput_close_im () function closes the input method $IM, which
4381 must have been created by minput_open_im (). */
4384 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4386 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4387 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4390 minput_close_im (MInputMethod *im)
4392 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4393 msymbol_name (im->name), msymbol_name (im->language));
4394 (*im->driver.close_im) (im);
4396 MDEBUG_PRINT (" done\n");
4402 @brief Create an input context.
4404 The minput_create_ic () function creates an input context object
4405 associated with input method $IM, and calls callback functions
4406 corresponding to #Minput_preedit_start, #Minput_status_start, and
4407 #Minput_status_draw in this order.
4410 If an input context is successfully created, minput_create_ic ()
4411 returns a pointer to it. Otherwise it returns @c NULL. */
4414 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4416 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4417 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4418 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4419 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4422 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4423 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4427 minput_create_ic (MInputMethod *im, void *arg)
4431 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4432 msymbol_name (im->name), msymbol_name (im->language));
4433 MSTRUCT_CALLOC (ic, MERROR_IM);
4436 ic->preedit = mtext ();
4437 ic->candidate_list = NULL;
4438 ic->produced = mtext ();
4439 ic->spot.x = ic->spot.y = 0;
4441 ic->plist = mplist ();
4442 if ((*im->driver.create_ic) (ic) < 0)
4444 MDEBUG_PRINT (" failed\n");
4445 M17N_OBJECT_UNREF (ic->preedit);
4446 M17N_OBJECT_UNREF (ic->produced);
4447 M17N_OBJECT_UNREF (ic->plist);
4452 if (im->driver.callback_list)
4454 minput_callback (ic, Minput_preedit_start);
4455 minput_callback (ic, Minput_status_start);
4456 minput_callback (ic, Minput_status_draw);
4459 MDEBUG_PRINT (" ok\n");
4466 @brief Destroy an input context.
4468 The minput_destroy_ic () function destroys the input context $IC,
4469 which must have been created by minput_create_ic (). It calls
4470 callback functions corresponding to #Minput_preedit_done,
4471 #Minput_status_done, and #Minput_candidates_done in this order. */
4474 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4476 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4477 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4478 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4479 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4480 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4484 minput_destroy_ic (MInputContext *ic)
4486 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4487 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4488 if (ic->im->driver.callback_list)
4490 minput_callback (ic, Minput_preedit_done);
4491 minput_callback (ic, Minput_status_done);
4492 minput_callback (ic, Minput_candidates_done);
4494 (*ic->im->driver.destroy_ic) (ic);
4495 M17N_OBJECT_UNREF (ic->preedit);
4496 M17N_OBJECT_UNREF (ic->produced);
4497 M17N_OBJECT_UNREF (ic->plist);
4498 MDEBUG_PRINT (" done\n");
4505 @brief Filter an input key.
4507 The minput_filter () function filters input key $KEY according to
4508 input context $IC, and calls callback functions corresponding to
4509 #Minput_preedit_draw, #Minput_status_draw, and
4510 #Minput_candidates_draw if the preedit text, the status, and the
4511 current candidate are changed respectively.
4513 To make the input method commit the current preedit text (if any)
4514 and shift to the initial state, call this function with #Mnil as
4517 To inform the input method about the focus-out event, call this
4518 function with #Minput_focus_out as $KEY.
4520 To inform the input method about the focus-in event, call this
4521 function with #Minput_focus_in as $KEY.
4523 To inform the input method about the focus-move event (i.e. input
4524 spot change within the same input context), call this function
4525 with #Minput_focus_move as $KEY.
4528 If $KEY is filtered out, this function returns 1. In that case,
4529 the caller should discard the key. Otherwise, it returns 0, and
4530 the caller should handle the key, for instance, by calling the
4531 function minput_lookup () with the same key. */
4534 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4536 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4537 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4538 #Minput_preedit_draw, #Minput_status_draw,
4539 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4542 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4543 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4544 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4545 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4547 @latexonly \IPAlabel{minput_filter} @endlatexonly
4551 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4558 if (ic->im->driver.callback_list
4559 && mtext_nchars (ic->preedit) > 0)
4560 minput_callback (ic, Minput_preedit_draw);
4562 ret = (*ic->im->driver.filter) (ic, key, arg);
4564 if (ic->im->driver.callback_list)
4566 if (ic->preedit_changed)
4567 minput_callback (ic, Minput_preedit_draw);
4568 if (ic->status_changed)
4569 minput_callback (ic, Minput_status_draw);
4570 if (ic->candidates_changed)
4571 minput_callback (ic, Minput_candidates_draw);
4580 @brief Look up a text produced in the input context.
4582 The minput_lookup () function looks up a text in the input context
4583 $IC. $KEY must be identical to the one that was used in the previous call of
4586 If a text was produced by the input method, it is concatenated
4589 This function calls #MInputDriver::lookup .
4592 If $KEY was correctly handled by the input method, this function
4593 returns 0. Otherwise, it returns -1, even though some text
4594 might be produced in $MT. */
4597 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4599 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4600 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4602 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4605 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4608 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4609 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4610 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4612 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4615 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4617 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4622 @brief Set the spot of the input context.
4624 The minput_set_spot () function sets the spot of input context $IC
4625 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4626 The semantics of these values depends on the input method driver.
4628 For instance, a driver designed to work in a CUI environment may
4629 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4630 $DESCENT . A driver designed to work in a window system may
4631 interpret $X and $Y as the pixel offsets relative to the origin of the
4632 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4633 descent pixels of the line at ($X . $Y ).
4635 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4637 $MT and $POS are the M-text and the character position at the spot.
4638 $MT may be @c NULL, in which case, the input method cannot get
4639 information about the text around the spot. */
4642 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4644 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4645 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4646 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4648 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4649 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4650 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4651 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4652 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4653 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4655 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4657 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4658 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4662 minput_set_spot (MInputContext *ic, int x, int y,
4663 int ascent, int descent, int fontsize,
4668 ic->spot.ascent = ascent;
4669 ic->spot.descent = descent;
4670 ic->spot.fontsize = fontsize;
4673 if (ic->im->driver.callback_list)
4674 minput_callback (ic, Minput_set_spot);
4679 @brief Toggle input method.
4681 The minput_toggle () function toggles the input method associated
4682 with input context $IC. */
4684 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4686 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4687 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4691 minput_toggle (MInputContext *ic)
4693 if (ic->im->driver.callback_list)
4694 minput_callback (ic, Minput_toggle);
4695 ic->active = ! ic->active;
4701 @brief Reset an input context.
4703 The minput_reset_ic () function resets input context $IC by
4704 calling a callback function corresponding to #Minput_reset. It
4705 resets the status of $IC to its initial one. As the
4706 current preedit text is deleted without commitment, if necessary,
4707 call minput_filter () with the arg @r key #Mnil to force the input
4708 method to commit the preedit in advance. */
4711 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4713 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4714 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4715 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4716 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4717 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4718 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4721 minput_reset_ic (MInputContext *ic)
4723 if (ic->im->driver.callback_list)
4724 minput_callback (ic, Minput_reset);
4730 @brief Get title and icon filename of an input method.
4732 The minput_get_title_icon () function returns a plist containing a
4733 title and icon filename (if any) of an input method specified by
4734 $LANGUAGE and $NAME.
4736 The first element of the plist has key #Mtext and the value is an
4737 M-text of the title for identifying the input method. The second
4738 element (if any) has key #Mtext and the value is an M-text of the
4739 icon image (absolute) filename for the same purpose.
4742 If there exists a specified input method and it defines an title,
4743 a plist is returned. Otherwise, NULL is returned. The caller
4744 must free the plist by m17n_object_unref (). */
4746 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4748 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4749 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4752 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4753 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4754 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4757 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4758 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4759 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4762 minput_get_title_icon (MSymbol language, MSymbol name)
4764 MInputMethodInfo *im_info;
4771 im_info = get_im_info (language, name, Mnil, Mtitle);
4772 if (! im_info || !im_info->title)
4774 mt = mtext_get_prop (im_info->title, 0, Mtext);
4776 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4779 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4782 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4783 (char *) MSYMBOL_NAME (name));
4784 file = mdatabase__find_file (buf);
4785 if (! file && language == Mt)
4787 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4788 file = mdatabase__find_file (buf);
4793 mplist_add (plist, Mtext, im_info->title);
4796 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4798 mplist_add (plist, Mtext, mt);
4799 M17N_OBJECT_UNREF (mt);
4807 @brief Get description text of an input method.
4809 The minput_get_description () function returns an M-text that
4810 describes the input method specified by $LANGUAGE and $NAME.
4813 If the specified input method has a description text, a pointer to
4814 #MText is returned. The caller has to free it by m17n_object_unref ().
4815 If the input method does not have a description text, @c NULL is
4818 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4820 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4821 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4824 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4825 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4826 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4827 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4830 minput_get_description (MSymbol language, MSymbol name)
4832 MInputMethodInfo *im_info;
4840 extra = language, language = Mt;
4842 im_info = get_im_info (language, name, extra, Mdescription);
4843 if (! im_info || ! im_info->description)
4845 M17N_OBJECT_REF (im_info->description);
4846 return im_info->description;
4852 @brief Get information about input method command(s).
4854 The minput_get_command () function returns information about
4855 the command $COMMAND of the input method specified by $LANGUAGE and
4856 $NAME. An input method command is a pseudo key event to which one
4857 or more actual input key sequences are assigned.
4859 There are two kinds of commands, global and local. A global
4860 command has a global definition, and the description and the key
4861 assignment may be inherited by a local command. Each input method
4862 defines a local command which has a local key assignment. It may
4863 also declare a local command that inherits the definition of a
4864 global command of the same name.
4866 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4867 information about a global command. Otherwise information about a
4868 local command is returned.
4870 If $COMMAND is #Mnil, information about all commands is returned.
4872 The return value is a @e well-formed plist (@ref m17nPlist) of this
4875 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4877 @c NAME is a symbol representing the command name.
4879 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4880 command has no description.
4882 @c STATUS is a symbol representing how the key assignment is decided.
4883 The value is #Mnil (the default key assignment), #Mcustomized (the
4884 key assignment is customized by per-user customization file), or
4885 #Mconfigured (the key assignment is set by the call of
4886 minput_config_command ()). For a local command only, it may also
4887 be #Minherited (the key assignment is inherited from the
4888 corresponding global command).
4890 @c KEYSEQ is a plist of one or more symbols representing a key
4891 sequence assigned to the command. If there's no KEYSEQ, the
4892 command is currently disabled (i.e. no key sequence can trigger
4893 actions of the command).
4895 If $COMMAND is not #Mnil, the first element of the returned plist
4896 contains the information about $COMMAND.
4900 If the requested information was found, a pointer to a non-empty
4901 plist is returned. As the plist is kept in the library, the
4902 caller must not modify nor free it.
4904 Otherwise (the specified input method or the specified command
4905 does not exist), @c NULL is returned. */
4907 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4909 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4910 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4911 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4912 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4914 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4915 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4916 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4917 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4918 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4920 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4921 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4924 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4926 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4929 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4931 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4933 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4936 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4937 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4938 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4939 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4940 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4941 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4944 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4945 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4946 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4947 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4949 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4950 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4954 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4955 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4958 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4963 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4965 /* Return a description of the command COMMAND of the input method
4966 specified by LANGUAGE and NAME. */
4967 MPlist *cmd = minput_get_command (langauge, name, command);
4972 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4973 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4974 return (mplist_key (plist) == Mtext
4975 ? (MText *) mplist_value (plist)
4981 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4983 MInputMethodInfo *im_info;
4987 im_info = get_im_info (language, name, Mnil, Mcommand);
4989 || ! im_info->configured_cmds
4990 || MPLIST_TAIL_P (im_info->configured_cmds))
4992 if (command == Mnil)
4993 return im_info->configured_cmds;
4994 return mplist__assq (im_info->configured_cmds, command);
5000 @brief Configure the key sequence of an input method command.
5002 The minput_config_command () function assigns a list of key
5003 sequences $KEYSEQLIST to the command $COMMAND of the input method
5004 specified by $LANGUAGE and $NAME.
5006 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5007 sequences, and each key sequence must be a plist of symbols.
5009 If $KEYSEQLIST is an empty plist, any configuration and
5010 customization of the command are cancelled, and default key
5011 sequences become effective.
5013 If $KEYSEQLIST is NULL, the configuration of the command is
5014 canceled, and the original key sequences (what saved in per-user
5015 customization file, or the default one) become effective.
5017 In the latter two cases, $COMMAND can be #Mnil to make all the
5018 commands of the input method the target of the operation.
5020 If $NAME is #Mnil, this function configures the key assignment of a
5021 global command, not that of a specific input method.
5023 The configuration takes effect for input methods opened or
5024 re-opened later in the current session. In order to make the
5025 configuration take effect for the future session, it must be saved
5026 in a per-user customization file by the function
5027 minput_save_config ().
5030 If the operation was successful, this function returns 0,
5031 otherwise returns -1. The operation fails in these cases:
5033 <li>$KEYSEQLIST is not in a valid form.
5034 <li>$COMMAND is not available for the input method.
5035 <li>$LANGUAGE and $NAME do not specify an existing input method.
5039 minput_get_commands (), minput_save_config ().
5042 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5044 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5045 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5046 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5048 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5049 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5051 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5052 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5054 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5055 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5056 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5058 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5059 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5061 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5062 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5064 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5065 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5066 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5067 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5071 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5073 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5074 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5075 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5079 minput_get_commands (), minput_save_config ().
5083 /* Add "C-x u" to the "start" command of Unicode input method. */
5085 MSymbol start_command = msymbol ("start");
5086 MSymbol unicode = msymbol ("unicode");
5087 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5089 /* At first get the current key-sequence assignment. */
5090 cmd = minput_get_command (Mt, unicode, start_command);
5093 /* The input method does not have the command "start". Here
5094 should come some error handling code. */
5096 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5097 Extract the part (KEY-SEQUENCE ...). */
5098 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5099 /* Copy it because we should not modify it directly. */
5100 key_seq_list = mplist_copy (plist);
5102 key_seq = mplist ();
5103 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5104 mplist_add (key_seq, Msymbol, msymbol ("u"));
5105 mplist_add (key_seq_list, Mplist, key_seq);
5106 m17n_object_unref (key_seq);
5108 minput_config_command (Mt, unicode, start_command, key_seq_list);
5109 m17n_object_unref (key_seq_list);
5114 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5117 MInputMethodInfo *im_info, *config;
5122 im_info = get_im_info (language, name, Mnil, Mcommand);
5124 MERROR (MERROR_IM, -1);
5125 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5127 || ! mplist__assq (im_info->configured_cmds, command)))
5128 MERROR (MERROR_IM, -1);
5129 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5131 MPLIST_DO (plist, keyseqlist)
5132 if (! check_command_keyseq (plist))
5133 MERROR (MERROR_IM, -1);
5136 config = get_config_info (im_info);
5139 if (! im_config_list)
5140 im_config_list = mplist ();
5141 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5142 config->cmds = mplist ();
5143 config->vars = mplist ();
5146 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5147 /* Nothing to do. */
5150 if (command == Mnil)
5154 /* Cancal the configuration. */
5155 if (MPLIST_TAIL_P (config->cmds))
5157 mplist_set (config->cmds, Mnil, NULL);
5161 /* Cancal the customization. */
5162 MInputMethodInfo *custom = get_custom_info (im_info);
5164 if (MPLIST_TAIL_P (config->cmds)
5165 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5166 /* Nothing to do. */
5168 mplist_set (config->cmds, Mnil, NULL);
5169 MPLIST_DO (plist, custom->cmds)
5171 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5173 mplist_add (plist, Msymbol, command);
5174 mplist_push (config->cmds, Mplist, plist);
5175 M17N_OBJECT_UNREF (plist);
5181 plist = mplist__assq (config->cmds, command);
5184 /* Cancel the configuration. */
5187 mplist__pop_unref (plist);
5189 else if (MPLIST_TAIL_P (keyseqlist))
5191 /* Cancel the customization. */
5192 MInputMethodInfo *custom = get_custom_info (im_info);
5193 int no_custom = (! custom || ! custom->cmds
5194 || ! mplist__assq (custom->cmds, command));
5200 mplist_add (config->cmds, Mplist, plist);
5201 M17N_OBJECT_UNREF (plist);
5202 plist = mplist_add (plist, Msymbol, command);
5207 mplist__pop_unref (plist);
5210 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5211 plist = MPLIST_NEXT (plist);
5212 mplist_set (plist, Mnil, NULL);
5222 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5223 if (! MPLIST_TAIL_P (plist))
5224 mplist_set (plist, Mnil, NULL);
5229 mplist_add (config->cmds, Mplist, plist);
5230 M17N_OBJECT_UNREF (plist);
5231 plist = mplist_add (plist, Msymbol, command);
5232 plist = MPLIST_NEXT (plist);
5234 MPLIST_DO (keyseqlist, keyseqlist)
5236 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5237 plist = mplist_add (plist, Mplist, pl);
5238 M17N_OBJECT_UNREF (pl);
5242 config_all_commands (im_info);
5243 im_info->tick = time (NULL);
5250 @brief Get information about input method variable(s).
5252 The minput_get_variable () function returns information about
5253 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5254 An input method variable controls behavior of an input method.
5256 There are two kinds of variables, global and local. A global
5257 variable has a global definition, and the description and the value
5258 may be inherited by a local variable. Each input method defines a
5259 local variable which has local value. It may also declare a
5260 local variable that inherits definition of a global variable of
5263 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5264 variable is returned. Otherwise information about a local variable
5267 If $VARIABLE is #Mnil, information about all variables is
5270 The return value is a @e well-formed plist (@ref m17nPlist) of this
5273 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5275 @c NAME is a symbol representing the variable name.
5277 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5278 variable has no description.
5280 @c STATUS is a symbol representing how the value is decided. The
5281 value is #Mnil (the default value), #Mcustomized (the value is
5282 customized by per-user customization file), or #Mconfigured (the
5283 value is set by the call of minput_config_variable ()). For a
5284 local variable only, it may also be #Minherited (the value is
5285 inherited from the corresponding global variable).
5287 @c VALUE is the initial value of the variable. If the key of this
5288 element is #Mt, the variable has no initial value. Otherwise, the
5289 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5292 @c VALID-VALUEs (if any) specify which values the variable can have.
5293 They have the same type (i.e. having the same key) as @c VALUE except
5294 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5295 may be a plist of two integers specifying the range of possible
5298 If there no @c VALID-VALUE, the variable can have any value as long
5299 as the type is the same as @c VALUE.
5301 If $VARIABLE is not #Mnil, the first element of the returned plist
5302 contains the information about $VARIABLE.
5306 If the requested information was found, a pointer to a non-empty
5307 plist is returned. As the plist is kept in the library, the
5308 caller must not modify nor free it.
5310 Otherwise (the specified input method or the specified variable
5311 does not exist), @c NULL is returned. */
5313 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5315 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5316 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5317 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5319 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5320 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5321 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5322 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5325 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5326 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5328 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5330 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5332 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5335 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5337 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5340 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5341 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5342 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5343 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5344 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5345 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5347 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5348 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5349 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5351 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5352 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5353 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5354 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5356 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5359 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5360 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5364 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5365 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5368 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5372 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5374 MInputMethodInfo *im_info;
5378 im_info = get_im_info (language, name, Mnil, Mvariable);
5379 if (! im_info || ! im_info->configured_vars)
5381 if (variable == Mnil)
5382 return im_info->configured_vars;
5383 return mplist__assq (im_info->configured_vars, variable);
5389 @brief Configure the value of an input method variable.
5391 The minput_config_variable () function assigns $VALUE to the
5392 variable $VARIABLE of the input method specified by $LANGUAGE and
5395 If $VALUE is a non-empty plist, it must be a plist of one element
5396 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5397 the corresponding type. That value is assigned to the variable.
5399 If $VALUE is an empty plist, any configuration and customization
5400 of the variable are canceled, and the default value is assigned to
5403 If $VALUE is NULL, the configuration of the variable is canceled,
5404 and the original value (what saved in per-user customization file,
5405 or the default value) is assigned to the variable.
5407 In the latter two cases, $VARIABLE can be #Mnil to make all the
5408 variables of the input method the target of the operation.
5410 If $NAME is #Mnil, this function configures the value of global
5411 variable, not that of a specific input method.
5413 The configuration takes effect for input methods opened or
5414 re-opened later in the current session. To make the configuration
5415 take effect for the future session, it must be saved in a per-user
5416 customization file by the function minput_save_config ().
5420 If the operation was successful, this function returns 0,
5421 otherwise returns -1. The operation fails in these cases:
5423 <li>$VALUE is not in a valid form, the type does not match the
5424 definition, or the value is our of range.
5425 <li>$VARIABLE is not available for the input method.
5426 <li>$LANGUAGE and $NAME do not specify an existing input method.
5430 minput_get_variable (), minput_save_config (). */
5432 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5434 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5435 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5437 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5438 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5439 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5441 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5442 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5444 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5445 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5447 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5448 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5450 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5451 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5453 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5454 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5455 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5456 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5460 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5462 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5463 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5464 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5468 minput_get_commands (), minput_save_config ().
5471 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5474 MInputMethodInfo *im_info, *config;
5479 im_info = get_im_info (language, name, Mnil, Mvariable);
5481 MERROR (MERROR_IM, -1);
5482 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5484 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5485 MERROR (MERROR_IM, -1);
5487 if (value && ! MPLIST_TAIL_P (value))
5489 plist = MPLIST_PLIST (plist);
5490 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5491 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5492 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5493 if (MPLIST_KEY (plist) != Mt
5494 && ! check_variable_value (value, plist))
5495 MERROR (MERROR_IM, -1);
5498 config = get_config_info (im_info);
5501 if (! im_config_list)
5502 im_config_list = mplist ();
5503 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5504 config->cmds = mplist ();
5505 config->vars = mplist ();
5508 if (! value && MPLIST_TAIL_P (config->vars))
5509 /* Nothing to do. */
5512 if (variable == Mnil)
5516 /* Cancel the configuration. */
5517 if (MPLIST_TAIL_P (config->vars))
5519 mplist_set (config->vars, Mnil, NULL);
5523 /* Cancel the customization. */
5524 MInputMethodInfo *custom = get_custom_info (im_info);
5526 if (MPLIST_TAIL_P (config->vars)
5527 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5528 /* Nothing to do. */
5530 mplist_set (config->vars, Mnil, NULL);
5531 MPLIST_DO (plist, custom->vars)
5533 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5535 mplist_add (plist, Msymbol, variable);
5536 mplist_push (config->vars, Mplist, plist);
5537 M17N_OBJECT_UNREF (plist);
5543 plist = mplist__assq (config->vars, variable);
5546 /* Cancel the configuration. */
5549 mplist__pop_unref (plist);
5551 else if (MPLIST_TAIL_P (value))
5553 /* Cancel the customization. */
5554 MInputMethodInfo *custom = get_custom_info (im_info);
5555 int no_custom = (! custom || ! custom->vars
5556 || ! mplist__assq (custom->vars, variable));
5562 mplist_add (config->vars, Mplist, plist);
5563 M17N_OBJECT_UNREF (plist);
5564 plist = mplist_add (plist, Msymbol, variable);
5569 mplist__pop_unref (plist);
5572 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5573 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5574 mplist_set (plist, Mnil ,NULL);
5582 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5583 if (! MPLIST_TAIL_P (plist))
5584 mplist_set (plist, Mnil, NULL);
5589 mplist_add (config->vars, Mplist, plist);
5590 M17N_OBJECT_UNREF (plist);
5591 plist = mplist_add (plist, Msymbol, variable);
5592 plist = MPLIST_NEXT (plist);
5594 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5597 config_all_variables (im_info);
5598 im_info->tick = time (NULL);
5605 @brief Get the name of per-user customization file.
5607 The minput_config_file () function returns the absolute path name
5608 of per-user customization file into which minput_save_config ()
5609 save configurations. It is usually @c config.mic under the
5610 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5611 directory). It is not assured that the file of the returned name
5612 exists nor is readable/writable. If minput_save_config () fails
5613 and returns -1, an application program might check the file, make
5614 it writable (if possible), and try minput_save_config () again.
5618 This function returns a string. As the string is kept in the
5619 library, the caller must not modify nor free it.
5622 minput_save_config ()
5625 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5627 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5628 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5629 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5630 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5631 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5632 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5633 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5638 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5639 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5642 minput_save_config ()
5646 minput_config_file ()
5650 return mdatabase__file (im_custom_mdb);
5656 @brief Save configurations in per-user customization file.
5658 The minput_save_config () function saves the configurations done
5659 so far in the current session into the per-user customization
5664 If the operation was successful, 1 is returned. If the per-user
5665 customization file is currently locked, 0 is returned. In that
5666 case, the caller may wait for a while and try again. If the
5667 configuration file is not writable, -1 is returned. In that case,
5668 the caller may check the name of the file by calling
5669 minput_config_file (), make it writable if possible, and try
5673 minput_config_file () */
5675 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5677 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5678 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5682 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5683 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5684 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5685 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5689 minput_config_file () */
5692 minput_save_config (void)
5694 MPlist *data, *tail, *plist, *p, *elt;
5698 ret = mdatabase__lock (im_custom_mdb);
5701 if (! im_config_list)
5703 update_custom_info ();
5704 if (! im_custom_list)
5705 im_custom_list = mplist ();
5707 /* At first, reflect configuration in customization. */
5708 MPLIST_DO (plist, im_config_list)
5710 MPlist *pl = MPLIST_PLIST (plist);
5711 MSymbol language, name, extra, command, variable;
5712 MInputMethodInfo *custom, *config;
5714 language = MPLIST_SYMBOL (pl);
5715 pl = MPLIST_NEXT (pl);
5716 name = MPLIST_SYMBOL (pl);
5717 pl = MPLIST_NEXT (pl);
5718 extra = MPLIST_SYMBOL (pl);
5719 pl = MPLIST_NEXT (pl);
5720 config = MPLIST_VAL (pl);
5721 custom = get_custom_info (config);
5723 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5725 MPLIST_DO (pl, config->cmds)
5727 elt = MPLIST_PLIST (pl);
5728 command = MPLIST_SYMBOL (elt);
5730 p = mplist__assq (custom->cmds, command);
5732 custom->cmds = mplist (), p = NULL;
5733 elt = MPLIST_NEXT (elt);
5736 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5737 mplist_set (p, Mnil, NULL);
5742 mplist_add (custom->cmds, Mplist, p);
5743 M17N_OBJECT_UNREF (p);
5744 mplist_add (p, Msymbol, command);
5745 p = mplist_add (p, Msymbol, Mnil);
5746 p = MPLIST_NEXT (p);
5748 mplist__conc (p, elt);
5751 MPLIST_DO (pl, config->vars)
5753 elt = MPLIST_PLIST (pl);
5754 variable = MPLIST_SYMBOL (elt);
5756 p = mplist__assq (custom->vars, variable);
5758 custom->vars = mplist (), p = NULL;
5759 elt = MPLIST_NEXT (elt);
5762 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5763 mplist_set (p, Mnil, NULL);
5768 mplist_add (custom->vars, Mplist, p);
5769 M17N_OBJECT_UNREF (p);
5770 mplist_add (p, Msymbol, variable);
5771 p = mplist_add (p, Msymbol, Mnil);
5772 p = MPLIST_NEXT (p);
5774 mplist__conc (p, elt);
5777 free_im_list (im_config_list);
5778 im_config_list = NULL;
5780 /* Next, reflect customization to the actual plist to be written. */
5781 data = tail = mplist ();
5782 MPLIST_DO (plist, im_custom_list)
5784 MPlist *pl = MPLIST_PLIST (plist);
5785 MSymbol language, name, extra;
5786 MInputMethodInfo *custom, *im_info;
5788 language = MPLIST_SYMBOL (pl);
5789 pl = MPLIST_NEXT (pl);
5790 name = MPLIST_SYMBOL (pl);
5791 pl = MPLIST_NEXT (pl);
5792 extra = MPLIST_SYMBOL (pl);
5793 pl = MPLIST_NEXT (pl);
5794 custom = MPLIST_VAL (pl);
5795 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5796 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5798 im_info = lookup_im_info (im_info_list, language, name, extra);
5802 config_all_commands (im_info);
5804 config_all_variables (im_info);
5808 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5810 MPLIST_DO (p, custom->cmds)
5811 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5813 if (! MPLIST_TAIL_P (p))
5817 mplist_add (elt, Mplist, pl);
5818 M17N_OBJECT_UNREF (pl);
5819 pl = mplist_add (pl, Msymbol, Mcommand);
5820 MPLIST_DO (p, custom->cmds)
5821 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5822 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5825 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5827 MPLIST_DO (p, custom->vars)
5828 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5830 if (! MPLIST_TAIL_P (p))
5835 mplist_add (elt, Mplist, pl);
5836 M17N_OBJECT_UNREF (pl);
5837 pl = mplist_add (pl, Msymbol, Mvariable);
5838 MPLIST_DO (p, custom->vars)
5839 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5840 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5846 mplist_push (elt, Mplist, pl);
5847 M17N_OBJECT_UNREF (pl);
5848 pl = mplist_add (pl, Msymbol, Minput_method);
5849 pl = mplist_add (pl, Msymbol, language);
5850 pl = mplist_add (pl, Msymbol, name);
5852 pl = mplist_add (pl, Msymbol, extra);
5853 tail = mplist_add (tail, Mplist, elt);
5854 M17N_OBJECT_UNREF (elt);
5858 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5859 ret = mdatabase__save (im_custom_mdb, data);
5860 mdatabase__unlock (im_custom_mdb);
5861 M17N_OBJECT_UNREF (data);
5862 return (ret < 0 ? -1 : 1);
5869 @name Obsolete functions
5872 @name Obsolete ¤Ê´Ø¿ô
5878 @brief Get a list of variables of an input method (obsolete).
5880 This function is obsolete. Use minput_get_variable () instead.
5882 The minput_get_variables () function returns a plist (#MPlist) of
5883 variables used to control the behavior of the input method
5884 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5885 (@ref m17nPlist) of the following format:
5888 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5889 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5893 @c VARNAME is a symbol representing the variable name.
5895 @c DOC-MTEXT is an M-text describing the variable.
5897 @c DEFAULT-VALUE is the default value of the variable. It is a
5898 symbol, integer, or M-text.
5900 @c VALUEs (if any) specifies the possible values of the variable.
5901 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5902 @c TO), where @c FROM and @c TO specifies a range of possible
5905 For instance, suppose an input method has the variables:
5907 @li name:intvar, description:"value is an integer",
5908 initial value:0, value-range:0..3,10,20
5910 @li name:symvar, description:"value is a symbol",
5911 initial value:nil, value-range:a, b, c, nil
5913 @li name:txtvar, description:"value is an M-text",
5914 initial value:empty text, no value-range (i.e. any text)
5916 Then, the returned plist is as follows.
5919 (intvar ("value is an integer" 0 (0 3) 10 20)
5920 symvar ("value is a symbol" nil a b c nil)
5921 txtvar ("value is an M-text" ""))
5925 If the input method uses any variables, a pointer to #MPlist is
5926 returned. As the plist is kept in the library, the caller must not
5927 modify nor free it. If the input method does not use any
5928 variable, @c NULL is returned. */
5930 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5932 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5933 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5934 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5938 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5939 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5943 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5945 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5947 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5950 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5951 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5952 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5954 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5956 @li name:intvar, ÀâÌÀ:"value is an integer",
5957 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5959 @li name:symvar, ÀâÌÀ:"value is a symbol",
5960 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5962 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5963 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5965 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5968 (intvar ("value is an integer" 0 (0 3) 10 20)
5969 symvar ("value is a symbol" nil a b c nil)
5970 txtvar ("value is an M-text" ""))
5974 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5975 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5976 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5979 minput_get_variables (MSymbol language, MSymbol name)
5981 MInputMethodInfo *im_info;
5986 im_info = get_im_info (language, name, Mnil, Mvariable);
5987 if (! im_info || ! im_info->configured_vars)
5990 M17N_OBJECT_UNREF (im_info->bc_vars);
5991 im_info->bc_vars = mplist ();
5992 MPLIST_DO (vars, im_info->configured_vars)
5994 MPlist *plist = MPLIST_PLIST (vars);
5995 MPlist *elt = mplist ();
5997 mplist_push (im_info->bc_vars, Mplist, elt);
5998 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5999 elt = MPLIST_NEXT (elt);
6000 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6001 M17N_OBJECT_UNREF (elt);
6003 return im_info->bc_vars;
6009 @brief Set the initial value of an input method variable.
6011 The minput_set_variable () function sets the initial value of
6012 input method variable $VARIABLE to $VALUE for the input method
6013 specified by $LANGUAGE and $NAME.
6015 By default, the initial value is 0.
6017 This setting gets effective in a newly opened input method.
6020 If the operation was successful, 0 is returned. Otherwise -1 is
6021 returned, and #merror_code is set to #MERROR_IM. */
6023 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6025 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6026 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6027 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6029 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6031 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6034 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6035 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6038 minput_set_variable (MSymbol language, MSymbol name,
6039 MSymbol variable, void *value)
6042 MInputMethodInfo *im_info;
6047 if (variable == Mnil)
6048 MERROR (MERROR_IM, -1);
6049 plist = minput_get_variable (language, name, variable);
6050 plist = MPLIST_PLIST (plist);
6051 plist = MPLIST_NEXT (plist);
6053 mplist_add (pl, MPLIST_KEY (plist), value);
6054 ret = minput_config_variable (language, name, variable, pl);
6055 M17N_OBJECT_UNREF (pl);
6058 im_info = get_im_info (language, name, Mnil, Mvariable);
6067 @brief Get information about input method commands.
6069 The minput_get_commands () function returns information about
6070 input method commands of the input method specified by $LANGUAGE
6071 and $NAME. An input method command is a pseudo key event to which
6072 one or more actual input key sequences are assigned.
6074 There are two kinds of commands, global and local. Global
6075 commands are used by multiple input methods for the same purpose,
6076 and have global key assignments. Local commands are used only by
6077 a specific input method, and have only local key assignments.
6079 Each input method may locally change key assignments for global
6080 commands. The global key assignment for a global command is
6081 effective only when the current input method does not have local
6082 key assignments for that command.
6084 If $NAME is #Mnil, information about global commands is returned.
6085 In this case $LANGUAGE is ignored.
6087 If $NAME is not #Mnil, information about those commands that have
6088 local key assignments in the input method specified by $LANGUAGE
6089 and $NAME is returned.
6092 If no input method commands are found, this function returns @c NULL.
6094 Otherwise, a pointer to a plist is returned. The key of each
6095 element in the plist is a symbol representing a command, and the
6096 value is a plist of the form COMMAND-INFO described below.
6098 The first element of COMMAND-INFO has the key #Mtext, and the
6099 value is an M-text describing the command.
6101 If there are no more elements, that means no key sequences are
6102 assigned to the command. Otherwise, each of the remaining
6103 elements has the key #Mplist, and the value is a plist whose keys are
6104 #Msymbol and values are symbols representing input keys, which are
6105 currently assigned to the command.
6107 As the returned plist is kept in the library, the caller must not
6108 modify nor free it. */
6110 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6112 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6113 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6114 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6115 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6117 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6118 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6119 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6120 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6122 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6123 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6124 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6127 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6128 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6130 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6131 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6135 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6137 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6138 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6139 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6141 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6142 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6143 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6146 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6147 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6148 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6149 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6150 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6152 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6153 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6156 minput_get_commands (MSymbol language, MSymbol name)
6158 MInputMethodInfo *im_info;
6163 im_info = get_im_info (language, name, Mnil, Mcommand);
6164 if (! im_info || ! im_info->configured_vars)
6166 M17N_OBJECT_UNREF (im_info->bc_cmds);
6167 im_info->bc_cmds = mplist ();
6168 MPLIST_DO (cmds, im_info->configured_cmds)
6170 MPlist *plist = MPLIST_PLIST (cmds);
6171 MPlist *elt = mplist ();
6173 mplist_push (im_info->bc_cmds, Mplist, elt);
6174 mplist_add (elt, MPLIST_SYMBOL (plist),
6175 mplist_copy (MPLIST_NEXT (plist)));
6176 M17N_OBJECT_UNREF (elt);
6178 return im_info->bc_cmds;
6184 @brief Assign a key sequence to an input method command (obsolete).
6186 This function is obsolete. Use minput_config_command () instead.
6188 The minput_assign_command_keys () function assigns input key
6189 sequence $KEYSEQ to input method command $COMMAND for the input
6190 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6191 key sequence is assigned globally no matter what $LANGUAGE is.
6192 Otherwise the key sequence is assigned locally.
6194 Each element of $KEYSEQ must have the key $Msymbol and the value
6195 must be a symbol representing an input key.
6197 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6198 globally or locally.
6200 This assignment gets effective in a newly opened input method.
6203 If the operation was successful, 0 is returned. Otherwise -1 is
6204 returned, and #merror_code is set to #MERROR_IM. */
6206 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6208 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6209 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6210 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6211 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6212 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6214 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6215 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6217 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6218 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6220 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6224 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6225 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6228 minput_assign_command_keys (MSymbol language, MSymbol name,
6229 MSymbol command, MPlist *keyseq)
6235 if (command == Mnil)
6236 MERROR (MERROR_IM, -1);
6241 if (! check_command_keyseq (keyseq))
6242 MERROR (MERROR_IM, -1);
6244 mplist_add (plist, Mplist, keyseq);
6249 ret = minput_config_command (language, name, command, keyseq);
6250 M17N_OBJECT_UNREF (keyseq);
6257 @brief Call a callback function
6259 The minput_callback () functions calls a callback function
6260 $COMMAND assigned for the input context $IC. The caller must set
6261 specific elements in $IC->plist if the callback function requires.
6264 If there exists a specified callback function, 0 is returned.
6265 Otherwise -1 is returned. By side effects, $IC->plist may be
6269 minput_callback (MInputContext *ic, MSymbol command)
6271 MInputCallbackFunc func;
6273 if (! ic->im->driver.callback_list)
6275 func = ((MInputCallbackFunc)
6276 mplist_get_func (ic->im->driver.callback_list, command));
6279 (func) (ic, command);
6286 /*** @addtogroup m17nDebug */
6292 @brief Dump an input method.
6294 The mdebug_dump_im () function prints the input method $IM in a
6295 human readable way to the stderr. $INDENT specifies how many
6296 columns to indent the lines but the first one.
6299 This function returns $IM. */
6301 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6303 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6304 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6307 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6310 mdebug_dump_im (MInputMethod *im, int indent)
6312 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6315 prefix = (char *) alloca (indent + 1);
6316 memset (prefix, 32, indent);
6317 prefix[indent] = '\0';
6319 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6320 msymbol_name (im->name));
6321 mdebug_dump_mtext (im_info->title, 0, 0);
6322 if (im->name != Mnil)
6326 MPLIST_DO (state, im_info->states)
6328 fprintf (stderr, "\n%s ", prefix);
6329 dump_im_state (MPLIST_VAL (state), indent + 2);
6332 fprintf (stderr, ")");