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];
284 /* Maximum case: 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 */
348 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
351 /* `C-M-a' == `C-A-a' */
353 alias[j++] = one_char_symbol[i] = msymbol (buf);
355 alias[j++] = msymbol (buf);
356 if (key_names[i - 128])
358 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
360 strcpy (buf2 + 2, key_names[i - 128]);
361 alias[j++] = msymbol (buf2);
363 alias[j++] = msymbol (buf2);
365 if (buf[4] >= 'A' && buf[4] <= 'Z')
367 /* Ex: `C-M-a' == `C-M-A'. */
370 alias[j++] = msymbol (buf);
372 alias[j++] = msymbol (buf);
375 /* Establish cyclic alias chain. */
378 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
381 /* Aliases for 0xA0-0xFF */
382 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
385 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
387 alias[1] = msymbol (buf + 2);
388 for (j = 0; j < 2; j++)
389 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
390 if (buf[4] < 'A' || (buf[4] > 'Z' && buf[4] < 'a') || buf[4] > 'z')
393 alias[0] = alias[2] = msymbol (buf);
395 alias[1] = msymbol (buf);
396 for (j = 0; j < 2; j++)
397 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
401 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
402 alias[1] = msymbol ("A-Delete");
403 alias[2] = msymbol ("C-M-?");
404 alias[3] = msymbol ("C-A-?");
405 for (j = 0; j < 4; j++)
406 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
408 Minput_method = msymbol ("input-method");
409 Mtitle = msymbol ("title");
410 Mmacro = msymbol ("macro");
411 Mmodule = msymbol ("module");
412 Mmap = msymbol ("map");
413 Mstate = msymbol ("state");
414 Minclude = msymbol ("include");
415 Minsert = msymbol ("insert");
416 M_candidates = msymbol (" candidates");
417 Mdelete = msymbol ("delete");
418 Mmove = msymbol ("move");
419 Mmark = msymbol ("mark");
420 Mpushback = msymbol ("pushback");
421 Mpop = msymbol ("pop");
422 Mundo = msymbol ("undo");
423 Mcall = msymbol ("call");
424 Mshift = msymbol ("shift");
425 Mselect = msymbol ("select");
426 Mshow = msymbol ("show");
427 Mhide = msymbol ("hide");
428 Mcommit = msymbol ("commit");
429 Munhandle = msymbol ("unhandle");
430 Mset = msymbol ("set");
431 Madd = msymbol ("add");
432 Msub = msymbol ("sub");
433 Mmul = msymbol ("mul");
434 Mdiv = msymbol ("div");
435 Mequal = msymbol ("=");
436 Mless = msymbol ("<");
437 Mgreater = msymbol (">");
438 Mless_equal = msymbol ("<=");
439 Mgreater_equal = msymbol (">=");
440 Mcond = msymbol ("cond");
441 Mplus = msymbol ("+");
442 Mminus = msymbol ("-");
443 Mstar = msymbol ("*");
444 Mslash = msymbol ("/");
445 Mand = msymbol ("&");
447 Mnot = msymbol ("!");
449 Mat_reload = msymbol ("@reload");
451 Mcandidates_group_size = msymbol ("candidates-group-size");
452 Mcandidates_charset = msymbol ("candidates-charset");
454 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
455 Mcandidate_index = msymbol (" candidate-index");
457 Minit = msymbol ("init");
458 Mfini = msymbol ("fini");
460 Mdescription = msymbol ("description");
461 Mcommand = msymbol ("command");
462 Mvariable = msymbol ("variable");
463 Mglobal = msymbol ("global");
464 Mconfig = msymbol ("config");
465 M_gettext = msymbol ("_");
467 load_im_info_keys = mplist ();
468 mplist_add (load_im_info_keys, Mstate, Mnil);
469 mplist_push (load_im_info_keys, Mmap, Mnil);
471 im_info_list = mplist ();
472 im_config_list = im_custom_list = NULL;
473 im_custom_mdb = NULL;
474 update_custom_info ();
476 update_global_info ();
478 fully_initialized = 1;
481 #define MINPUT__INIT() \
483 if (! fully_initialized) \
484 fully_initialize (); \
489 marker_code (MSymbol sym, int surrounding)
495 name = MSYMBOL_NAME (sym);
496 return (name[0] != '@' ? -1
497 : (((name[1] >= '0' && name[1] <= '9')
498 || name[1] == '<' || name[1] == '>' || name[1] == '='
499 || name[1] == '[' || name[1] == ']'
501 && name[2] == '\0') ? name[1]
502 : (name[1] != '+' && name[1] != '-') ? -1
503 : (name[2] == '\0' || surrounding) ? name[1]
508 /* Return a plist containing an integer value of VAR. */
511 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
513 MPlist *plist = mplist__assq (ic_info->vars, var);
517 plist = MPLIST_PLIST (plist);
518 return MPLIST_NEXT (plist);
522 mplist_push (ic_info->vars, Mplist, plist);
523 M17N_OBJECT_UNREF (plist);
524 plist = mplist_add (plist, Msymbol, var);
525 plist = mplist_add (plist, Minteger, (void *) 0);
530 get_surrounding_text (MInputContext *ic, int len)
534 mplist_push (ic->plist, Minteger, (void *) len);
535 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
536 && MPLIST_MTEXT_P (ic->plist))
537 mt = MPLIST_MTEXT (ic->plist);
538 mplist_pop (ic->plist);
543 delete_surrounding_text (MInputContext *ic, int pos)
545 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
547 mplist_push (ic->plist, Minteger, (void *) pos);
548 minput_callback (ic, Minput_delete_surrounding_text);
549 mplist_pop (ic->plist);
552 M17N_OBJECT_UNREF (ic_info->preceding_text);
553 ic_info->preceding_text = NULL;
557 M17N_OBJECT_UNREF (ic_info->following_text);
558 ic_info->following_text = NULL;
563 get_preceding_char (MInputContext *ic, int pos)
565 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
569 if (pos && ic_info->preceding_text)
571 len = mtext_nchars (ic_info->preceding_text);
573 return mtext_ref_char (ic_info->preceding_text, len - pos);
575 mt = get_surrounding_text (ic, - pos);
578 len = mtext_nchars (mt);
579 if (ic_info->preceding_text)
581 if (mtext_nchars (ic_info->preceding_text) < len)
583 M17N_OBJECT_UNREF (ic_info->preceding_text);
584 ic_info->preceding_text = mt;
587 M17N_OBJECT_UNREF (mt);
590 ic_info->preceding_text = mt;
593 return mtext_ref_char (ic_info->preceding_text, len - pos);
597 get_following_char (MInputContext *ic, int pos)
599 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
603 if (ic_info->following_text)
605 len = mtext_nchars (ic_info->following_text);
607 return mtext_ref_char (ic_info->following_text, pos);
609 mt = get_surrounding_text (ic, pos + 1);
612 len = mtext_nchars (mt);
613 if (ic_info->following_text)
615 if (mtext_nchars (ic_info->following_text) < len)
617 M17N_OBJECT_UNREF (ic_info->following_text);
618 ic_info->following_text = mt;
621 M17N_OBJECT_UNREF (mt);
624 ic_info->following_text = mt;
627 return mtext_ref_char (ic_info->following_text, pos);
631 surrounding_pos (MSymbol sym)
637 name = MSYMBOL_NAME (sym);
639 && (name[1] == '-' || name[1] == '+')
640 && name[2] >= '1' && name[2] <= '9')
641 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
646 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
648 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
650 MText *preedit = ic->preedit;
651 int len = mtext_nchars (preedit);
653 if (MPLIST_INTEGER_P (arg))
654 return MPLIST_INTEGER (arg);
656 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
659 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
661 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
664 return ic_info->key_head;
665 if ((code == '-' || code == '+'))
667 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
671 pos = atoi (name + 1);
673 return get_preceding_char (ic, 0);
675 pos = ic->cursor_pos + pos;
677 pos = ic->cursor_pos + pos - 1;
680 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
681 return mtext_ref_char (ic->produced,
682 mtext_len (ic->produced) + pos);
683 return get_preceding_char (ic, - pos);
686 return get_following_char (ic, pos - len);
689 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
691 else if (code >= '0' && code <= '9')
693 else if (code == '=')
694 pos = ic->cursor_pos;
695 else if (code == '[')
696 pos = ic->cursor_pos - 1;
697 else if (code == ']')
698 pos = ic->cursor_pos + 1;
699 else if (code == '<')
701 else if (code == '>')
703 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
707 parse_expression (MPlist *plist)
711 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
713 if (! MPLIST_PLIST_P (plist))
715 plist = MPLIST_PLIST (plist);
716 op = MPLIST_SYMBOL (plist);
717 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
718 && op != Mand && op != Mor && op != Mnot
719 && op != Mless && op != Mgreater && op != Mequal
720 && op != Mless_equal && op != Mgreater_equal)
721 MERROR (MERROR_IM, -1);
722 MPLIST_DO (plist, MPLIST_NEXT (plist))
723 if (parse_expression (plist) < 0)
729 resolve_expression (MInputContext *ic, MPlist *plist)
734 if (MPLIST_INTEGER_P (plist))
735 return MPLIST_INTEGER (plist);
736 if (MPLIST_SYMBOL_P (plist))
737 return integer_value (ic, plist, 1);
738 if (! MPLIST_PLIST_P (plist))
740 plist = MPLIST_PLIST (plist);
741 if (! MPLIST_SYMBOL_P (plist))
743 op = MPLIST_SYMBOL (plist);
744 plist = MPLIST_NEXT (plist);
745 val = resolve_expression (ic, plist);
747 MPLIST_DO (plist, MPLIST_NEXT (plist))
748 val += resolve_expression (ic, plist);
749 else if (op == Mminus)
750 MPLIST_DO (plist, MPLIST_NEXT (plist))
751 val -= resolve_expression (ic, plist);
752 else if (op == Mstar)
753 MPLIST_DO (plist, MPLIST_NEXT (plist))
754 val *= resolve_expression (ic, plist);
755 else if (op == Mslash)
756 MPLIST_DO (plist, MPLIST_NEXT (plist))
757 val /= resolve_expression (ic, plist);
759 MPLIST_DO (plist, MPLIST_NEXT (plist))
760 val &= resolve_expression (ic, plist);
762 MPLIST_DO (plist, MPLIST_NEXT (plist))
763 val |= resolve_expression (ic, plist);
766 else if (op == Mless)
767 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
768 else if (op == Mequal)
769 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
770 else if (op == Mgreater)
771 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
772 else if (op == Mless_equal)
773 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
774 else if (op == Mgreater_equal)
775 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
779 /* Parse PLIST as an action list. PLIST should have this form:
780 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
781 Return 0 if successfully parsed, otherwise return -1. */
784 parse_action_list (MPlist *plist, MPlist *macros)
786 MPLIST_DO (plist, plist)
788 if (MPLIST_MTEXT_P (plist))
790 /* This is a short form of (insert MTEXT). */
791 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
792 MERROR (MERROR_IM, -1); */
794 else if (MPLIST_PLIST_P (plist)
795 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
796 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
800 /* This is a short form of (insert (GROUPS *)). */
801 MPLIST_DO (pl, MPLIST_PLIST (plist))
803 if (MPLIST_PLIST_P (pl))
807 MPLIST_DO (elt, MPLIST_PLIST (pl))
808 if (! MPLIST_MTEXT_P (elt)
809 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
810 MERROR (MERROR_IM, -1);
814 if (! MPLIST_MTEXT_P (pl)
815 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
816 MERROR (MERROR_IM, -1);
820 else if (MPLIST_INTEGER_P (plist))
822 int c = MPLIST_INTEGER (plist);
824 if (c < 0 || c > MCHAR_MAX)
825 MERROR (MERROR_IM, -1);
827 else if (MPLIST_PLIST_P (plist)
828 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
830 MPlist *pl = MPLIST_PLIST (plist);
831 MSymbol action_name = MPLIST_SYMBOL (pl);
833 pl = MPLIST_NEXT (pl);
835 if (action_name == M_candidates)
837 /* This is an already regularised action. */
840 if (action_name == Minsert)
842 if (MPLIST_MTEXT_P (pl))
844 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
845 MERROR (MERROR_IM, -1);
847 else if (MPLIST_INTEGER_P (pl))
849 int c = MPLIST_INTEGER (pl);
851 if (c < 0 || c > MCHAR_MAX)
852 MERROR (MERROR_IM, -1);
854 else if (MPLIST_PLIST_P (pl))
856 MPLIST_DO (pl, MPLIST_PLIST (pl))
858 if (MPLIST_PLIST_P (pl))
862 MPLIST_DO (elt, MPLIST_PLIST (pl))
863 if (! MPLIST_MTEXT_P (elt)
864 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
865 MERROR (MERROR_IM, -1);
869 if (! MPLIST_MTEXT_P (pl)
870 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
871 MERROR (MERROR_IM, -1);
875 else if (! MPLIST_SYMBOL_P (pl))
876 MERROR (MERROR_IM, -1);
878 else if (action_name == Mselect
879 || action_name == Mdelete
880 || action_name == Mmove)
882 if (parse_expression (pl) < 0)
885 else if (action_name == Mmark
886 || action_name == Mcall
887 || action_name == Mshift)
889 if (! MPLIST_SYMBOL_P (pl))
890 MERROR (MERROR_IM, -1);
892 else if (action_name == Mundo)
894 if (! MPLIST_TAIL_P (pl))
896 if (! MPLIST_SYMBOL_P (pl)
897 && ! MPLIST_INTEGER_P (pl))
898 MERROR (MERROR_IM, -1);
901 else if (action_name == Mpushback)
903 if (MPLIST_MTEXT_P (pl))
905 MText *mt = MPLIST_MTEXT (pl);
907 if (mtext_nchars (mt) != mtext_nbytes (mt))
908 MERROR (MERROR_IM, -1);
910 else if (MPLIST_PLIST_P (pl))
914 MPLIST_DO (p, MPLIST_PLIST (pl))
915 if (! MPLIST_SYMBOL_P (p))
916 MERROR (MERROR_IM, -1);
918 else if (! MPLIST_INTEGER_P (pl))
919 MERROR (MERROR_IM, -1);
921 else if (action_name == Mset || action_name == Madd
922 || action_name == Msub || action_name == Mmul
923 || action_name == Mdiv)
925 if (! MPLIST_SYMBOL_P (pl))
926 MERROR (MERROR_IM, -1);
927 if (parse_expression (MPLIST_NEXT (pl)) < 0)
930 else if (action_name == Mequal || action_name == Mless
931 || action_name == Mgreater || action_name == Mless_equal
932 || action_name == Mgreater_equal)
934 if (parse_expression (pl) < 0
935 || parse_expression (MPLIST_NEXT (pl)) < 0)
937 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
938 if (! MPLIST_PLIST_P (pl))
939 MERROR (MERROR_IM, -1);
940 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
941 MERROR (MERROR_IM, -1);
942 pl = MPLIST_NEXT (pl);
943 if (MPLIST_PLIST_P (pl)
944 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
945 MERROR (MERROR_IM, -1);
947 else if (action_name == Mshow || action_name == Mhide
948 || action_name == Mcommit || action_name == Munhandle
949 || action_name == Mpop)
951 else if (action_name == Mcond)
954 if (! MPLIST_PLIST_P (pl))
955 MERROR (MERROR_IM, -1);
957 else if (! macros || ! mplist_get (macros, action_name))
958 MERROR (MERROR_IM, -1);
960 else if (! MPLIST_SYMBOL_P (plist))
961 MERROR (MERROR_IM, -1);
968 resolve_command (MPlist *cmds, MSymbol command)
972 if (! cmds || ! (plist = mplist__assq (cmds, command)))
974 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
975 plist = MPLIST_NEXT (plist);
976 plist = MPLIST_NEXT (plist);
977 plist = MPLIST_NEXT (plist);
981 /* Load a translation into MAP from PLIST.
983 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
986 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
987 MPlist *branch_actions, MPlist *macros)
992 if (MPLIST_MTEXT_P (keylist))
994 MText *mt = MPLIST_MTEXT (keylist);
996 len = mtext_nchars (mt);
997 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
999 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1000 for (i = 0; i < len; i++)
1001 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1007 if (MFAILP (MPLIST_PLIST_P (keylist)))
1009 elt = MPLIST_PLIST (keylist);
1010 len = MPLIST_LENGTH (elt);
1011 if (MFAILP (len > 0))
1013 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1014 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1016 if (MPLIST_INTEGER_P (elt))
1018 int c = MPLIST_INTEGER (elt);
1020 if (MFAILP (c >= 0 && c < 0x100))
1022 keyseq[i] = one_char_symbol[c];
1026 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1028 keyseq[i] = MPLIST_SYMBOL (elt);
1033 for (i = 0; i < len; i++)
1035 MIMMap *deeper = NULL;
1038 deeper = mplist_get (map->submaps, keyseq[i]);
1040 map->submaps = mplist ();
1043 /* Fixme: It is better to make all deeper maps at once. */
1044 MSTRUCT_CALLOC (deeper, MERROR_IM);
1045 mplist_put (map->submaps, keyseq[i], deeper);
1050 /* We reach a terminal map. */
1051 if (map->map_actions
1052 || map->branch_actions)
1053 /* This map is already defined. We avoid overriding it. */
1056 if (! MPLIST_TAIL_P (map_actions))
1058 if (parse_action_list (map_actions, macros) < 0)
1059 MERROR (MERROR_IM, -1);
1060 map->map_actions = map_actions;
1064 map->branch_actions = branch_actions;
1065 M17N_OBJECT_REF (branch_actions);
1071 /* Load a branch from PLIST into MAP. PLIST has this form:
1072 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1075 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1078 MPlist *branch_actions;
1080 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1082 map_name = MPLIST_SYMBOL (plist);
1083 plist = MPLIST_NEXT (plist);
1084 if (MPLIST_TAIL_P (plist))
1085 branch_actions = NULL;
1086 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1089 branch_actions = plist;
1090 if (map_name == Mnil)
1092 map->branch_actions = branch_actions;
1094 M17N_OBJECT_REF (branch_actions);
1096 else if (map_name == Mt)
1098 map->map_actions = branch_actions;
1100 M17N_OBJECT_REF (branch_actions);
1102 else if (im_info->maps)
1104 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1105 if (! plist && im_info->configured_vars)
1107 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1109 if (p && MPLIST_PLIST_P (p))
1111 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1112 if (MPLIST_SYMBOL_P (p))
1113 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1118 MPLIST_DO (plist, plist)
1120 MPlist *keylist, *map_actions;
1122 if (! MPLIST_PLIST_P (plist))
1123 MERROR (MERROR_IM, -1);
1124 keylist = MPLIST_PLIST (plist);
1125 map_actions = MPLIST_NEXT (keylist);
1126 if (MPLIST_SYMBOL_P (keylist))
1128 MSymbol command = MPLIST_SYMBOL (keylist);
1131 if (MFAILP (command != Mat_reload))
1133 pl = resolve_command (im_info->configured_cmds, command);
1137 load_translation (map, pl, map_actions, branch_actions,
1141 load_translation (map, keylist, map_actions, branch_actions,
1150 /* Load a macro from PLIST into IM_INFO->macros.
1151 PLIST has this from:
1152 PLIST ::= ( MACRO-NAME ACTION * )
1153 IM_INFO->macros is a plist of macro names vs action list. */
1156 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1161 if (! MPLIST_SYMBOL_P (plist))
1162 MERROR (MERROR_IM, -1);
1163 name = MPLIST_SYMBOL (plist);
1164 plist = MPLIST_NEXT (plist);
1165 if (MPLIST_TAIL_P (plist)
1166 || parse_action_list (plist, im_info->macros) < 0)
1167 MERROR (MERROR_IM, -1);
1168 pl = mplist_get (im_info->macros, name);
1169 M17N_OBJECT_UNREF (pl);
1170 mplist_put (im_info->macros, name, plist);
1171 M17N_OBJECT_REF (plist);
1175 /* Load an external module from PLIST into IM_INFO->externals.
1176 PLIST has this form:
1177 PLIST ::= ( MODULE-NAME FUNCTION * )
1178 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1181 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1186 MIMExternalModule *external;
1190 if (MPLIST_MTEXT_P (plist))
1191 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1192 else if (MPLIST_SYMBOL_P (plist))
1193 module = MPLIST_SYMBOL (plist);
1194 module_file = alloca (strlen (MSYMBOL_NAME (module))
1195 + strlen (DLOPEN_SHLIB_EXT) + 1);
1196 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1198 handle = dlopen (module_file, RTLD_NOW);
1199 if (MFAILP (handle))
1201 fprintf (stderr, "%s\n", dlerror ());
1204 func_list = mplist ();
1205 MPLIST_DO (plist, MPLIST_NEXT (plist))
1207 if (! MPLIST_SYMBOL_P (plist))
1208 MERROR_GOTO (MERROR_IM, err_label);
1209 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1212 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1215 MSTRUCT_MALLOC (external, MERROR_IM);
1216 external->handle = handle;
1217 external->func_list = func_list;
1218 mplist_add (im_info->externals, module, external);
1223 M17N_OBJECT_UNREF (func_list);
1228 free_map (MIMMap *map, int top)
1233 M17N_OBJECT_UNREF (map->map_actions);
1236 MPLIST_DO (plist, map->submaps)
1237 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1238 M17N_OBJECT_UNREF (map->submaps);
1240 M17N_OBJECT_UNREF (map->branch_actions);
1245 free_state (void *object)
1247 MIMState *state = object;
1249 M17N_OBJECT_UNREF (state->title);
1251 free_map (state->map, 1);
1255 /** Load a state from PLIST into a newly allocated state object.
1256 PLIST has this form:
1257 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1258 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1259 Return the state object. */
1262 load_state (MInputMethodInfo *im_info, MPlist *plist)
1266 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1268 M17N_OBJECT (state, free_state, MERROR_IM);
1269 state->name = MPLIST_SYMBOL (plist);
1270 plist = MPLIST_NEXT (plist);
1271 if (MPLIST_MTEXT_P (plist))
1273 state->title = MPLIST_MTEXT (plist);
1274 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1275 Mlanguage, im_info->language);
1276 M17N_OBJECT_REF (state->title);
1277 plist = MPLIST_NEXT (plist);
1279 MSTRUCT_CALLOC (state->map, MERROR_IM);
1280 MPLIST_DO (plist, plist)
1282 if (MFAILP (MPLIST_PLIST_P (plist)))
1284 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1289 /* Return a newly created IM_INFO for an input method specified by
1290 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1292 static MInputMethodInfo *
1293 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1296 MInputMethodInfo *im_info;
1299 if (name == Mnil && extra == Mnil)
1300 language = Mt, extra = Mglobal;
1301 MSTRUCT_CALLOC (im_info, MERROR_IM);
1303 im_info->language = language;
1304 im_info->name = name;
1305 im_info->extra = extra;
1308 mplist_add (plist, Mplist, elt);
1309 M17N_OBJECT_UNREF (elt);
1310 elt = mplist_add (elt, Msymbol, language);
1311 elt = mplist_add (elt, Msymbol, name);
1312 elt = mplist_add (elt, Msymbol, extra);
1313 mplist_add (elt, Mt, im_info);
1319 fini_im_info (MInputMethodInfo *im_info)
1323 M17N_OBJECT_UNREF (im_info->cmds);
1324 M17N_OBJECT_UNREF (im_info->configured_cmds);
1325 M17N_OBJECT_UNREF (im_info->bc_cmds);
1326 M17N_OBJECT_UNREF (im_info->vars);
1327 M17N_OBJECT_UNREF (im_info->configured_vars);
1328 M17N_OBJECT_UNREF (im_info->bc_vars);
1329 M17N_OBJECT_UNREF (im_info->description);
1330 M17N_OBJECT_UNREF (im_info->title);
1331 if (im_info->states)
1333 MPLIST_DO (plist, im_info->states)
1335 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1337 M17N_OBJECT_UNREF (state);
1339 M17N_OBJECT_UNREF (im_info->states);
1342 if (im_info->macros)
1344 MPLIST_DO (plist, im_info->macros)
1345 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1346 M17N_OBJECT_UNREF (im_info->macros);
1349 if (im_info->externals)
1351 MPLIST_DO (plist, im_info->externals)
1353 MIMExternalModule *external = MPLIST_VAL (plist);
1355 dlclose (external->handle);
1356 M17N_OBJECT_UNREF (external->func_list);
1358 MPLIST_KEY (plist) = Mt;
1360 M17N_OBJECT_UNREF (im_info->externals);
1364 MPLIST_DO (plist, im_info->maps)
1366 MPlist *p = MPLIST_PLIST (plist);
1368 M17N_OBJECT_UNREF (p);
1370 M17N_OBJECT_UNREF (im_info->maps);
1377 free_im_info (MInputMethodInfo *im_info)
1379 fini_im_info (im_info);
1384 free_im_list (MPlist *plist)
1388 MPLIST_DO (pl, plist)
1390 MInputMethodInfo *im_info;
1392 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1393 im_info = MPLIST_VAL (elt);
1394 free_im_info (im_info);
1396 M17N_OBJECT_UNREF (plist);
1399 static MInputMethodInfo *
1400 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1402 if (name == Mnil && extra == Mnil)
1403 language = Mt, extra = Mglobal;
1404 while ((plist = mplist__assq (plist, language)))
1406 MPlist *elt = MPLIST_PLIST (plist);
1408 plist = MPLIST_NEXT (plist);
1409 elt = MPLIST_NEXT (elt);
1410 if (MPLIST_SYMBOL (elt) != name)
1412 elt = MPLIST_NEXT (elt);
1413 if (MPLIST_SYMBOL (elt) != extra)
1415 elt = MPLIST_NEXT (elt);
1416 return MPLIST_VAL (elt);
1421 static void load_im_info (MPlist *, MInputMethodInfo *);
1423 #define get_custom_info(im_info) \
1425 ? lookup_im_info (im_custom_list, (im_info)->language, \
1426 (im_info)->name, (im_info)->extra) \
1429 #define get_config_info(im_info) \
1431 ? lookup_im_info (im_config_list, (im_info)->language, \
1432 (im_info)->name, (im_info)->extra) \
1436 update_custom_info (void)
1442 if (mdatabase__check (im_custom_mdb) > 0)
1447 MDatabaseInfo *custom_dir_info;
1448 char custom_path[PATH_MAX + 1];
1450 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1451 if (! custom_dir_info->filename
1452 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1454 strcpy (custom_path, custom_dir_info->filename);
1455 strcat (custom_path, CUSTOM_FILE);
1456 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1462 free_im_list (im_custom_list);
1463 im_custom_list = NULL;
1465 plist = mdatabase_load (im_custom_mdb);
1468 im_custom_list = mplist ();
1470 MPLIST_DO (pl, plist)
1472 MSymbol language, name, extra;
1473 MInputMethodInfo *im_info;
1474 MPlist *im_data, *p;
1476 if (! MPLIST_PLIST_P (pl))
1478 p = MPLIST_PLIST (pl);
1479 im_data = MPLIST_NEXT (p);
1480 if (! MPLIST_PLIST_P (p))
1482 p = MPLIST_PLIST (p);
1483 if (! MPLIST_SYMBOL_P (p)
1484 || MPLIST_SYMBOL (p) != Minput_method)
1486 p = MPLIST_NEXT (p);
1487 if (! MPLIST_SYMBOL_P (p))
1489 language = MPLIST_SYMBOL (p);
1490 p = MPLIST_NEXT (p);
1491 if (! MPLIST_SYMBOL_P (p))
1493 name = MPLIST_SYMBOL (p);
1494 p = MPLIST_NEXT (p);
1495 if (MPLIST_TAIL_P (p))
1497 else if (MPLIST_SYMBOL_P (p))
1498 extra = MPLIST_SYMBOL (p);
1499 if (language == Mnil || (name == Mnil && extra == Mnil))
1501 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1502 load_im_info (im_data, im_info);
1504 M17N_OBJECT_UNREF (plist);
1509 update_global_info (void)
1515 int ret = mdatabase__check (global_info->mdb);
1519 fini_im_info (global_info);
1523 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1527 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1529 if (! global_info->mdb
1530 || ! (plist = mdatabase_load (global_info->mdb)))
1533 load_im_info (plist, global_info);
1534 M17N_OBJECT_UNREF (plist);
1539 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1540 and EXTRA. KEY, if not Mnil, tells which kind of information about
1541 the input method is necessary, and the returned IM_INFO may contain
1542 only that information. */
1544 static MInputMethodInfo *
1545 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1548 MInputMethodInfo *im_info;
1551 if (name == Mnil && extra == Mnil)
1552 language = Mt, extra = Mglobal;
1553 im_info = lookup_im_info (im_info_list, language, name, extra);
1556 if (key == Mnil ? im_info->states != NULL
1557 : key == Mcommand ? im_info->cmds != NULL
1558 : key == Mvariable ? im_info->vars != NULL
1559 : key == Mtitle ? im_info->title != NULL
1560 : key == Mdescription ? im_info->description != NULL
1562 /* IM_INFO already contains required information. */
1564 /* We have not yet loaded required information. */
1568 mdb = mdatabase_find (Minput_method, language, name, extra);
1571 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1576 plist = mdatabase_load (im_info->mdb);
1580 mplist_push (load_im_info_keys, key, Mt);
1581 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1582 mplist_pop (load_im_info_keys);
1586 MERROR (MERROR_IM, im_info);
1587 update_global_info ();
1588 load_im_info (plist, im_info);
1589 M17N_OBJECT_UNREF (plist);
1592 if (! im_info->cmds)
1593 im_info->cmds = mplist ();
1594 if (! im_info->vars)
1595 im_info->vars = mplist ();
1596 if (! im_info->states)
1597 im_info->states = mplist ();
1599 if (! im_info->title
1600 && (key == Mnil || key == Mtitle))
1601 im_info->title = (name == Mnil ? mtext ()
1602 : mtext_from_data (MSYMBOL_NAME (name),
1603 MSYMBOL_NAMELEN (name),
1604 MTEXT_FORMAT_US_ASCII));
1608 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1609 If updated, but got unloadable, return -1. Otherwise, update
1610 contents of IM_INFO from the new database, and return 1. */
1613 reload_im_info (MInputMethodInfo *im_info)
1618 update_custom_info ();
1619 update_global_info ();
1620 check = mdatabase__check (im_info->mdb);
1623 plist = mdatabase_load (im_info->mdb);
1626 fini_im_info (im_info);
1627 load_im_info (plist, im_info);
1628 M17N_OBJECT_UNREF (plist);
1629 if (! im_info->cmds)
1630 im_info->cmds = mplist ();
1631 if (! im_info->vars)
1632 im_info->vars = mplist ();
1633 if (! im_info->title)
1635 MSymbol name = im_info->name;
1637 im_info->title = (name == Mnil ? mtext ()
1638 : mtext_from_data (MSYMBOL_NAME (name),
1639 MSYMBOL_NAMELEN (name),
1640 MTEXT_FORMAT_US_ASCII));
1645 static MInputMethodInfo *
1646 get_im_info_by_tags (MPlist *plist)
1651 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1652 i++, plist = MPLIST_NEXT (plist))
1653 tag[i] = MPLIST_SYMBOL (plist);
1658 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1663 check_description (MPlist *plist)
1667 if (MPLIST_MTEXT_P (plist))
1669 if (MPLIST_PLIST_P (plist))
1671 MPlist *pl = MPLIST_PLIST (plist);
1673 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1675 pl =MPLIST_NEXT (pl);
1676 if (MFAILP (MPLIST_MTEXT_P (pl)))
1678 mt = MPLIST_MTEXT (pl);
1679 M17N_OBJECT_REF (mt);
1682 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1684 if (translated == (char *) MTEXT_DATA (mt))
1685 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1686 if (translated != (char *) MTEXT_DATA (mt))
1688 M17N_OBJECT_UNREF (mt);
1689 mt = mtext__from_data (translated, strlen (translated),
1690 MTEXT_FORMAT_UTF_8, 1);
1694 mplist_set (plist, Mtext, mt);
1695 M17N_OBJECT_UNREF (mt);
1698 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1704 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1708 check_command_keyseq (MPlist *keyseq)
1710 if (MPLIST_PLIST_P (keyseq))
1712 MPlist *p = MPLIST_PLIST (keyseq);
1715 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1719 if (MPLIST_MTEXT_P (keyseq))
1721 MText *mt = MPLIST_MTEXT (keyseq);
1724 for (i = 0; i < mtext_nchars (mt); i++)
1725 if (mtext_ref_char (mt, i) >= 256)
1732 /* Load command defitions from PLIST into IM_INFO->cmds.
1734 PLIST is well-formed and has this form;
1735 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1736 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1737 M-text or a plist of symbols.
1739 The returned list has the same form, but for each element...
1741 (1) If DESCRIPTION and the rest are omitted, the element is not
1742 stored in the returned list.
1744 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1745 description in global_info->cmds (if any). */
1748 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1752 im_info->cmds = tail = mplist ();
1754 MPLIST_DO (plist, MPLIST_NEXT (plist))
1756 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1759 if (MFAILP (MPLIST_PLIST_P (plist)))
1761 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1762 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1764 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1765 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1767 if (MFAILP (im_info != global_info))
1768 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1772 if (! check_description (p))
1773 mplist_set (p, Msymbol, Mnil);
1774 p = MPLIST_NEXT (p);
1775 while (! MPLIST_TAIL_P (p))
1777 if (MFAILP (check_command_keyseq (p)))
1778 mplist__pop_unref (p);
1780 p = MPLIST_NEXT (p);
1783 tail = mplist_add (tail, Mplist, pl);
1788 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1789 MPlist *config_cmds)
1791 MPlist *global = NULL, *custom = NULL, *config = NULL;
1792 MSymbol name = MPLIST_SYMBOL (plist);
1794 MPlist *description, *keyseq;
1796 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1797 global = MPLIST_NEXT (MPLIST_PLIST (global));
1799 plist = MPLIST_NEXT (plist);
1800 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1802 description = plist;
1803 plist = MPLIST_NEXT (plist);
1807 description = global;
1808 if (! MPLIST_TAIL_P (plist))
1809 plist = MPLIST_NEXT (plist);
1811 if (MPLIST_TAIL_P (plist) && global)
1813 keyseq = MPLIST_NEXT (global);
1814 status = Minherited;
1822 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1824 status = Mconfigured;
1825 config = MPLIST_NEXT (MPLIST_PLIST (config));
1826 if (! MPLIST_TAIL_P (config))
1829 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1831 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1833 if (MPLIST_TAIL_P (this_keyseq))
1834 mplist__pop_unref (custom);
1837 status = Mcustomized;
1838 keyseq = this_keyseq;
1843 mplist_add (plist, Msymbol, name);
1845 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1847 mplist_add (plist, Msymbol, Mnil);
1848 mplist_add (plist, Msymbol, status);
1849 mplist__conc (plist, keyseq);
1854 config_all_commands (MInputMethodInfo *im_info)
1856 MPlist *global_cmds, *custom_cmds, *config_cmds;
1857 MInputMethodInfo *temp;
1858 MPlist *tail, *plist;
1860 M17N_OBJECT_UNREF (im_info->configured_cmds);
1862 if (MPLIST_TAIL_P (im_info->cmds)
1866 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1867 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1868 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1870 im_info->configured_cmds = tail = mplist ();
1871 MPLIST_DO (plist, im_info->cmds)
1873 MPlist *pl = config_command (MPLIST_PLIST (plist),
1874 global_cmds, custom_cmds, config_cmds);
1877 tail = mplist_add (tail, Mplist, pl);
1878 M17N_OBJECT_UNREF (pl);
1883 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1884 valid, return 0 if not. */
1887 check_variable_value (MPlist *val, MPlist *global)
1889 MSymbol type = MPLIST_KEY (val);
1890 MPlist *valids = MPLIST_NEXT (val);
1892 if (type != Minteger && type != Mtext && type != Msymbol)
1896 if (MPLIST_KEY (global) != Mt
1897 && MPLIST_KEY (global) != MPLIST_KEY (val))
1899 if (MPLIST_TAIL_P (valids))
1900 valids = MPLIST_NEXT (global);
1902 if (MPLIST_TAIL_P (valids))
1905 if (type == Minteger)
1907 int n = MPLIST_INTEGER (val);
1909 MPLIST_DO (valids, valids)
1911 if (MPLIST_INTEGER_P (valids))
1913 if (n == MPLIST_INTEGER (valids))
1916 else if (MPLIST_PLIST_P (valids))
1918 MPlist *p = MPLIST_PLIST (valids);
1919 int min_bound, max_bound;
1921 if (! MPLIST_INTEGER_P (p))
1922 MERROR (MERROR_IM, 0);
1923 min_bound = MPLIST_INTEGER (p);
1924 p = MPLIST_NEXT (p);
1925 if (! MPLIST_INTEGER_P (p))
1926 MERROR (MERROR_IM, 0);
1927 max_bound = MPLIST_INTEGER (p);
1928 if (n >= min_bound && n <= max_bound)
1933 else if (type == Msymbol)
1935 MSymbol sym = MPLIST_SYMBOL (val);
1937 MPLIST_DO (valids, valids)
1939 if (! MPLIST_SYMBOL_P (valids))
1940 MERROR (MERROR_IM, 0);
1941 if (sym == MPLIST_SYMBOL (valids))
1947 MText *mt = MPLIST_MTEXT (val);
1949 MPLIST_DO (valids, valids)
1951 if (! MPLIST_MTEXT_P (valids))
1952 MERROR (MERROR_IM, 0);
1953 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1958 return (! MPLIST_TAIL_P (valids));
1961 /* Load variable defitions from PLIST into IM_INFO->vars.
1963 PLIST is well-formed and has this form;
1964 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1966 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1968 The returned list has the same form, but for each element...
1970 (1) If DESCRIPTION and the rest are omitted, the element is not
1971 stored in the returned list.
1973 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1974 description in global_info->vars (if any). */
1977 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1979 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1980 ? global_info->vars : NULL);
1983 im_info->vars = tail = mplist ();
1984 MPLIST_DO (plist, MPLIST_NEXT (plist))
1988 if (MFAILP (MPLIST_PLIST_P (plist)))
1990 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1991 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1993 if (im_info == global_info)
1995 /* Loading a global variable. */
1996 p = MPLIST_NEXT (pl);
1997 if (MPLIST_TAIL_P (p))
1998 mplist_add (p, Msymbol, Mnil);
2001 if (! check_description (p))
2002 mplist_set (p, Msymbol, Mnil);
2003 p = MPLIST_NEXT (p);
2004 if (MFAILP (! MPLIST_TAIL_P (p)
2005 && check_variable_value (p, NULL)))
2006 mplist_set (p, Mt, NULL);
2009 else if (im_info->mdb)
2011 /* Loading a local variable. */
2012 MSymbol name = MPLIST_SYMBOL (pl);
2013 MPlist *global = NULL;
2016 && (p = mplist__assq (global_vars, name)))
2018 /* P ::= ((NAME DESC ...) ...) */
2019 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2020 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2021 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2024 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2025 if (! MPLIST_TAIL_P (p))
2027 if (! check_description (p))
2028 mplist_set (p, Msymbol, Mnil);
2029 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2030 if (MFAILP (! MPLIST_TAIL_P (p)))
2031 mplist_set (p, Mt, NULL);
2034 MPlist *valid_values = MPLIST_NEXT (p);
2036 if (! MPLIST_TAIL_P (valid_values)
2037 ? MFAILP (check_variable_value (p, NULL))
2038 : global && MFAILP (check_variable_value (p, global)))
2039 mplist_set (p, Mt, NULL);
2045 /* Loading a variable customization. */
2046 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2047 if (MFAILP (! MPLIST_TAIL_P (p)))
2049 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2050 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2051 || MPLIST_MTEXT_P (p)))
2054 tail = mplist_add (tail, Mplist, pl);
2059 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2060 MPlist *config_vars)
2062 MPlist *global = NULL, *custom = NULL, *config = NULL;
2063 MSymbol name = MPLIST_SYMBOL (plist);
2065 MPlist *description = NULL, *value, *valids;
2069 global = mplist__assq (global_vars, name);
2071 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2074 plist = MPLIST_NEXT (plist);
2075 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2076 description = plist;
2078 description = global;
2080 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2082 if (MPLIST_TAIL_P (plist))
2084 /* Inherit from global (if any). */
2088 if (MPLIST_KEY (value) == Mt)
2090 valids = MPLIST_NEXT (global);
2091 status = Minherited;
2103 value = plist = MPLIST_NEXT (plist);
2104 valids = MPLIST_NEXT (value);
2105 if (MPLIST_KEY (value) == Mt)
2107 if (! MPLIST_TAIL_P (valids))
2110 valids = MPLIST_NEXT (global);
2114 if (config_vars && (config = mplist__assq (config_vars, name)))
2116 status = Mconfigured;
2117 config = MPLIST_NEXT (MPLIST_PLIST (config));
2118 if (! MPLIST_TAIL_P (config))
2121 if (MFAILP (check_variable_value (value, global ? global : plist)))
2125 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2127 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2129 if (MPLIST_TAIL_P (this_value))
2130 mplist__pop_unref (custom);
2134 if (MFAILP (check_variable_value (value, global ? global : plist)))
2136 status = Mcustomized;
2141 mplist_add (plist, Msymbol, name);
2143 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2145 mplist_add (plist, Msymbol, Mnil);
2146 mplist_add (plist, Msymbol, status);
2148 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2150 mplist_add (plist, Mt, NULL);
2151 if (valids && ! MPLIST_TAIL_P (valids))
2152 mplist__conc (plist, valids);
2156 /* Return a configured variable definition list based on
2157 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2158 get it from global_info->vars. */
2161 config_all_variables (MInputMethodInfo *im_info)
2163 MPlist *global_vars, *custom_vars, *config_vars;
2164 MInputMethodInfo *temp;
2165 MPlist *tail, *plist;
2167 M17N_OBJECT_UNREF (im_info->configured_vars);
2169 if (MPLIST_TAIL_P (im_info->vars)
2173 global_vars = im_info != global_info ? global_info->vars : NULL;
2174 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2175 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2177 im_info->configured_vars = tail = mplist ();
2178 MPLIST_DO (plist, im_info->vars)
2180 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2181 global_vars, custom_vars, config_vars);
2184 tail = mplist_add (tail, Mplist, pl);
2185 M17N_OBJECT_UNREF (pl);
2190 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2191 CONFIG contains configuration information of the input method. */
2194 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2198 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2200 load_commands (im_info, MPLIST_PLIST (pl));
2201 config_all_commands (im_info);
2202 pl = mplist_pop (pl);
2203 M17N_OBJECT_UNREF (pl);
2206 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2208 load_variables (im_info, MPLIST_PLIST (pl));
2209 config_all_variables (im_info);
2210 pl = mplist_pop (pl);
2211 M17N_OBJECT_UNREF (pl);
2214 MPLIST_DO (plist, plist)
2215 if (MPLIST_PLIST_P (plist))
2217 MPlist *elt = MPLIST_PLIST (plist);
2220 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2222 key = MPLIST_SYMBOL (elt);
2227 elt = MPLIST_NEXT (elt);
2228 if (MFAILP (MPLIST_MTEXT_P (elt)))
2230 im_info->title = MPLIST_MTEXT (elt);
2231 M17N_OBJECT_REF (im_info->title);
2233 else if (key == Mmap)
2235 pl = mplist__from_alist (MPLIST_NEXT (elt));
2238 if (! im_info->maps)
2242 mplist__conc (im_info->maps, pl);
2243 M17N_OBJECT_UNREF (pl);
2246 else if (key == Mmacro)
2248 if (! im_info->macros)
2249 im_info->macros = mplist ();
2250 MPLIST_DO (elt, MPLIST_NEXT (elt))
2252 if (MFAILP (MPLIST_PLIST_P (elt)))
2254 load_macros (im_info, MPLIST_PLIST (elt));
2257 else if (key == Mmodule)
2259 if (! im_info->externals)
2260 im_info->externals = mplist ();
2261 MPLIST_DO (elt, MPLIST_NEXT (elt))
2263 if (MFAILP (MPLIST_PLIST_P (elt)))
2265 load_external_module (im_info, MPLIST_PLIST (elt));
2268 else if (key == Mstate)
2270 MPLIST_DO (elt, MPLIST_NEXT (elt))
2274 if (MFAILP (MPLIST_PLIST_P (elt)))
2276 pl = MPLIST_PLIST (elt);
2277 if (! im_info->states)
2278 im_info->states = mplist ();
2279 state = load_state (im_info, MPLIST_PLIST (elt));
2282 mplist_put (im_info->states, state->name, state);
2285 else if (key == Minclude)
2287 /* elt ::= include (tag1 tag2 ...) key item ... */
2289 MInputMethodInfo *temp;
2291 elt = MPLIST_NEXT (elt);
2292 if (MFAILP (MPLIST_PLIST_P (elt)))
2294 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2297 elt = MPLIST_NEXT (elt);
2298 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2300 key = MPLIST_SYMBOL (elt);
2301 elt = MPLIST_NEXT (elt);
2304 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2306 if (! im_info->maps)
2307 im_info->maps = mplist ();
2308 MPLIST_DO (pl, temp->maps)
2310 p = MPLIST_VAL (pl);
2311 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2312 M17N_OBJECT_REF (p);
2315 else if (key == Mmacro)
2317 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2319 if (! im_info->macros)
2320 im_info->macros = mplist ();
2321 MPLIST_DO (pl, temp->macros)
2323 p = MPLIST_VAL (pl);
2324 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2325 M17N_OBJECT_REF (p);
2328 else if (key == Mstate)
2330 if (! temp->states || MPLIST_TAIL_P (temp->states))
2332 if (! im_info->states)
2333 im_info->states = mplist ();
2334 MPLIST_DO (pl, temp->states)
2336 MIMState *state = MPLIST_VAL (pl);
2338 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2339 M17N_OBJECT_REF (state);
2343 else if (key == Mdescription)
2345 if (im_info->description)
2347 elt = MPLIST_NEXT (elt);
2348 if (! check_description (elt))
2350 im_info->description = MPLIST_MTEXT (elt);
2351 M17N_OBJECT_REF (im_info->description);
2354 im_info->tick = time (NULL);
2359 static int take_action_list (MInputContext *ic, MPlist *action_list);
2360 static void preedit_commit (MInputContext *ic, int need_prefix);
2363 shift_state (MInputContext *ic, MSymbol state_name)
2365 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2366 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2367 MIMState *orig_state = ic_info->state, *state;
2369 /* Find a state to shift to. If not found, shift to the initial
2371 if (state_name == Mt)
2373 if (! ic_info->prev_state)
2375 state = ic_info->prev_state;
2377 else if (state_name == Mnil)
2379 state = (MIMState *) MPLIST_VAL (im_info->states);
2383 state = (MIMState *) mplist_get (im_info->states, state_name);
2385 state = (MIMState *) MPLIST_VAL (im_info->states);
2391 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2392 MSYMBOL_NAME (orig_state->name),
2393 MSYMBOL_NAME (state->name));
2395 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2398 /* Enter the new state. */
2399 ic_info->state = state;
2400 ic_info->map = state->map;
2401 ic_info->state_key_head = ic_info->key_head;
2402 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2404 /* We have shifted to the initial state. */
2405 preedit_commit (ic, 0);
2406 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2407 ic_info->state_pos = ic->cursor_pos;
2408 if (state != orig_state)
2410 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2412 /* Shifted to the initial state. */
2413 ic_info->prev_state = NULL;
2414 M17N_OBJECT_UNREF (ic_info->vars_saved);
2415 ic_info->vars_saved = mplist_copy (ic_info->vars);
2418 ic_info->prev_state = orig_state;
2421 ic->status = state->title;
2423 ic->status = im_info->title;
2424 ic->status_changed = 1;
2425 if (ic_info->map == ic_info->state->map
2426 && ic_info->map->map_actions)
2428 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2429 MSYMBOL_NAME (state->name));
2430 take_action_list (ic, ic_info->map->map_actions);
2435 /* Find a candidate group that contains a candidate number INDEX from
2436 PLIST. Set START_INDEX to the first candidate number of the group,
2437 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2438 candidate group number if they are non-NULL. If INDEX is -1, find
2439 the last candidate group. */
2442 find_candidates_group (MPlist *plist, int index,
2443 int *start_index, int *end_index, int *group_index)
2445 int i = 0, gidx = 0, len;
2447 MPLIST_DO (plist, plist)
2449 if (MPLIST_MTEXT_P (plist))
2450 len = mtext_nchars (MPLIST_MTEXT (plist));
2452 len = mplist_length (MPLIST_PLIST (plist));
2453 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2459 *end_index = i + len;
2461 *group_index = gidx;
2470 /* Adjust markers for the change of preedit text.
2471 If FROM == TO, the change is insertion of INS chars.
2472 If FROM < TO and INS == 0, the change is deletion of the range.
2473 If FROM < TO and INS > 0, the change is replacement. */
2476 adjust_markers (MInputContext *ic, int from, int to, int ins)
2478 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2483 MPLIST_DO (markers, ic_info->markers)
2484 if (MPLIST_INTEGER (markers) > from)
2485 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2486 if (ic->cursor_pos >= from)
2487 ic->cursor_pos += ins;
2491 MPLIST_DO (markers, ic_info->markers)
2493 if (MPLIST_INTEGER (markers) >= to)
2494 MPLIST_VAL (markers)
2495 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2496 else if (MPLIST_INTEGER (markers) > from)
2497 MPLIST_VAL (markers) = (void *) from;
2499 if (ic->cursor_pos >= to)
2500 ic->cursor_pos += ins - (to - from);
2501 else if (ic->cursor_pos > from)
2502 ic->cursor_pos = from;
2508 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2510 int nchars = mt ? mtext_nchars (mt) : 1;
2514 mtext_ins (ic->preedit, pos, mt);
2515 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2519 mtext_ins_char (ic->preedit, pos, c, 1);
2521 MDEBUG_PRINT1 ("('%c')", c);
2523 MDEBUG_PRINT1 ("(U+%04X)", c);
2525 adjust_markers (ic, pos, pos, nchars);
2526 ic->preedit_changed = 1;
2531 preedit_delete (MInputContext *ic, int from, int to)
2533 mtext_del (ic->preedit, from, to);
2534 adjust_markers (ic, from, to, 0);
2535 ic->preedit_changed = 1;
2539 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2543 mtext_del (ic->preedit, from, to);
2546 mtext_ins (ic->preedit, from, mt);
2547 ins = mtext_nchars (mt);
2551 mtext_ins_char (ic->preedit, from, c, 1);
2554 adjust_markers (ic, from, to, ins);
2555 ic->preedit_changed = 1;
2560 preedit_commit (MInputContext *ic, int need_prefix)
2562 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2563 int preedit_len = mtext_nchars (ic->preedit);
2565 if (preedit_len > 0)
2569 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2570 Mcandidate_list, NULL, 0);
2571 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2572 Mcandidate_index, NULL, 0);
2573 mtext_cat (ic->produced, ic->preedit);
2579 MDEBUG_PRINT1 ("\n [IM] [%s]",
2580 MSYMBOL_NAME (ic_info->state->name));
2581 MDEBUG_PRINT (" (commit");
2582 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2583 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2587 mtext_reset (ic->preedit);
2588 mtext_reset (ic_info->preedit_saved);
2589 MPLIST_DO (p, ic_info->markers)
2591 ic->cursor_pos = ic_info->state_pos = 0;
2592 ic->preedit_changed = 1;
2593 ic_info->commit_key_head = ic_info->key_head;
2595 if (ic->candidate_list)
2597 M17N_OBJECT_UNREF (ic->candidate_list);
2598 ic->candidate_list = NULL;
2599 ic->candidate_index = 0;
2600 ic->candidate_from = ic->candidate_to = 0;
2601 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2602 if (ic->candidate_show)
2604 ic->candidate_show = 0;
2605 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2611 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2613 int code = marker_code (sym, 0);
2615 if (mt && (code == '[' || code == ']'))
2619 if (code == '[' && current > 0)
2621 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2625 else if (code == ']' && current < mtext_nchars (mt))
2627 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2633 return (code == '<' ? 0
2634 : code == '>' ? limit
2635 : code == '-' ? current - 1
2636 : code == '+' ? current + 1
2637 : code == '=' ? current
2638 : code - '0' > limit ? limit
2642 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2646 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2648 int from = mtext_property_start (prop);
2649 int to = mtext_property_end (prop);
2651 MPlist *candidate_list = mtext_property_value (prop);
2652 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2654 int ingroup_index = idx - start;
2657 candidate_list = mplist_copy (candidate_list);
2658 if (MPLIST_MTEXT_P (group))
2660 mt = MPLIST_MTEXT (group);
2661 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2669 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2670 i++, plist = MPLIST_NEXT (plist));
2671 mt = MPLIST_MTEXT (plist);
2672 preedit_replace (ic, from, to, mt, 0);
2673 to = from + mtext_nchars (mt);
2675 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2676 M17N_OBJECT_UNREF (candidate_list);
2677 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2678 ic->cursor_pos = to;
2682 get_select_charset (MInputContextInfo * ic_info)
2684 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2687 if (! MPLIST_VAL (plist))
2689 sym = MPLIST_SYMBOL (plist);
2692 return MCHARSET (sym);
2696 adjust_candidates (MPlist *plist, MCharset *charset)
2700 /* plist ::= MTEXT ... | PLIST ... */
2701 plist = mplist_copy (plist);
2702 if (MPLIST_MTEXT_P (plist))
2705 while (! MPLIST_TAIL_P (pl))
2707 /* pl ::= MTEXT ... */
2708 MText *mt = MPLIST_MTEXT (pl);
2712 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2714 c = mtext_ref_char (mt, i);
2715 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2719 mt = mtext_dup (mt);
2720 mplist_set (pl, Mtext, mt);
2721 M17N_OBJECT_UNREF (mt);
2724 mtext_del (mt, i, i + 1);
2727 if (mtext_len (mt) > 0)
2728 pl = MPLIST_NEXT (pl);
2732 M17N_OBJECT_UNREF (mt);
2736 else /* MPLIST_PLIST_P (plist) */
2739 while (! MPLIST_TAIL_P (pl))
2741 /* pl ::= (MTEXT ...) ... */
2742 MPlist *p = MPLIST_PLIST (pl);
2744 /* p ::= MTEXT ... */
2748 while (! MPLIST_TAIL_P (p0))
2750 MText *mt = MPLIST_MTEXT (p0);
2753 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2755 c = mtext_ref_char (mt, i);
2756 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2761 p0 = MPLIST_NEXT (p0);
2768 p = mplist_copy (p);
2769 mplist_set (pl, Mplist, p);
2770 M17N_OBJECT_UNREF (p);
2774 p0 = MPLIST_NEXT (p0);
2777 M17N_OBJECT_UNREF (mt);
2780 if (! MPLIST_TAIL_P (p))
2781 pl = MPLIST_NEXT (pl);
2785 M17N_OBJECT_UNREF (p);
2789 if (MPLIST_TAIL_P (plist))
2791 M17N_OBJECT_UNREF (plist);
2798 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2800 MCharset *charset = get_select_charset (ic_info);
2805 plist = resolve_variable (ic_info, Mcandidates_group_size);
2806 column = MPLIST_INTEGER (plist);
2808 plist = MPLIST_PLIST (args);
2810 plist = adjust_candidates (plist, charset);
2812 if (plist && column > 0)
2814 if (MPLIST_MTEXT_P (plist))
2816 MText *mt = MPLIST_MTEXT (plist);
2817 MPlist *next = MPLIST_NEXT (plist);
2819 if (MPLIST_TAIL_P (next))
2820 M17N_OBJECT_REF (mt);
2823 mt = mtext_dup (mt);
2824 while (! MPLIST_TAIL_P (next))
2826 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2827 next = MPLIST_NEXT (next);
2831 M17N_OBJECT_UNREF (plist);
2833 len = mtext_nchars (mt);
2835 mplist_add (plist, Mtext, mt);
2838 for (i = 0; i < len; i += column)
2840 int to = (i + column < len ? i + column : len);
2841 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2843 mplist_add (plist, Mtext, sub);
2844 M17N_OBJECT_UNREF (sub);
2847 M17N_OBJECT_UNREF (mt);
2849 else if (! MPLIST_TAIL_P (plist))
2851 MPlist *tail = plist;
2852 MPlist *new = mplist ();
2853 MPlist *this = mplist ();
2856 MPLIST_DO (tail, tail)
2858 MPlist *p = MPLIST_PLIST (tail);
2862 MText *mt = MPLIST_MTEXT (p);
2864 if (count == column)
2866 mplist_add (new, Mplist, this);
2867 M17N_OBJECT_UNREF (this);
2871 mplist_add (this, Mtext, mt);
2875 mplist_add (new, Mplist, this);
2876 M17N_OBJECT_UNREF (this);
2877 mplist_set (plist, Mnil, NULL);
2878 MPLIST_DO (tail, new)
2880 MPlist *elt = MPLIST_PLIST (tail);
2882 mplist_add (plist, Mplist, elt);
2884 M17N_OBJECT_UNREF (new);
2893 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2895 MPlist *action = NULL;
2899 if (MPLIST_SYMBOL_P (action_list))
2901 MSymbol var = MPLIST_SYMBOL (action_list);
2904 MPLIST_DO (p, ic_info->vars)
2905 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2907 if (MPLIST_TAIL_P (p))
2909 action = MPLIST_NEXT (MPLIST_PLIST (p));
2910 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2913 if (MPLIST_PLIST_P (action_list))
2915 action = MPLIST_PLIST (action_list);
2916 if (MPLIST_SYMBOL_P (action))
2918 name = MPLIST_SYMBOL (action);
2919 args = MPLIST_NEXT (action);
2921 && MPLIST_PLIST_P (args))
2922 mplist_set (action, Msymbol, M_candidates);
2924 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2927 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2928 mplist_push (action, Msymbol, M_candidates);
2929 mplist_set (action_list, Mplist, action);
2930 M17N_OBJECT_UNREF (action);
2933 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2936 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2937 mplist_push (action, Msymbol, Minsert);
2938 mplist_set (action_list, Mplist, action);
2939 M17N_OBJECT_UNREF (action);
2944 /* Perform list of actions in ACTION_LIST for the current input
2945 context IC. If unhandle action was not performed, return 0.
2946 Otherwise, return -1. */
2949 take_action_list (MInputContext *ic, MPlist *action_list)
2951 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2952 MPlist *candidate_list = ic->candidate_list;
2953 int candidate_index = ic->candidate_index;
2954 int candidate_show = ic->candidate_show;
2955 MTextProperty *prop;
2957 MPLIST_DO (action_list, action_list)
2959 MPlist *action = regularize_action (action_list, ic_info);
2965 name = MPLIST_SYMBOL (action);
2966 args = MPLIST_NEXT (action);
2968 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2969 if (name == Minsert)
2971 if (MPLIST_SYMBOL_P (args))
2973 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2974 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2977 if (MPLIST_MTEXT_P (args))
2978 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2979 else /* MPLIST_INTEGER_P (args)) */
2980 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2982 else if (name == M_candidates)
2984 MPlist *plist = get_candidate_list (ic_info, args);
2987 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2989 if (MPLIST_MTEXT_P (plist))
2991 preedit_insert (ic, ic->cursor_pos, NULL,
2992 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2995 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2999 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3001 preedit_insert (ic, ic->cursor_pos, mt, 0);
3002 len = mtext_nchars (mt);
3004 plist = mplist_copy (plist);
3005 mtext_put_prop (ic->preedit,
3006 ic->cursor_pos - len, ic->cursor_pos,
3007 Mcandidate_list, plist);
3008 M17N_OBJECT_UNREF (plist);
3009 mtext_put_prop (ic->preedit,
3010 ic->cursor_pos - len, ic->cursor_pos,
3011 Mcandidate_index, (void *) 0);
3013 else if (name == Mselect)
3016 int code, idx, gindex;
3017 int pos = ic->cursor_pos;
3019 int idx_decided = 0;
3022 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3025 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3026 group = find_candidates_group (mtext_property_value (prop), idx,
3027 &start, &end, &gindex);
3028 if (MPLIST_SYMBOL_P (args))
3030 code = marker_code (MPLIST_SYMBOL (args), 0);
3033 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3034 if (! MPLIST_INTEGER_P (args))
3036 idx = start + MPLIST_INTEGER (args);
3037 if (idx < start || idx >= end)
3045 if (code != '[' && code != ']')
3050 ? new_index (NULL, ic->candidate_index - start,
3051 end - start - 1, MPLIST_SYMBOL (args),
3053 : MPLIST_INTEGER (args)));
3056 find_candidates_group (mtext_property_value (prop), -1,
3061 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3066 int ingroup_index = idx - start;
3069 group = mtext_property_value (prop);
3070 len = mplist_length (group);
3083 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3084 idx += (MPLIST_MTEXT_P (group)
3085 ? mtext_nchars (MPLIST_MTEXT (group))
3086 : mplist_length (MPLIST_PLIST (group)));
3087 len = (MPLIST_MTEXT_P (group)
3088 ? mtext_nchars (MPLIST_MTEXT (group))
3089 : mplist_length (MPLIST_PLIST (group)));
3090 if (ingroup_index >= len)
3091 ingroup_index = len - 1;
3092 idx += ingroup_index;
3094 update_candidate (ic, prop, idx);
3095 MDEBUG_PRINT1 ("(%d)", idx);
3097 else if (name == Mshow)
3098 ic->candidate_show = 1;
3099 else if (name == Mhide)
3100 ic->candidate_show = 0;
3101 else if (name == Mdelete)
3103 int len = mtext_nchars (ic->preedit);
3107 if (MPLIST_SYMBOL_P (args)
3108 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3110 to = ic->cursor_pos + pos;
3113 delete_surrounding_text (ic, to);
3118 delete_surrounding_text (ic, to - len);
3124 to = (MPLIST_SYMBOL_P (args)
3125 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3127 : MPLIST_INTEGER (args));
3132 pos = to - ic->cursor_pos;
3134 MDEBUG_PRINT1 ("(%d)", pos);
3135 if (to < ic->cursor_pos)
3136 preedit_delete (ic, to, ic->cursor_pos);
3137 else if (to > ic->cursor_pos)
3138 preedit_delete (ic, ic->cursor_pos, to);
3140 else if (name == Mmove)
3142 int len = mtext_nchars (ic->preedit);
3144 = (MPLIST_SYMBOL_P (args)
3145 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3147 : MPLIST_INTEGER (args));
3153 if (pos != ic->cursor_pos)
3155 ic->cursor_pos = pos;
3156 ic->preedit_changed = 1;
3158 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3160 else if (name == Mmark)
3162 int code = marker_code (MPLIST_SYMBOL (args), 0);
3166 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3167 (void *) ic->cursor_pos);
3168 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3171 else if (name == Mpushback)
3173 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3177 if (MPLIST_SYMBOL_P (args))
3179 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3180 if (MPLIST_INTEGER_P (args))
3181 num = MPLIST_INTEGER (args);
3186 num = MPLIST_INTEGER (args);
3189 ic_info->key_head -= num;
3191 ic_info->key_head = 0;
3193 ic_info->key_head = - num;
3194 if (ic_info->key_head > ic_info->used)
3195 ic_info->key_head = ic_info->used;
3197 else if (MPLIST_MTEXT_P (args))
3199 MText *mt = MPLIST_MTEXT (args);
3200 int i, len = mtext_nchars (mt);
3203 ic_info->key_head--;
3204 for (i = 0; i < len; i++)
3206 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3207 if (ic_info->key_head + i < ic_info->used)
3208 ic_info->keys[ic_info->key_head + i] = key;
3210 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3215 MPlist *plist = MPLIST_PLIST (args), *pl;
3219 ic_info->key_head--;
3221 MPLIST_DO (pl, plist)
3223 key = MPLIST_SYMBOL (pl);
3224 if (ic_info->key_head < ic_info->used)
3225 ic_info->keys[ic_info->key_head + i] = key;
3227 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3232 else if (name == Mpop)
3234 if (ic_info->key_head < ic_info->used)
3235 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3237 else if (name == Mcall)
3239 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3240 MIMExternalFunc func = NULL;
3241 MSymbol module, func_name;
3242 MPlist *func_args, *val;
3245 module = MPLIST_SYMBOL (args);
3246 args = MPLIST_NEXT (args);
3247 func_name = MPLIST_SYMBOL (args);
3249 if (im_info->externals)
3251 MIMExternalModule *external
3252 = (MIMExternalModule *) mplist_get (im_info->externals,
3255 func = ((MIMExternalFunc)
3256 mplist_get_func (external->func_list, func_name));
3260 func_args = mplist ();
3261 mplist_add (func_args, Mt, ic);
3262 MPLIST_DO (args, MPLIST_NEXT (args))
3266 if (MPLIST_KEY (args) == Msymbol
3267 && MPLIST_KEY (args) != Mnil
3268 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3270 code = new_index (ic, ic->cursor_pos,
3271 mtext_nchars (ic->preedit),
3272 MPLIST_SYMBOL (args), ic->preedit);
3273 mplist_add (func_args, Minteger, (void *) code);
3276 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3278 val = (func) (func_args);
3279 M17N_OBJECT_UNREF (func_args);
3280 if (val && ! MPLIST_TAIL_P (val))
3281 ret = take_action_list (ic, val);
3282 M17N_OBJECT_UNREF (val);
3286 else if (name == Mshift)
3288 shift_state (ic, MPLIST_SYMBOL (args));
3290 else if (name == Mundo)
3292 int intarg = (MPLIST_TAIL_P (args)
3294 : integer_value (ic, args, 0));
3296 mtext_reset (ic->preedit);
3297 mtext_reset (ic_info->preedit_saved);
3298 mtext_reset (ic->produced);
3299 M17N_OBJECT_UNREF (ic_info->vars);
3300 ic_info->vars = mplist_copy (ic_info->vars_saved);
3301 ic->cursor_pos = ic_info->state_pos = 0;
3302 ic_info->state_key_head = ic_info->key_head
3303 = ic_info->commit_key_head = 0;
3305 shift_state (ic, Mnil);
3308 if (MPLIST_TAIL_P (args))
3313 ic_info->used += intarg;
3316 ic_info->used = intarg;
3319 else if (name == Mset || name == Madd || name == Msub
3320 || name == Mmul || name == Mdiv)
3322 MSymbol sym = MPLIST_SYMBOL (args);
3323 MPlist *value = resolve_variable (ic_info, sym);
3327 val1 = MPLIST_INTEGER (value);
3328 args = MPLIST_NEXT (args);
3329 val2 = resolve_expression (ic, args);
3331 val1 = val2, op = "=";
3332 else if (name == Madd)
3333 val1 += val2, op = "+=";
3334 else if (name == Msub)
3335 val1 -= val2, op = "-=";
3336 else if (name == Mmul)
3337 val1 *= val2, op = "*=";
3339 val1 /= val2, op = "/=";
3340 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3341 MSYMBOL_NAME (sym), op, val1, val1);
3342 mplist_set (value, Minteger, (void *) val1);
3344 else if (name == Mequal || name == Mless || name == Mgreater
3345 || name == Mless_equal || name == Mgreater_equal)
3348 MPlist *actions1, *actions2;
3351 val1 = resolve_expression (ic, args);
3352 args = MPLIST_NEXT (args);
3353 val2 = resolve_expression (ic, args);
3354 args = MPLIST_NEXT (args);
3355 actions1 = MPLIST_PLIST (args);
3356 args = MPLIST_NEXT (args);
3357 if (MPLIST_TAIL_P (args))
3360 actions2 = MPLIST_PLIST (args);
3361 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3362 if (name == Mequal ? val1 == val2
3363 : name == Mless ? val1 < val2
3364 : name == Mgreater ? val1 > val2
3365 : name == Mless_equal ? val1 <= val2
3368 MDEBUG_PRINT ("ok");
3369 ret = take_action_list (ic, actions1);
3373 MDEBUG_PRINT ("no");
3375 ret = take_action_list (ic, actions2);
3380 else if (name == Mcond)
3384 MPLIST_DO (args, args)
3389 if (! MPLIST_PLIST (args))
3391 cond = MPLIST_PLIST (args);
3392 if (resolve_expression (ic, cond) != 0)
3394 MDEBUG_PRINT1 ("(%dth)", idx);
3395 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3401 else if (name == Mcommit)
3403 preedit_commit (ic, 0);
3405 else if (name == Munhandle)
3407 preedit_commit (ic, 0);
3412 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3416 && (actions = mplist_get (im_info->macros, name)))
3418 if (take_action_list (ic, actions) < 0)
3424 if (ic->candidate_list)
3426 M17N_OBJECT_UNREF (ic->candidate_list);
3427 ic->candidate_list = NULL;
3429 if (ic->cursor_pos > 0
3430 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3433 ic->candidate_list = mtext_property_value (prop);
3434 M17N_OBJECT_REF (ic->candidate_list);
3436 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3438 ic->candidate_from = mtext_property_start (prop);
3439 ic->candidate_to = mtext_property_end (prop);
3442 if (candidate_list != ic->candidate_list)
3443 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3444 if (candidate_index != ic->candidate_index)
3445 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3446 if (candidate_show != ic->candidate_show)
3447 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3452 /* Handle the input key KEY in the current state and map specified in
3453 the input context IC. If KEY is handled correctly, return 0.
3454 Otherwise, return -1. */
3457 handle_key (MInputContext *ic)
3459 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3460 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3461 MIMMap *map = ic_info->map;
3462 MIMMap *submap = NULL;
3463 MSymbol key = ic_info->keys[ic_info->key_head];
3464 MSymbol alias = Mnil;
3467 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3468 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3472 submap = mplist_get (map->submaps, key);
3475 && (alias = msymbol_get (alias, M_key_alias))
3477 submap = mplist_get (map->submaps, alias);
3482 if (! alias || alias == key)
3483 MDEBUG_PRINT (" submap-found");
3485 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3486 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3487 ic->preedit_changed = 1;
3488 ic->cursor_pos = ic_info->state_pos;
3489 ic_info->key_head++;
3490 ic_info->map = map = submap;
3491 if (map->map_actions)
3493 MDEBUG_PRINT (" map-actions:");
3494 if (take_action_list (ic, map->map_actions) < 0)
3496 MDEBUG_PRINT ("\n");
3500 else if (map->submaps)
3502 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3504 MSymbol key = ic_info->keys[i];
3505 char *name = msymbol_name (key);
3507 if (! name[0] || ! name[1])
3508 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3512 /* If this is the terminal map or we have shifted to another
3513 state, perform branch actions (if any). */
3514 if (! map->submaps || map != ic_info->map)
3516 if (map->branch_actions)
3518 MDEBUG_PRINT (" branch-actions:");
3519 if (take_action_list (ic, map->branch_actions) < 0)
3521 MDEBUG_PRINT ("\n");
3525 /* If MAP is still not the root map, shift to the current
3527 if (ic_info->map != ic_info->state->map)
3528 shift_state (ic, ic_info->state->name);
3533 /* MAP can not handle KEY. */
3535 /* Perform branch actions if any. */
3536 if (map->branch_actions)
3538 MDEBUG_PRINT (" branch-actions:");
3539 if (take_action_list (ic, map->branch_actions) < 0)
3541 MDEBUG_PRINT ("\n");
3546 if (map == ic_info->map)
3548 /* The above branch actions didn't change the state. */
3550 /* If MAP is the root map of the initial state, and there
3551 still exist an unhandled key, it means that the current
3552 input method can not handle it. */
3553 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3554 && ic_info->key_head < ic_info->used)
3556 MDEBUG_PRINT (" unhandled\n");
3560 if (map != ic_info->state->map)
3562 /* MAP is not the root map. Shift to the root map of the
3564 shift_state (ic, ic_info->state->name);
3566 else if (! map->branch_actions)
3568 /* MAP is the root map without any default branch
3569 actions. Shift to the initial state. */
3570 shift_state (ic, Mnil);
3574 MDEBUG_PRINT ("\n");
3578 /* Initialize IC->ic_info. */
3581 init_ic_info (MInputContext *ic)
3583 MInputMethodInfo *im_info = ic->im->info;
3584 MInputContextInfo *ic_info = ic->info;
3587 MLIST_INIT1 (ic_info, keys, 8);;
3589 ic_info->markers = mplist ();
3591 ic_info->vars = mplist ();
3592 if (im_info->configured_vars)
3593 MPLIST_DO (plist, im_info->configured_vars)
3595 MPlist *pl = MPLIST_PLIST (plist);
3596 MSymbol name = MPLIST_SYMBOL (pl);
3598 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3599 if (MPLIST_KEY (pl) != Mt)
3601 MPlist *p = mplist ();
3603 mplist_push (ic_info->vars, Mplist, p);
3604 M17N_OBJECT_UNREF (p);
3605 mplist_add (p, Msymbol, name);
3606 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3609 ic_info->vars_saved = mplist_copy (ic_info->vars);
3611 if (im_info->externals)
3613 MPlist *func_args = mplist (), *plist;
3615 mplist_add (func_args, Mt, ic);
3616 MPLIST_DO (plist, im_info->externals)
3618 MIMExternalModule *external = MPLIST_VAL (plist);
3619 MIMExternalFunc func
3620 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3625 M17N_OBJECT_UNREF (func_args);
3628 ic_info->preedit_saved = mtext ();
3629 ic_info->tick = im_info->tick;
3632 /* Finalize IC->ic_info. */
3635 fini_ic_info (MInputContext *ic)
3637 MInputMethodInfo *im_info = ic->im->info;
3638 MInputContextInfo *ic_info = ic->info;
3640 if (im_info->externals)
3642 MPlist *func_args = mplist (), *plist;
3644 mplist_add (func_args, Mt, ic);
3645 MPLIST_DO (plist, im_info->externals)
3647 MIMExternalModule *external = MPLIST_VAL (plist);
3648 MIMExternalFunc func
3649 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3654 M17N_OBJECT_UNREF (func_args);
3657 MLIST_FREE1 (ic_info, keys);
3658 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3659 M17N_OBJECT_UNREF (ic_info->markers);
3660 M17N_OBJECT_UNREF (ic_info->vars);
3661 M17N_OBJECT_UNREF (ic_info->vars_saved);
3662 M17N_OBJECT_UNREF (ic_info->preceding_text);
3663 M17N_OBJECT_UNREF (ic_info->following_text);
3665 memset (ic_info, 0, sizeof (MInputContextInfo));
3669 re_init_ic (MInputContext *ic, int reload)
3671 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3672 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3673 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3675 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3676 preedit_changed = mtext_nchars (ic->preedit) > 0;
3677 cursor_pos_changed = ic->cursor_pos > 0;
3678 candidates_changed = 0;
3679 if (ic->candidate_list)
3681 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3682 M17N_OBJECT_UNREF (ic->candidate_list);
3683 ic->candidate_list = NULL;
3685 if (ic->candidate_show)
3687 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3688 ic->candidate_show = 0;
3690 if (ic->candidate_index > 0)
3692 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3693 ic->candidate_index = 0;
3694 ic->candidate_from = ic->candidate_to = 0;
3696 if (mtext_nchars (ic->produced) > 0)
3697 mtext_reset (ic->produced);
3698 if (mtext_nchars (ic->preedit) > 0)
3699 mtext_reset (ic->preedit);
3701 M17N_OBJECT_UNREF (ic->plist);
3702 ic->plist = mplist ();
3706 reload_im_info (im_info);
3707 if (! im_info->states)
3709 struct MIMState *state;
3711 M17N_OBJECT (state, free_state, MERROR_IM);
3712 state->name = msymbol ("init");
3713 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3714 MSTRUCT_CALLOC (state->map, MERROR_IM);
3715 im_info->states = mplist ();
3716 mplist_add (im_info->states, state->name, state);
3719 shift_state (ic, Mnil);
3721 ic->status_changed = status_changed;
3722 ic->preedit_changed = preedit_changed;
3723 ic->cursor_pos_changed = cursor_pos_changed;
3724 ic->candidates_changed = candidates_changed;
3728 reset_ic (MInputContext *ic, MSymbol ignore)
3730 MDEBUG_PRINT ("\n [IM] reset\n");
3735 open_im (MInputMethod *im)
3737 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3739 if (! im_info || ! im_info->states)
3740 MERROR (MERROR_IM, -1);
3747 close_im (MInputMethod *im)
3753 create_ic (MInputContext *ic)
3755 MInputContextInfo *ic_info;
3757 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3760 shift_state (ic, Mnil);
3765 destroy_ic (MInputContext *ic)
3772 check_reload (MInputContext *ic, MSymbol key)
3774 MInputMethodInfo *im_info = ic->im->info;
3775 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3779 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3783 MPLIST_DO (plist, plist)
3785 MSymbol this_key, alias;
3787 if (MPLIST_MTEXT_P (plist))
3789 MText *mt = MPLIST_MTEXT (plist);
3790 int c = mtext_ref_char (mt, 0);
3794 this_key = one_char_symbol[c];
3798 MPlist *pl = MPLIST_PLIST (plist);
3800 this_key = MPLIST_SYMBOL (pl);
3804 && (alias = msymbol_get (alias, M_key_alias))
3805 && alias != this_key);
3809 if (MPLIST_TAIL_P (plist))
3812 MDEBUG_PRINT ("\n [IM] reload");
3818 /** Handle the input key KEY in the current state and map of IC->info.
3819 If KEY is handled but no text is produced, return 0, otherwise
3825 filter (MInputContext *ic, MSymbol key, void *arg)
3827 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3828 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3831 if (check_reload (ic, key))
3834 if (! ic_info->state)
3836 ic_info->key_unhandled = 1;
3839 mtext_reset (ic->produced);
3840 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3841 M17N_OBJECT_UNREF (ic_info->preceding_text);
3842 M17N_OBJECT_UNREF (ic_info->following_text);
3843 ic_info->preceding_text = ic_info->following_text = NULL;
3844 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3845 ic_info->key_unhandled = 0;
3848 if (handle_key (ic) < 0)
3850 /* KEY was not handled. Delete it from the current key sequence. */
3851 if (ic_info->used > 0)
3853 memmove (ic_info->keys, ic_info->keys + 1,
3854 sizeof (int) * (ic_info->used - 1));
3856 if (ic_info->state_key_head > 0)
3857 ic_info->state_key_head--;
3858 if (ic_info->commit_key_head > 0)
3859 ic_info->commit_key_head--;
3861 /* This forces returning 1. */
3862 ic_info->key_unhandled = 1;
3868 reset_ic (ic, Mnil);
3869 ic_info->key_unhandled = 1;
3872 /* Break the loop if all keys were handled. */
3873 } while (ic_info->key_head < ic_info->used);
3875 /* If the current map is the root of the initial state, we should
3876 produce any preedit text in ic->produced. */
3877 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3878 preedit_commit (ic, 1);
3880 if (mtext_nchars (ic->produced) > 0)
3884 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3885 MSYMBOL_NAME (ic_info->state->name));
3886 for (i = 0; i < mtext_nchars (ic->produced); i++)
3887 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3891 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3892 Mlanguage, ic->im->language);
3894 if (ic_info->commit_key_head > 0)
3896 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3897 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3898 ic_info->used -= ic_info->commit_key_head;
3899 ic_info->key_head -= ic_info->commit_key_head;
3900 ic_info->state_key_head -= ic_info->commit_key_head;
3901 ic_info->commit_key_head = 0;
3903 if (ic_info->key_unhandled)
3906 ic_info->key_head = ic_info->state_key_head
3907 = ic_info->commit_key_head = 0;
3910 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3914 /** Return 1 if the last event or key was not handled, otherwise
3917 There is no need of looking up because ic->produced should already
3918 contain the produced text (if any).
3923 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3925 mtext_cat (mt, ic->produced);
3926 mtext_reset (ic->produced);
3927 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3931 /* Input method command handler. */
3933 /* List of all (global and local) commands.
3934 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3935 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3936 Global commands are stored as (t (t COMMAND ...)) */
3939 /* Input method variable handler. */
3942 /* Support functions for mdebug_dump_im. */
3945 dump_im_map (MPlist *map_list, int indent)
3948 MSymbol key = MPLIST_KEY (map_list);
3949 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3951 prefix = (char *) alloca (indent + 1);
3952 memset (prefix, 32, indent);
3953 prefix[indent] = '\0';
3955 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3956 if (map->map_actions)
3957 mdebug_dump_plist (map->map_actions, indent + 2);
3960 MPLIST_DO (map_list, map->submaps)
3962 fprintf (stderr, "\n%s ", prefix);
3963 dump_im_map (map_list, indent + 2);
3966 if (map->branch_actions)
3968 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3969 mdebug_dump_plist (map->branch_actions, indent + 4);
3970 fprintf (stderr, ")");
3972 fprintf (stderr, ")");
3977 dump_im_state (MIMState *state, int indent)
3982 prefix = (char *) alloca (indent + 1);
3983 memset (prefix, 32, indent);
3984 prefix[indent] = '\0';
3986 fprintf (stderr, "(%s", msymbol_name (state->name));
3987 if (state->map->submaps)
3989 MPLIST_DO (map_list, state->map->submaps)
3991 fprintf (stderr, "\n%s ", prefix);
3992 dump_im_map (map_list, indent + 2);
3995 fprintf (stderr, ")");
4003 Minput_driver = msymbol ("input-driver");
4005 Minput_preedit_start = msymbol ("input-preedit-start");
4006 Minput_preedit_done = msymbol ("input-preedit-done");
4007 Minput_preedit_draw = msymbol ("input-preedit-draw");
4008 Minput_status_start = msymbol ("input-status-start");
4009 Minput_status_done = msymbol ("input-status-done");
4010 Minput_status_draw = msymbol ("input-status-draw");
4011 Minput_candidates_start = msymbol ("input-candidates-start");
4012 Minput_candidates_done = msymbol ("input-candidates-done");
4013 Minput_candidates_draw = msymbol ("input-candidates-draw");
4014 Minput_set_spot = msymbol ("input-set-spot");
4015 Minput_focus_move = msymbol ("input-focus-move");
4016 Minput_focus_in = msymbol ("input-focus-in");
4017 Minput_focus_out = msymbol ("input-focus-out");
4018 Minput_toggle = msymbol ("input-toggle");
4019 Minput_reset = msymbol ("input-reset");
4020 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4021 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4022 Mcustomized = msymbol ("customized");
4023 Mconfigured = msymbol ("configured");
4024 Minherited = msymbol ("inherited");
4026 minput_default_driver.open_im = open_im;
4027 minput_default_driver.close_im = close_im;
4028 minput_default_driver.create_ic = create_ic;
4029 minput_default_driver.destroy_ic = destroy_ic;
4030 minput_default_driver.filter = filter;
4031 minput_default_driver.lookup = lookup;
4032 minput_default_driver.callback_list = mplist ();
4033 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4034 M17N_FUNC (reset_ic));
4035 minput_driver = &minput_default_driver;
4037 fully_initialized = 0;
4044 if (fully_initialized)
4046 free_im_list (im_info_list);
4048 free_im_list (im_custom_list);
4050 free_im_list (im_config_list);
4051 M17N_OBJECT_UNREF (load_im_info_keys);
4054 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4055 M17N_OBJECT_UNREF (minput_driver->callback_list);
4060 minput__char_to_key (int c)
4062 if (c < 0 || c >= 0x100)
4065 return one_char_symbol[c];
4069 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4074 /*** @addtogroup m17nInputMethod */
4079 @name Variables: Predefined symbols for callback commands.
4081 These are the predefined symbols that are used as the @c COMMAND
4082 argument of callback functions of an input method driver (see
4083 #MInputDriver::callback_list).
4085 Most of them do not require extra argument nor return any value;
4086 exceptions are these:
4088 Minput_get_surrounding_text: When a callback function assigned for
4089 this command is called, the first element of #MInputContext::plist
4090 has key #Minteger and the value specifies which portion of the
4091 surrounding text should be retrieved. If the value is positive,
4092 it specifies the number of characters following the current cursor
4093 position. If the value is negative, the absolute value specifies
4094 the number of characters preceding the current cursor position.
4095 If the value is zero, it means that the caller just wants to know
4096 if the surrounding text is currently supported or not.
4098 If the surrounding text is currently supported, the callback
4099 function must set the key of this element to #Mtext and the value
4100 to the retrieved M-text. The length of the M-text may be shorter
4101 than the requested number of characters, if the available text is
4102 not that long. The length can be zero in the worst case. Or, the
4103 length may be longer if an application thinks it is more efficient
4104 to return that length.
4106 If the surrounding text is not currently supported, the callback
4107 function should return without changing the first element of
4108 #MInputContext::plist.
4110 Minput_delete_surrounding_text: When a callback function assigned
4111 for this command is called, the first element of
4112 #MInputContext::plist has key #Minteger and the value specifies
4113 which portion of the surrounding text should be deleted in the
4114 same way as the case of Minput_get_surrounding_text. The callback
4115 function must delete the specified text. It should not alter
4116 #MInputContext::plist. */
4118 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4120 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4121 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4123 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4125 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4126 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4127 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4128 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4129 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4130 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4131 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4133 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4134 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4135 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4136 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4137 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4139 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4140 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4142 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4143 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4144 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4145 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4146 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4147 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4151 MSymbol Minput_preedit_start;
4152 MSymbol Minput_preedit_done;
4153 MSymbol Minput_preedit_draw;
4154 MSymbol Minput_status_start;
4155 MSymbol Minput_status_done;
4156 MSymbol Minput_status_draw;
4157 MSymbol Minput_candidates_start;
4158 MSymbol Minput_candidates_done;
4159 MSymbol Minput_candidates_draw;
4160 MSymbol Minput_set_spot;
4161 MSymbol Minput_toggle;
4162 MSymbol Minput_reset;
4163 MSymbol Minput_get_surrounding_text;
4164 MSymbol Minput_delete_surrounding_text;
4170 @name Variables: Predefined symbols for special input events.
4172 These are the predefined symbols that are used as the @c KEY
4173 argument of minput_filter (). */
4175 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4177 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4182 MSymbol Minput_focus_out;
4183 MSymbol Minput_focus_in;
4184 MSymbol Minput_focus_move;
4190 @name Variables: Predefined symbols used in input method information.
4192 These are the predefined symbols describing status of input method
4193 command and variable, and are used in a return value of
4194 minput_get_command () and minput_get_variable (). */
4196 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4198 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4199 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4203 MSymbol Mcustomized;
4204 MSymbol Mconfigured;
4210 @brief The default driver for internal input methods.
4212 The variable #minput_default_driver is the default driver for
4213 internal input methods.
4215 The member MInputDriver::open_im () searches the m17n database for
4216 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4217 $NAME\> and loads it.
4219 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4220 programmers responsibility to set it to a plist of proper callback
4221 functions. Otherwise, no feedback information (e.g. preedit text)
4222 can be shown to users.
4224 The macro M17N_INIT () sets the variable #minput_driver to the
4225 pointer to this driver so that all internal input methods use it.
4227 Therefore, unless @c minput_driver is set differently, the driver
4228 dependent arguments $ARG of the functions whose name begins with
4229 "minput_" are all ignored. */
4231 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4233 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4235 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4236 \< #Minput_method, $LANGUAGE, $NAME\>
4237 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4239 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4240 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4241 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4242 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4244 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4245 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4247 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4248 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4250 MInputDriver minput_default_driver;
4254 @brief The driver for internal input methods.
4256 The variable #minput_driver is a pointer to the input method
4257 driver that is used by internal input methods. The macro
4258 M17N_INIT () initializes it to a pointer to #minput_default_driver
4259 if <m17n<EM></EM>.h> is included. */
4261 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4263 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4264 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4265 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4266 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4268 MInputDriver *minput_driver;
4270 MSymbol Minput_driver;
4285 @brief Open an input method.
4287 The minput_open_im () function opens an input method whose
4288 language and name match $LANGUAGE and $NAME, and returns a pointer
4289 to the input method object newly allocated.
4291 This function at first decides a driver for the input method as
4294 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4295 #minput_driver is used.
4297 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4298 driver pointed to by the property value is used to open the input
4299 method. If $NAME has no such a property, @c NULL is returned.
4301 Then, the member MInputDriver::open_im () of the driver is
4304 $ARG is set in the member @c arg of the structure MInputMethod so
4305 that the driver can refer to it. */
4307 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4309 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4310 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4312 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4314 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4315 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4317 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4318 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4319 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4321 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4323 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4325 @latexonly \IPAlabel{minput_open} @endlatexonly
4330 minput_open_im (MSymbol language, MSymbol name, void *arg)
4333 MInputDriver *driver;
4337 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4338 msymbol_name (language), msymbol_name (name));
4342 MERROR (MERROR_IM, NULL);
4343 driver = minput_driver;
4347 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4349 MERROR (MERROR_IM, NULL);
4352 MSTRUCT_CALLOC (im, MERROR_IM);
4353 im->language = language;
4356 im->driver = *driver;
4357 if ((*im->driver.open_im) (im) < 0)
4359 MDEBUG_PRINT (" failed\n");
4363 MDEBUG_PRINT (" ok\n");
4370 @brief Close an input method.
4372 The minput_close_im () function closes the input method $IM, which
4373 must have been created by minput_open_im (). */
4376 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4378 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4379 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4382 minput_close_im (MInputMethod *im)
4384 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4385 msymbol_name (im->name), msymbol_name (im->language));
4386 (*im->driver.close_im) (im);
4388 MDEBUG_PRINT (" done\n");
4394 @brief Create an input context.
4396 The minput_create_ic () function creates an input context object
4397 associated with input method $IM, and calls callback functions
4398 corresponding to #Minput_preedit_start, #Minput_status_start, and
4399 #Minput_status_draw in this order.
4402 If an input context is successfully created, minput_create_ic ()
4403 returns a pointer to it. Otherwise it returns @c NULL. */
4406 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4408 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4409 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4410 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4411 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4414 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4415 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4419 minput_create_ic (MInputMethod *im, void *arg)
4423 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4424 msymbol_name (im->name), msymbol_name (im->language));
4425 MSTRUCT_CALLOC (ic, MERROR_IM);
4428 ic->preedit = mtext ();
4429 ic->candidate_list = NULL;
4430 ic->produced = mtext ();
4431 ic->spot.x = ic->spot.y = 0;
4433 ic->plist = mplist ();
4434 if ((*im->driver.create_ic) (ic) < 0)
4436 MDEBUG_PRINT (" failed\n");
4437 M17N_OBJECT_UNREF (ic->preedit);
4438 M17N_OBJECT_UNREF (ic->produced);
4439 M17N_OBJECT_UNREF (ic->plist);
4444 if (im->driver.callback_list)
4446 minput_callback (ic, Minput_preedit_start);
4447 minput_callback (ic, Minput_status_start);
4448 minput_callback (ic, Minput_status_draw);
4451 MDEBUG_PRINT (" ok\n");
4458 @brief Destroy an input context.
4460 The minput_destroy_ic () function destroys the input context $IC,
4461 which must have been created by minput_create_ic (). It calls
4462 callback functions corresponding to #Minput_preedit_done,
4463 #Minput_status_done, and #Minput_candidates_done in this order. */
4466 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4468 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4469 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4470 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4471 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4472 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4476 minput_destroy_ic (MInputContext *ic)
4478 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4479 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4480 if (ic->im->driver.callback_list)
4482 minput_callback (ic, Minput_preedit_done);
4483 minput_callback (ic, Minput_status_done);
4484 minput_callback (ic, Minput_candidates_done);
4486 (*ic->im->driver.destroy_ic) (ic);
4487 M17N_OBJECT_UNREF (ic->preedit);
4488 M17N_OBJECT_UNREF (ic->produced);
4489 M17N_OBJECT_UNREF (ic->plist);
4490 MDEBUG_PRINT (" done\n");
4497 @brief Filter an input key.
4499 The minput_filter () function filters input key $KEY according to
4500 input context $IC, and calls callback functions corresponding to
4501 #Minput_preedit_draw, #Minput_status_draw, and
4502 #Minput_candidates_draw if the preedit text, the status, and the
4503 current candidate are changed respectively.
4505 To make the input method commit the current preedit text (if any)
4506 and shift to the initial state, call this function with #Mnil as
4509 To inform the input method about the focus-out event, call this
4510 function with #Minput_focus_out as $KEY.
4512 To inform the input method about the focus-in event, call this
4513 function with #Minput_focus_in as $KEY.
4515 To inform the input method about the focus-move event (i.e. input
4516 spot change within the same input context), call this function
4517 with #Minput_focus_move as $KEY.
4520 If $KEY is filtered out, this function returns 1. In that case,
4521 the caller should discard the key. Otherwise, it returns 0, and
4522 the caller should handle the key, for instance, by calling the
4523 function minput_lookup () with the same key. */
4526 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4528 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4529 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4530 #Minput_preedit_draw, #Minput_status_draw,
4531 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4534 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4535 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4536 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4537 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4539 @latexonly \IPAlabel{minput_filter} @endlatexonly
4543 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4550 if (ic->im->driver.callback_list
4551 && mtext_nchars (ic->preedit) > 0)
4552 minput_callback (ic, Minput_preedit_draw);
4554 ret = (*ic->im->driver.filter) (ic, key, arg);
4556 if (ic->im->driver.callback_list)
4558 if (ic->preedit_changed)
4559 minput_callback (ic, Minput_preedit_draw);
4560 if (ic->status_changed)
4561 minput_callback (ic, Minput_status_draw);
4562 if (ic->candidates_changed)
4563 minput_callback (ic, Minput_candidates_draw);
4572 @brief Look up a text produced in the input context.
4574 The minput_lookup () function looks up a text in the input context
4575 $IC. $KEY must be identical to the one that was used in the previous call of
4578 If a text was produced by the input method, it is concatenated
4581 This function calls #MInputDriver::lookup .
4584 If $KEY was correctly handled by the input method, this function
4585 returns 0. Otherwise, it returns -1, even though some text
4586 might be produced in $MT. */
4589 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4591 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4592 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4594 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4597 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4600 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4601 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4602 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4604 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4607 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4609 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4614 @brief Set the spot of the input context.
4616 The minput_set_spot () function sets the spot of input context $IC
4617 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4618 The semantics of these values depends on the input method driver.
4620 For instance, a driver designed to work in a CUI environment may
4621 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4622 $DESCENT . A driver designed to work in a window system may
4623 interpret $X and $Y as the pixel offsets relative to the origin of the
4624 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4625 descent pixels of the line at ($X . $Y ).
4627 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4629 $MT and $POS are the M-text and the character position at the spot.
4630 $MT may be @c NULL, in which case, the input method cannot get
4631 information about the text around the spot. */
4634 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4636 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4637 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4638 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4640 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4641 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4642 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4643 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4644 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4645 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4647 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4649 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4650 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4654 minput_set_spot (MInputContext *ic, int x, int y,
4655 int ascent, int descent, int fontsize,
4660 ic->spot.ascent = ascent;
4661 ic->spot.descent = descent;
4662 ic->spot.fontsize = fontsize;
4665 if (ic->im->driver.callback_list)
4666 minput_callback (ic, Minput_set_spot);
4671 @brief Toggle input method.
4673 The minput_toggle () function toggles the input method associated
4674 with input context $IC. */
4676 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4678 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4679 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4683 minput_toggle (MInputContext *ic)
4685 if (ic->im->driver.callback_list)
4686 minput_callback (ic, Minput_toggle);
4687 ic->active = ! ic->active;
4693 @brief Reset an input context.
4695 The minput_reset_ic () function resets input context $IC by
4696 calling a callback function corresponding to #Minput_reset. It
4697 resets the status of $IC to its initial one. As the
4698 current preedit text is deleted without commitment, if necessary,
4699 call minput_filter () with the arg @r key #Mnil to force the input
4700 method to commit the preedit in advance. */
4703 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4705 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4706 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4707 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4708 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4709 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4710 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4713 minput_reset_ic (MInputContext *ic)
4715 if (ic->im->driver.callback_list)
4716 minput_callback (ic, Minput_reset);
4722 @brief Get title and icon filename of an input method.
4724 The minput_get_title_icon () function returns a plist containing a
4725 title and icon filename (if any) of an input method specified by
4726 $LANGUAGE and $NAME.
4728 The first element of the plist has key #Mtext and the value is an
4729 M-text of the title for identifying the input method. The second
4730 element (if any) has key #Mtext and the value is an M-text of the
4731 icon image (absolute) filename for the same purpose.
4734 If there exists a specified input method and it defines an title,
4735 a plist is returned. Otherwise, NULL is returned. The caller
4736 must free the plist by m17n_object_unref (). */
4738 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4740 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4741 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4744 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4745 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4746 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4749 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4750 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4751 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4754 minput_get_title_icon (MSymbol language, MSymbol name)
4756 MInputMethodInfo *im_info;
4763 im_info = get_im_info (language, name, Mnil, Mtitle);
4764 if (! im_info || !im_info->title)
4766 mt = mtext_get_prop (im_info->title, 0, Mtext);
4768 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4771 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4774 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4775 (char *) MSYMBOL_NAME (name));
4776 file = mdatabase__find_file (buf);
4777 if (! file && language == Mt)
4779 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4780 file = mdatabase__find_file (buf);
4785 mplist_add (plist, Mtext, im_info->title);
4788 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4790 mplist_add (plist, Mtext, mt);
4791 M17N_OBJECT_UNREF (mt);
4799 @brief Get description text of an input method.
4801 The minput_get_description () function returns an M-text that
4802 describes the input method specified by $LANGUAGE and $NAME.
4805 If the specified input method has a description text, a pointer to
4806 #MText is returned. The caller has to free it by m17n_object_unref ().
4807 If the input method does not have a description text, @c NULL is
4810 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4812 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4813 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4816 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4817 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4818 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4819 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4822 minput_get_description (MSymbol language, MSymbol name)
4824 MInputMethodInfo *im_info;
4832 extra = language, language = Mt;
4834 im_info = get_im_info (language, name, extra, Mdescription);
4835 if (! im_info || ! im_info->description)
4837 M17N_OBJECT_REF (im_info->description);
4838 return im_info->description;
4844 @brief Get information about input method command(s).
4846 The minput_get_command () function returns information about
4847 the command $COMMAND of the input method specified by $LANGUAGE and
4848 $NAME. An input method command is a pseudo key event to which one
4849 or more actual input key sequences are assigned.
4851 There are two kinds of commands, global and local. A global
4852 command has a global definition, and the description and the key
4853 assignment may be inherited by a local command. Each input method
4854 defines a local command which has a local key assignment. It may
4855 also declare a local command that inherits the definition of a
4856 global command of the same name.
4858 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4859 information about a global command. Otherwise information about a
4860 local command is returned.
4862 If $COMMAND is #Mnil, information about all commands is returned.
4864 The return value is a @e well-formed plist (@ref m17nPlist) of this
4867 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4869 @c NAME is a symbol representing the command name.
4871 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4872 command has no description.
4874 @c STATUS is a symbol representing how the key assignment is decided.
4875 The value is #Mnil (the default key assignment), #Mcustomized (the
4876 key assignment is customized by per-user customization file), or
4877 #Mconfigured (the key assignment is set by the call of
4878 minput_config_command ()). For a local command only, it may also
4879 be #Minherited (the key assignment is inherited from the
4880 corresponding global command).
4882 @c KEYSEQ is a plist of one or more symbols representing a key
4883 sequence assigned to the command. If there's no KEYSEQ, the
4884 command is currently disabled (i.e. no key sequence can trigger
4885 actions of the command).
4887 If $COMMAND is not #Mnil, the first element of the returned plist
4888 contains the information about $COMMAND.
4892 If the requested information was found, a pointer to a non-empty
4893 plist is returned. As the plist is kept in the library, the
4894 caller must not modify nor free it.
4896 Otherwise (the specified input method or the specified command
4897 does not exist), @c NULL is returned. */
4899 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4901 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4902 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4903 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4904 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4906 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4907 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4908 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4909 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4910 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4912 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4913 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4916 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4918 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4921 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4923 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4925 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4928 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4929 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4930 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4931 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4932 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4933 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4936 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4937 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4938 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4939 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4941 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4942 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4946 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4947 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4950 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4955 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4957 /* Return a description of the command COMMAND of the input method
4958 specified by LANGUAGE and NAME. */
4959 MPlist *cmd = minput_get_command (langauge, name, command);
4964 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4965 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4966 return (mplist_key (plist) == Mtext
4967 ? (MText *) mplist_value (plist)
4973 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4975 MInputMethodInfo *im_info;
4979 im_info = get_im_info (language, name, Mnil, Mcommand);
4981 || ! im_info->configured_cmds
4982 || MPLIST_TAIL_P (im_info->configured_cmds))
4984 if (command == Mnil)
4985 return im_info->configured_cmds;
4986 return mplist__assq (im_info->configured_cmds, command);
4992 @brief Configure the key sequence of an input method command.
4994 The minput_config_command () function assigns a list of key
4995 sequences $KEYSEQLIST to the command $COMMAND of the input method
4996 specified by $LANGUAGE and $NAME.
4998 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4999 sequences, and each key sequence must be a plist of symbols.
5001 If $KEYSEQLIST is an empty plist, any configuration and
5002 customization of the command are cancelled, and default key
5003 sequences become effective.
5005 If $KEYSEQLIST is NULL, the configuration of the command is
5006 canceled, and the original key sequences (what saved in per-user
5007 customization file, or the default one) become effective.
5009 In the latter two cases, $COMMAND can be #Mnil to make all the
5010 commands of the input method the target of the operation.
5012 If $NAME is #Mnil, this function configures the key assignment of a
5013 global command, not that of a specific input method.
5015 The configuration takes effect for input methods opened or
5016 re-opened later in the current session. In order to make the
5017 configuration take effect for the future session, it must be saved
5018 in a per-user customization file by the function
5019 minput_save_config ().
5022 If the operation was successful, this function returns 0,
5023 otherwise returns -1. The operation fails in these cases:
5025 <li>$KEYSEQLIST is not in a valid form.
5026 <li>$COMMAND is not available for the input method.
5027 <li>$LANGUAGE and $NAME do not specify an existing input method.
5031 minput_get_commands (), minput_save_config ().
5034 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5036 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5037 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5038 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5040 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5041 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5043 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5044 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5046 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5047 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5048 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5050 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5051 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5053 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5054 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5056 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5057 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5058 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5059 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5063 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5065 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5066 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5067 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5071 minput_get_commands (), minput_save_config ().
5075 /* Add "C-x u" to the "start" command of Unicode input method. */
5077 MSymbol start_command = msymbol ("start");
5078 MSymbol unicode = msymbol ("unicode");
5079 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5081 /* At first get the current key-sequence assignment. */
5082 cmd = minput_get_command (Mt, unicode, start_command);
5085 /* The input method does not have the command "start". Here
5086 should come some error handling code. */
5088 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5089 Extract the part (KEY-SEQUENCE ...). */
5090 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5091 /* Copy it because we should not modify it directly. */
5092 key_seq_list = mplist_copy (plist);
5094 key_seq = mplist ();
5095 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5096 mplist_add (key_seq, Msymbol, msymbol ("u"));
5097 mplist_add (key_seq_list, Mplist, key_seq);
5098 m17n_object_unref (key_seq);
5100 minput_config_command (Mt, unicode, start_command, key_seq_list);
5101 m17n_object_unref (key_seq_list);
5106 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5109 MInputMethodInfo *im_info, *config;
5114 im_info = get_im_info (language, name, Mnil, Mcommand);
5116 MERROR (MERROR_IM, -1);
5117 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5119 || ! mplist__assq (im_info->configured_cmds, command)))
5120 MERROR (MERROR_IM, -1);
5121 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5123 MPLIST_DO (plist, keyseqlist)
5124 if (! check_command_keyseq (plist))
5125 MERROR (MERROR_IM, -1);
5128 config = get_config_info (im_info);
5131 if (! im_config_list)
5132 im_config_list = mplist ();
5133 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5134 config->cmds = mplist ();
5135 config->vars = mplist ();
5138 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5139 /* Nothing to do. */
5142 if (command == Mnil)
5146 /* Cancal the configuration. */
5147 if (MPLIST_TAIL_P (config->cmds))
5149 mplist_set (config->cmds, Mnil, NULL);
5153 /* Cancal the customization. */
5154 MInputMethodInfo *custom = get_custom_info (im_info);
5156 if (MPLIST_TAIL_P (config->cmds)
5157 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5158 /* Nothing to do. */
5160 mplist_set (config->cmds, Mnil, NULL);
5161 MPLIST_DO (plist, custom->cmds)
5163 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5165 mplist_add (plist, Msymbol, command);
5166 mplist_push (config->cmds, Mplist, plist);
5167 M17N_OBJECT_UNREF (plist);
5173 plist = mplist__assq (config->cmds, command);
5176 /* Cancel the configuration. */
5179 mplist__pop_unref (plist);
5181 else if (MPLIST_TAIL_P (keyseqlist))
5183 /* Cancel the customization. */
5184 MInputMethodInfo *custom = get_custom_info (im_info);
5185 int no_custom = (! custom || ! custom->cmds
5186 || ! mplist__assq (custom->cmds, command));
5192 mplist_add (config->cmds, Mplist, plist);
5193 M17N_OBJECT_UNREF (plist);
5194 plist = mplist_add (plist, Msymbol, command);
5199 mplist__pop_unref (plist);
5202 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5203 plist = MPLIST_NEXT (plist);
5204 mplist_set (plist, Mnil, NULL);
5214 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5215 if (! MPLIST_TAIL_P (plist))
5216 mplist_set (plist, Mnil, NULL);
5221 mplist_add (config->cmds, Mplist, plist);
5222 M17N_OBJECT_UNREF (plist);
5223 plist = mplist_add (plist, Msymbol, command);
5224 plist = MPLIST_NEXT (plist);
5226 MPLIST_DO (keyseqlist, keyseqlist)
5228 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5229 plist = mplist_add (plist, Mplist, pl);
5230 M17N_OBJECT_UNREF (pl);
5234 config_all_commands (im_info);
5235 im_info->tick = time (NULL);
5242 @brief Get information about input method variable(s).
5244 The minput_get_variable () function returns information about
5245 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5246 An input method variable controls behavior of an input method.
5248 There are two kinds of variables, global and local. A global
5249 variable has a global definition, and the description and the value
5250 may be inherited by a local variable. Each input method defines a
5251 local variable which has local value. It may also declare a
5252 local variable that inherits definition of a global variable of
5255 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5256 variable is returned. Otherwise information about a local variable
5259 If $VARIABLE is #Mnil, information about all variables is
5262 The return value is a @e well-formed plist (@ref m17nPlist) of this
5265 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5267 @c NAME is a symbol representing the variable name.
5269 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5270 variable has no description.
5272 @c STATUS is a symbol representing how the value is decided. The
5273 value is #Mnil (the default value), #Mcustomized (the value is
5274 customized by per-user customization file), or #Mconfigured (the
5275 value is set by the call of minput_config_variable ()). For a
5276 local variable only, it may also be #Minherited (the value is
5277 inherited from the corresponding global variable).
5279 @c VALUE is the initial value of the variable. If the key of this
5280 element is #Mt, the variable has no initial value. Otherwise, the
5281 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5284 @c VALID-VALUEs (if any) specify which values the variable can have.
5285 They have the same type (i.e. having the same key) as @c VALUE except
5286 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5287 may be a plist of two integers specifying the range of possible
5290 If there no @c VALID-VALUE, the variable can have any value as long
5291 as the type is the same as @c VALUE.
5293 If $VARIABLE is not #Mnil, the first element of the returned plist
5294 contains the information about $VARIABLE.
5298 If the requested information was found, a pointer to a non-empty
5299 plist is returned. As the plist is kept in the library, the
5300 caller must not modify nor free it.
5302 Otherwise (the specified input method or the specified variable
5303 does not exist), @c NULL is returned. */
5305 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5307 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5308 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5309 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5311 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5312 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5313 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5314 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5317 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5318 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5320 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5322 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5324 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5327 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5329 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5332 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5333 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5334 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5335 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5336 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5337 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5339 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5340 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5341 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5343 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5344 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5345 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5346 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5348 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5351 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5352 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5356 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5357 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5360 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5364 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5366 MInputMethodInfo *im_info;
5370 im_info = get_im_info (language, name, Mnil, Mvariable);
5371 if (! im_info || ! im_info->configured_vars)
5373 if (variable == Mnil)
5374 return im_info->configured_vars;
5375 return mplist__assq (im_info->configured_vars, variable);
5381 @brief Configure the value of an input method variable.
5383 The minput_config_variable () function assigns $VALUE to the
5384 variable $VARIABLE of the input method specified by $LANGUAGE and
5387 If $VALUE is a non-empty plist, it must be a plist of one element
5388 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5389 the corresponding type. That value is assigned to the variable.
5391 If $VALUE is an empty plist, any configuration and customization
5392 of the variable are canceled, and the default value is assigned to
5395 If $VALUE is NULL, the configuration of the variable is canceled,
5396 and the original value (what saved in per-user customization file,
5397 or the default value) is assigned to the variable.
5399 In the latter two cases, $VARIABLE can be #Mnil to make all the
5400 variables of the input method the target of the operation.
5402 If $NAME is #Mnil, this function configures the value of global
5403 variable, not that of a specific input method.
5405 The configuration takes effect for input methods opened or
5406 re-opened later in the current session. To make the configuration
5407 take effect for the future session, it must be saved in a per-user
5408 customization file by the function minput_save_config ().
5412 If the operation was successful, this function returns 0,
5413 otherwise returns -1. The operation fails in these cases:
5415 <li>$VALUE is not in a valid form, the type does not match the
5416 definition, or the value is our of range.
5417 <li>$VARIABLE is not available for the input method.
5418 <li>$LANGUAGE and $NAME do not specify an existing input method.
5422 minput_get_variable (), minput_save_config (). */
5424 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5426 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5427 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5429 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5430 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5431 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5433 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5434 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5436 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5437 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5439 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5440 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5442 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5443 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5445 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5446 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5447 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5448 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5452 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5454 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5455 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5456 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5460 minput_get_commands (), minput_save_config ().
5463 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5466 MInputMethodInfo *im_info, *config;
5471 im_info = get_im_info (language, name, Mnil, Mvariable);
5473 MERROR (MERROR_IM, -1);
5474 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5476 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5477 MERROR (MERROR_IM, -1);
5479 if (value && ! MPLIST_TAIL_P (value))
5481 plist = MPLIST_PLIST (plist);
5482 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5483 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5484 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5485 if (MPLIST_KEY (plist) != Mt
5486 && ! check_variable_value (value, plist))
5487 MERROR (MERROR_IM, -1);
5490 config = get_config_info (im_info);
5493 if (! im_config_list)
5494 im_config_list = mplist ();
5495 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5496 config->cmds = mplist ();
5497 config->vars = mplist ();
5500 if (! value && MPLIST_TAIL_P (config->vars))
5501 /* Nothing to do. */
5504 if (variable == Mnil)
5508 /* Cancel the configuration. */
5509 if (MPLIST_TAIL_P (config->vars))
5511 mplist_set (config->vars, Mnil, NULL);
5515 /* Cancel the customization. */
5516 MInputMethodInfo *custom = get_custom_info (im_info);
5518 if (MPLIST_TAIL_P (config->vars)
5519 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5520 /* Nothing to do. */
5522 mplist_set (config->vars, Mnil, NULL);
5523 MPLIST_DO (plist, custom->vars)
5525 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5527 mplist_add (plist, Msymbol, variable);
5528 mplist_push (config->vars, Mplist, plist);
5529 M17N_OBJECT_UNREF (plist);
5535 plist = mplist__assq (config->vars, variable);
5538 /* Cancel the configuration. */
5541 mplist__pop_unref (plist);
5543 else if (MPLIST_TAIL_P (value))
5545 /* Cancel the customization. */
5546 MInputMethodInfo *custom = get_custom_info (im_info);
5547 int no_custom = (! custom || ! custom->vars
5548 || ! mplist__assq (custom->vars, variable));
5554 mplist_add (config->vars, Mplist, plist);
5555 M17N_OBJECT_UNREF (plist);
5556 plist = mplist_add (plist, Msymbol, variable);
5561 mplist__pop_unref (plist);
5564 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5565 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5566 mplist_set (plist, Mnil ,NULL);
5574 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5575 if (! MPLIST_TAIL_P (plist))
5576 mplist_set (plist, Mnil, NULL);
5581 mplist_add (config->vars, Mplist, plist);
5582 M17N_OBJECT_UNREF (plist);
5583 plist = mplist_add (plist, Msymbol, variable);
5584 plist = MPLIST_NEXT (plist);
5586 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5589 config_all_variables (im_info);
5590 im_info->tick = time (NULL);
5597 @brief Get the name of per-user customization file.
5599 The minput_config_file () function returns the absolute path name
5600 of per-user customization file into which minput_save_config ()
5601 save configurations. It is usually @c config.mic under the
5602 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5603 directory). It is not assured that the file of the returned name
5604 exists nor is readable/writable. If minput_save_config () fails
5605 and returns -1, an application program might check the file, make
5606 it writable (if possible), and try minput_save_config () again.
5610 This function returns a string. As the string is kept in the
5611 library, the caller must not modify nor free it.
5614 minput_save_config ()
5617 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5619 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5620 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5621 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5622 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5623 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5624 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5625 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5630 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5631 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5634 minput_save_config ()
5638 minput_config_file ()
5642 return mdatabase__file (im_custom_mdb);
5648 @brief Save configurations in per-user customization file.
5650 The minput_save_config () function saves the configurations done
5651 so far in the current session into the per-user customization
5656 If the operation was successful, 1 is returned. If the per-user
5657 customization file is currently locked, 0 is returned. In that
5658 case, the caller may wait for a while and try again. If the
5659 configuration file is not writable, -1 is returned. In that case,
5660 the caller may check the name of the file by calling
5661 minput_config_file (), make it writable if possible, and try
5665 minput_config_file () */
5667 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5669 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5670 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5674 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5675 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5676 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5677 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5681 minput_config_file () */
5684 minput_save_config (void)
5686 MPlist *data, *tail, *plist, *p, *elt;
5690 ret = mdatabase__lock (im_custom_mdb);
5693 if (! im_config_list)
5695 update_custom_info ();
5696 if (! im_custom_list)
5697 im_custom_list = mplist ();
5699 /* At first, reflect configuration in customization. */
5700 MPLIST_DO (plist, im_config_list)
5702 MPlist *pl = MPLIST_PLIST (plist);
5703 MSymbol language, name, extra, command, variable;
5704 MInputMethodInfo *custom, *config;
5706 language = MPLIST_SYMBOL (pl);
5707 pl = MPLIST_NEXT (pl);
5708 name = MPLIST_SYMBOL (pl);
5709 pl = MPLIST_NEXT (pl);
5710 extra = MPLIST_SYMBOL (pl);
5711 pl = MPLIST_NEXT (pl);
5712 config = MPLIST_VAL (pl);
5713 custom = get_custom_info (config);
5715 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5717 MPLIST_DO (pl, config->cmds)
5719 elt = MPLIST_PLIST (pl);
5720 command = MPLIST_SYMBOL (elt);
5722 p = mplist__assq (custom->cmds, command);
5724 custom->cmds = mplist (), p = NULL;
5725 elt = MPLIST_NEXT (elt);
5728 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5729 mplist_set (p, Mnil, NULL);
5734 mplist_add (custom->cmds, Mplist, p);
5735 M17N_OBJECT_UNREF (p);
5736 mplist_add (p, Msymbol, command);
5737 p = mplist_add (p, Msymbol, Mnil);
5738 p = MPLIST_NEXT (p);
5740 mplist__conc (p, elt);
5743 MPLIST_DO (pl, config->vars)
5745 elt = MPLIST_PLIST (pl);
5746 variable = MPLIST_SYMBOL (elt);
5748 p = mplist__assq (custom->vars, variable);
5750 custom->vars = mplist (), p = NULL;
5751 elt = MPLIST_NEXT (elt);
5754 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5755 mplist_set (p, Mnil, NULL);
5760 mplist_add (custom->vars, Mplist, p);
5761 M17N_OBJECT_UNREF (p);
5762 mplist_add (p, Msymbol, variable);
5763 p = mplist_add (p, Msymbol, Mnil);
5764 p = MPLIST_NEXT (p);
5766 mplist__conc (p, elt);
5769 free_im_list (im_config_list);
5770 im_config_list = NULL;
5772 /* Next, reflect customization to the actual plist to be written. */
5773 data = tail = mplist ();
5774 MPLIST_DO (plist, im_custom_list)
5776 MPlist *pl = MPLIST_PLIST (plist);
5777 MSymbol language, name, extra;
5778 MInputMethodInfo *custom, *im_info;
5780 language = MPLIST_SYMBOL (pl);
5781 pl = MPLIST_NEXT (pl);
5782 name = MPLIST_SYMBOL (pl);
5783 pl = MPLIST_NEXT (pl);
5784 extra = MPLIST_SYMBOL (pl);
5785 pl = MPLIST_NEXT (pl);
5786 custom = MPLIST_VAL (pl);
5787 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5788 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5790 im_info = lookup_im_info (im_info_list, language, name, extra);
5794 config_all_commands (im_info);
5796 config_all_variables (im_info);
5800 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5802 MPLIST_DO (p, custom->cmds)
5803 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5805 if (! MPLIST_TAIL_P (p))
5809 mplist_add (elt, Mplist, pl);
5810 M17N_OBJECT_UNREF (pl);
5811 pl = mplist_add (pl, Msymbol, Mcommand);
5812 MPLIST_DO (p, custom->cmds)
5813 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5814 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5817 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5819 MPLIST_DO (p, custom->vars)
5820 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5822 if (! MPLIST_TAIL_P (p))
5827 mplist_add (elt, Mplist, pl);
5828 M17N_OBJECT_UNREF (pl);
5829 pl = mplist_add (pl, Msymbol, Mvariable);
5830 MPLIST_DO (p, custom->vars)
5831 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5832 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5838 mplist_push (elt, Mplist, pl);
5839 M17N_OBJECT_UNREF (pl);
5840 pl = mplist_add (pl, Msymbol, Minput_method);
5841 pl = mplist_add (pl, Msymbol, language);
5842 pl = mplist_add (pl, Msymbol, name);
5844 pl = mplist_add (pl, Msymbol, extra);
5845 tail = mplist_add (tail, Mplist, elt);
5846 M17N_OBJECT_UNREF (elt);
5850 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5851 ret = mdatabase__save (im_custom_mdb, data);
5852 mdatabase__unlock (im_custom_mdb);
5853 M17N_OBJECT_UNREF (data);
5854 return (ret < 0 ? -1 : 1);
5861 @name Obsolete functions
5864 @name Obsolete ¤Ê´Ø¿ô
5870 @brief Get a list of variables of an input method (obsolete).
5872 This function is obsolete. Use minput_get_variable () instead.
5874 The minput_get_variables () function returns a plist (#MPlist) of
5875 variables used to control the behavior of the input method
5876 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5877 (@ref m17nPlist) of the following format:
5880 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5881 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5885 @c VARNAME is a symbol representing the variable name.
5887 @c DOC-MTEXT is an M-text describing the variable.
5889 @c DEFAULT-VALUE is the default value of the variable. It is a
5890 symbol, integer, or M-text.
5892 @c VALUEs (if any) specifies the possible values of the variable.
5893 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5894 @c TO), where @c FROM and @c TO specifies a range of possible
5897 For instance, suppose an input method has the variables:
5899 @li name:intvar, description:"value is an integer",
5900 initial value:0, value-range:0..3,10,20
5902 @li name:symvar, description:"value is a symbol",
5903 initial value:nil, value-range:a, b, c, nil
5905 @li name:txtvar, description:"value is an M-text",
5906 initial value:empty text, no value-range (i.e. any text)
5908 Then, the returned plist is as follows.
5911 (intvar ("value is an integer" 0 (0 3) 10 20)
5912 symvar ("value is a symbol" nil a b c nil)
5913 txtvar ("value is an M-text" ""))
5917 If the input method uses any variables, a pointer to #MPlist is
5918 returned. As the plist is kept in the library, the caller must not
5919 modify nor free it. If the input method does not use any
5920 variable, @c NULL is returned. */
5922 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5924 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5925 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5926 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5930 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5931 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5935 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5937 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5939 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5942 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5943 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5944 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5946 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5948 @li name:intvar, ÀâÌÀ:"value is an integer",
5949 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5951 @li name:symvar, ÀâÌÀ:"value is a symbol",
5952 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5954 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5955 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5957 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5960 (intvar ("value is an integer" 0 (0 3) 10 20)
5961 symvar ("value is a symbol" nil a b c nil)
5962 txtvar ("value is an M-text" ""))
5966 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5967 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5968 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5971 minput_get_variables (MSymbol language, MSymbol name)
5973 MInputMethodInfo *im_info;
5978 im_info = get_im_info (language, name, Mnil, Mvariable);
5979 if (! im_info || ! im_info->configured_vars)
5982 M17N_OBJECT_UNREF (im_info->bc_vars);
5983 im_info->bc_vars = mplist ();
5984 MPLIST_DO (vars, im_info->configured_vars)
5986 MPlist *plist = MPLIST_PLIST (vars);
5987 MPlist *elt = mplist ();
5989 mplist_push (im_info->bc_vars, Mplist, elt);
5990 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5991 elt = MPLIST_NEXT (elt);
5992 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5993 M17N_OBJECT_UNREF (elt);
5995 return im_info->bc_vars;
6001 @brief Set the initial value of an input method variable.
6003 The minput_set_variable () function sets the initial value of
6004 input method variable $VARIABLE to $VALUE for the input method
6005 specified by $LANGUAGE and $NAME.
6007 By default, the initial value is 0.
6009 This setting gets effective in a newly opened input method.
6012 If the operation was successful, 0 is returned. Otherwise -1 is
6013 returned, and #merror_code is set to #MERROR_IM. */
6015 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6017 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6018 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6019 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6021 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6023 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6026 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6027 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6030 minput_set_variable (MSymbol language, MSymbol name,
6031 MSymbol variable, void *value)
6034 MInputMethodInfo *im_info;
6039 if (variable == Mnil)
6040 MERROR (MERROR_IM, -1);
6041 plist = minput_get_variable (language, name, variable);
6042 plist = MPLIST_PLIST (plist);
6043 plist = MPLIST_NEXT (plist);
6045 mplist_add (pl, MPLIST_KEY (plist), value);
6046 ret = minput_config_variable (language, name, variable, pl);
6047 M17N_OBJECT_UNREF (pl);
6050 im_info = get_im_info (language, name, Mnil, Mvariable);
6059 @brief Get information about input method commands.
6061 The minput_get_commands () function returns information about
6062 input method commands of the input method specified by $LANGUAGE
6063 and $NAME. An input method command is a pseudo key event to which
6064 one or more actual input key sequences are assigned.
6066 There are two kinds of commands, global and local. Global
6067 commands are used by multiple input methods for the same purpose,
6068 and have global key assignments. Local commands are used only by
6069 a specific input method, and have only local key assignments.
6071 Each input method may locally change key assignments for global
6072 commands. The global key assignment for a global command is
6073 effective only when the current input method does not have local
6074 key assignments for that command.
6076 If $NAME is #Mnil, information about global commands is returned.
6077 In this case $LANGUAGE is ignored.
6079 If $NAME is not #Mnil, information about those commands that have
6080 local key assignments in the input method specified by $LANGUAGE
6081 and $NAME is returned.
6084 If no input method commands are found, this function returns @c NULL.
6086 Otherwise, a pointer to a plist is returned. The key of each
6087 element in the plist is a symbol representing a command, and the
6088 value is a plist of the form COMMAND-INFO described below.
6090 The first element of COMMAND-INFO has the key #Mtext, and the
6091 value is an M-text describing the command.
6093 If there are no more elements, that means no key sequences are
6094 assigned to the command. Otherwise, each of the remaining
6095 elements has the key #Mplist, and the value is a plist whose keys are
6096 #Msymbol and values are symbols representing input keys, which are
6097 currently assigned to the command.
6099 As the returned plist is kept in the library, the caller must not
6100 modify nor free it. */
6102 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6104 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6105 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6106 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6107 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6109 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6110 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6111 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6112 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6114 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6115 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6116 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6119 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6120 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6122 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6123 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6127 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6129 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6130 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6131 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6133 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6134 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6135 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6138 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6139 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6140 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6141 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6142 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6144 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6145 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6148 minput_get_commands (MSymbol language, MSymbol name)
6150 MInputMethodInfo *im_info;
6155 im_info = get_im_info (language, name, Mnil, Mcommand);
6156 if (! im_info || ! im_info->configured_vars)
6158 M17N_OBJECT_UNREF (im_info->bc_cmds);
6159 im_info->bc_cmds = mplist ();
6160 MPLIST_DO (cmds, im_info->configured_cmds)
6162 MPlist *plist = MPLIST_PLIST (cmds);
6163 MPlist *elt = mplist ();
6165 mplist_push (im_info->bc_cmds, Mplist, elt);
6166 mplist_add (elt, MPLIST_SYMBOL (plist),
6167 mplist_copy (MPLIST_NEXT (plist)));
6168 M17N_OBJECT_UNREF (elt);
6170 return im_info->bc_cmds;
6176 @brief Assign a key sequence to an input method command (obsolete).
6178 This function is obsolete. Use minput_config_command () instead.
6180 The minput_assign_command_keys () function assigns input key
6181 sequence $KEYSEQ to input method command $COMMAND for the input
6182 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6183 key sequence is assigned globally no matter what $LANGUAGE is.
6184 Otherwise the key sequence is assigned locally.
6186 Each element of $KEYSEQ must have the key $Msymbol and the value
6187 must be a symbol representing an input key.
6189 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6190 globally or locally.
6192 This assignment gets effective in a newly opened input method.
6195 If the operation was successful, 0 is returned. Otherwise -1 is
6196 returned, and #merror_code is set to #MERROR_IM. */
6198 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6200 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6201 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6202 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6203 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6204 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6206 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6207 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6209 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6210 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6212 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6216 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6217 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6220 minput_assign_command_keys (MSymbol language, MSymbol name,
6221 MSymbol command, MPlist *keyseq)
6227 if (command == Mnil)
6228 MERROR (MERROR_IM, -1);
6233 if (! check_command_keyseq (keyseq))
6234 MERROR (MERROR_IM, -1);
6236 mplist_add (plist, Mplist, keyseq);
6241 ret = minput_config_command (language, name, command, keyseq);
6242 M17N_OBJECT_UNREF (keyseq);
6249 @brief Call a callback function
6251 The minput_callback () functions calls a callback function
6252 $COMMAND assigned for the input context $IC. The caller must set
6253 specific elements in $IC->plist if the callback function requires.
6256 If there exists a specified callback function, 0 is returned.
6257 Otherwise -1 is returned. By side effects, $IC->plist may be
6261 minput_callback (MInputContext *ic, MSymbol command)
6263 MInputCallbackFunc func;
6265 if (! ic->im->driver.callback_list)
6267 func = ((MInputCallbackFunc)
6268 mplist_get_func (ic->im->driver.callback_list, command));
6271 (func) (ic, command);
6278 /*** @addtogroup m17nDebug */
6284 @brief Dump an input method.
6286 The mdebug_dump_im () function prints the input method $IM in a
6287 human readable way to the stderr. $INDENT specifies how many
6288 columns to indent the lines but the first one.
6291 This function returns $IM. */
6293 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6295 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6296 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6299 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6302 mdebug_dump_im (MInputMethod *im, int indent)
6304 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6307 prefix = (char *) alloca (indent + 1);
6308 memset (prefix, 32, indent);
6309 prefix[indent] = '\0';
6311 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6312 msymbol_name (im->name));
6313 mdebug_dump_mtext (im_info->title, 0, 0);
6314 if (im->name != Mnil)
6318 MPLIST_DO (state, im_info->states)
6320 fprintf (stderr, "\n%s ", prefix);
6321 dump_im_state (MPLIST_VAL (state), indent + 2);
6324 fprintf (stderr, ")");