1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32], buf3[2];
284 /* Maximum case: '\215', C-M-m, C-M-M, M-Return, C-A-m, C-A-M, A-Return. */
287 M_key_alias = msymbol (" key-alias");
291 /* Aliases for 0x00-0x1F */
295 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
299 alias[j++] = msymbol (buf3);
300 alias[j++] = one_char_symbol[i] = msymbol (buf);
301 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
305 /* Ex: `Escape' == `C-[' */
306 alias[j++] = msymbol (key_names[i]);
308 if (buf[2] >= 'A' && buf[2] <= 'Z')
310 /* Ex: `C-a' == `C-A' */
312 alias[j++] = msymbol (buf);
316 /* Establish cyclic alias chain. */
319 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
322 /* Aliases for 0x20-0x7E */
324 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
326 one_char_symbol[i] = msymbol (buf + 2);
327 if (i >= 'A' && i <= 'Z')
329 /* Ex: `A' == `S-A' == `S-a'. */
330 alias[0] = alias[3] = one_char_symbol[i];
331 alias[1] = msymbol (buf);
333 alias[2] = msymbol (buf);
335 for (j = 0; j < 3; j++)
336 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
340 /* Aliases for 0x7F */
342 alias[0] = alias[3] = msymbol (buf3);
343 alias[1] = one_char_symbol[127] = msymbol ("Delete");
344 alias[2] = msymbol ("C-?");
345 for (j = 0; j < 3; j++)
346 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
348 /* Aliases for 0x80-0x9F */
350 /* buf[1] = '-'; -- already done */
354 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
358 alias[j++] = msymbol (buf3);
359 /* `C-M-a' == `C-A-a' */
361 alias[j++] = one_char_symbol[i] = msymbol (buf);
363 alias[j++] = msymbol (buf);
364 if (key_names[i - 128])
366 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
368 strcpy (buf2 + 2, key_names[i - 128]);
369 alias[j++] = msymbol (buf2);
371 alias[j++] = msymbol (buf2);
373 if (buf[4] >= 'A' && buf[4] <= 'Z')
375 /* Ex: `C-M-a' == `C-M-A'. */
378 alias[j++] = msymbol (buf);
380 alias[j++] = msymbol (buf);
384 /* Establish cyclic alias chain. */
387 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
390 /* Aliases for 0xA0-0xFF */
391 for (i = 160, buf[4] = ' '; i < 255; i++, buf[4]++)
395 alias[j++] = msymbol (buf3);
397 alias[j++] = one_char_symbol[i] = msymbol (buf + 2);
399 alias[j++] = msymbol (buf + 2);
402 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
406 alias[0] = alias[3] = msymbol (buf3);
407 alias[1] = one_char_symbol[255] = msymbol ("M-Delete");
408 alias[2] = msymbol ("A-Delete");
409 for (j = 0; j < 3; j++)
410 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
412 /* Aliases for keys that can't be mapped to one-char-symbol
414 /* buf is already set to "C-?-". */
415 for (i = ' '; i <= '~'; i++)
429 alias[0] = alias[2] = msymbol (buf);
431 alias[1] = msymbol (buf);
432 for (j = 0; j < 2; j++)
433 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
436 Minput_method = msymbol ("input-method");
437 Mtitle = msymbol ("title");
438 Mmacro = msymbol ("macro");
439 Mmodule = msymbol ("module");
440 Mmap = msymbol ("map");
441 Mstate = msymbol ("state");
442 Minclude = msymbol ("include");
443 Minsert = msymbol ("insert");
444 M_candidates = msymbol (" candidates");
445 Mdelete = msymbol ("delete");
446 Mmove = msymbol ("move");
447 Mmark = msymbol ("mark");
448 Mpushback = msymbol ("pushback");
449 Mpop = msymbol ("pop");
450 Mundo = msymbol ("undo");
451 Mcall = msymbol ("call");
452 Mshift = msymbol ("shift");
453 Mselect = msymbol ("select");
454 Mshow = msymbol ("show");
455 Mhide = msymbol ("hide");
456 Mcommit = msymbol ("commit");
457 Munhandle = msymbol ("unhandle");
458 Mset = msymbol ("set");
459 Madd = msymbol ("add");
460 Msub = msymbol ("sub");
461 Mmul = msymbol ("mul");
462 Mdiv = msymbol ("div");
463 Mequal = msymbol ("=");
464 Mless = msymbol ("<");
465 Mgreater = msymbol (">");
466 Mless_equal = msymbol ("<=");
467 Mgreater_equal = msymbol (">=");
468 Mcond = msymbol ("cond");
469 Mplus = msymbol ("+");
470 Mminus = msymbol ("-");
471 Mstar = msymbol ("*");
472 Mslash = msymbol ("/");
473 Mand = msymbol ("&");
475 Mnot = msymbol ("!");
477 Mat_reload = msymbol ("@reload");
479 Mcandidates_group_size = msymbol ("candidates-group-size");
480 Mcandidates_charset = msymbol ("candidates-charset");
482 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
483 Mcandidate_index = msymbol (" candidate-index");
485 Minit = msymbol ("init");
486 Mfini = msymbol ("fini");
488 Mdescription = msymbol ("description");
489 Mcommand = msymbol ("command");
490 Mvariable = msymbol ("variable");
491 Mglobal = msymbol ("global");
492 Mconfig = msymbol ("config");
493 M_gettext = msymbol ("_");
495 load_im_info_keys = mplist ();
496 mplist_add (load_im_info_keys, Mstate, Mnil);
497 mplist_push (load_im_info_keys, Mmap, Mnil);
499 im_info_list = mplist ();
500 im_config_list = im_custom_list = NULL;
501 im_custom_mdb = NULL;
502 update_custom_info ();
504 update_global_info ();
506 fully_initialized = 1;
509 #define MINPUT__INIT() \
511 if (! fully_initialized) \
512 fully_initialize (); \
517 marker_code (MSymbol sym, int surrounding)
523 name = MSYMBOL_NAME (sym);
524 return (name[0] != '@' ? -1
525 : (((name[1] >= '0' && name[1] <= '9')
526 || name[1] == '<' || name[1] == '>' || name[1] == '='
527 || name[1] == '[' || name[1] == ']'
529 && name[2] == '\0') ? name[1]
530 : (name[1] != '+' && name[1] != '-') ? -1
531 : (name[2] == '\0' || surrounding) ? name[1]
536 /* Return a plist containing an integer value of VAR. */
539 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
541 MPlist *plist = mplist__assq (ic_info->vars, var);
545 plist = MPLIST_PLIST (plist);
546 return MPLIST_NEXT (plist);
550 mplist_push (ic_info->vars, Mplist, plist);
551 M17N_OBJECT_UNREF (plist);
552 plist = mplist_add (plist, Msymbol, var);
553 plist = mplist_add (plist, Minteger, (void *) 0);
558 get_surrounding_text (MInputContext *ic, int len)
562 mplist_push (ic->plist, Minteger, (void *) len);
563 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
564 && MPLIST_MTEXT_P (ic->plist))
565 mt = MPLIST_MTEXT (ic->plist);
566 mplist_pop (ic->plist);
571 delete_surrounding_text (MInputContext *ic, int pos)
573 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
575 mplist_push (ic->plist, Minteger, (void *) pos);
576 minput_callback (ic, Minput_delete_surrounding_text);
577 mplist_pop (ic->plist);
580 M17N_OBJECT_UNREF (ic_info->preceding_text);
581 ic_info->preceding_text = NULL;
585 M17N_OBJECT_UNREF (ic_info->following_text);
586 ic_info->following_text = NULL;
591 get_preceding_char (MInputContext *ic, int pos)
593 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
597 if (pos && ic_info->preceding_text)
599 len = mtext_nchars (ic_info->preceding_text);
601 return mtext_ref_char (ic_info->preceding_text, len - pos);
603 mt = get_surrounding_text (ic, - pos);
606 len = mtext_nchars (mt);
607 if (ic_info->preceding_text)
609 if (mtext_nchars (ic_info->preceding_text) < len)
611 M17N_OBJECT_UNREF (ic_info->preceding_text);
612 ic_info->preceding_text = mt;
615 M17N_OBJECT_UNREF (mt);
618 ic_info->preceding_text = mt;
621 return mtext_ref_char (ic_info->preceding_text, len - pos);
625 get_following_char (MInputContext *ic, int pos)
627 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
631 if (ic_info->following_text)
633 len = mtext_nchars (ic_info->following_text);
635 return mtext_ref_char (ic_info->following_text, pos);
637 mt = get_surrounding_text (ic, pos + 1);
640 len = mtext_nchars (mt);
641 if (ic_info->following_text)
643 if (mtext_nchars (ic_info->following_text) < len)
645 M17N_OBJECT_UNREF (ic_info->following_text);
646 ic_info->following_text = mt;
649 M17N_OBJECT_UNREF (mt);
652 ic_info->following_text = mt;
655 return mtext_ref_char (ic_info->following_text, pos);
659 surrounding_pos (MSymbol sym)
665 name = MSYMBOL_NAME (sym);
667 && (name[1] == '-' || name[1] == '+')
668 && name[2] >= '1' && name[2] <= '9')
669 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
674 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
676 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
678 MText *preedit = ic->preedit;
679 int len = mtext_nchars (preedit);
681 if (MPLIST_INTEGER_P (arg))
682 return MPLIST_INTEGER (arg);
684 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
687 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
689 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
692 return ic_info->key_head;
693 if ((code == '-' || code == '+'))
695 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
699 pos = atoi (name + 1);
701 return get_preceding_char (ic, 0);
703 pos = ic->cursor_pos + pos;
705 pos = ic->cursor_pos + pos - 1;
708 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
709 return mtext_ref_char (ic->produced,
710 mtext_len (ic->produced) + pos);
711 return get_preceding_char (ic, - pos);
714 return get_following_char (ic, pos - len);
717 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
719 else if (code >= '0' && code <= '9')
721 else if (code == '=')
722 pos = ic->cursor_pos;
723 else if (code == '[')
724 pos = ic->cursor_pos - 1;
725 else if (code == ']')
726 pos = ic->cursor_pos + 1;
727 else if (code == '<')
729 else if (code == '>')
731 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
735 parse_expression (MPlist *plist)
739 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
741 if (! MPLIST_PLIST_P (plist))
743 plist = MPLIST_PLIST (plist);
744 op = MPLIST_SYMBOL (plist);
745 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
746 && op != Mand && op != Mor && op != Mnot
747 && op != Mless && op != Mgreater && op != Mequal
748 && op != Mless_equal && op != Mgreater_equal)
749 MERROR (MERROR_IM, -1);
750 MPLIST_DO (plist, MPLIST_NEXT (plist))
751 if (parse_expression (plist) < 0)
757 resolve_expression (MInputContext *ic, MPlist *plist)
762 if (MPLIST_INTEGER_P (plist))
763 return MPLIST_INTEGER (plist);
764 if (MPLIST_SYMBOL_P (plist))
765 return integer_value (ic, plist, 1);
766 if (! MPLIST_PLIST_P (plist))
768 plist = MPLIST_PLIST (plist);
769 if (! MPLIST_SYMBOL_P (plist))
771 op = MPLIST_SYMBOL (plist);
772 plist = MPLIST_NEXT (plist);
773 val = resolve_expression (ic, plist);
775 MPLIST_DO (plist, MPLIST_NEXT (plist))
776 val += resolve_expression (ic, plist);
777 else if (op == Mminus)
778 MPLIST_DO (plist, MPLIST_NEXT (plist))
779 val -= resolve_expression (ic, plist);
780 else if (op == Mstar)
781 MPLIST_DO (plist, MPLIST_NEXT (plist))
782 val *= resolve_expression (ic, plist);
783 else if (op == Mslash)
784 MPLIST_DO (plist, MPLIST_NEXT (plist))
785 val /= resolve_expression (ic, plist);
787 MPLIST_DO (plist, MPLIST_NEXT (plist))
788 val &= resolve_expression (ic, plist);
790 MPLIST_DO (plist, MPLIST_NEXT (plist))
791 val |= resolve_expression (ic, plist);
794 else if (op == Mless)
795 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
796 else if (op == Mequal)
797 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
798 else if (op == Mgreater)
799 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
800 else if (op == Mless_equal)
801 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
802 else if (op == Mgreater_equal)
803 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
807 /* Parse PLIST as an action list. PLIST should have this form:
808 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
809 Return 0 if successfully parsed, otherwise return -1. */
812 parse_action_list (MPlist *plist, MPlist *macros)
814 MPLIST_DO (plist, plist)
816 if (MPLIST_MTEXT_P (plist))
818 /* This is a short form of (insert MTEXT). */
819 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
820 MERROR (MERROR_IM, -1); */
822 else if (MPLIST_PLIST_P (plist)
823 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
824 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
828 /* This is a short form of (insert (GROUPS *)). */
829 MPLIST_DO (pl, MPLIST_PLIST (plist))
831 if (MPLIST_PLIST_P (pl))
835 MPLIST_DO (elt, MPLIST_PLIST (pl))
836 if (! MPLIST_MTEXT_P (elt)
837 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
838 MERROR (MERROR_IM, -1);
842 if (! MPLIST_MTEXT_P (pl)
843 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
844 MERROR (MERROR_IM, -1);
848 else if (MPLIST_INTEGER_P (plist))
850 int c = MPLIST_INTEGER (plist);
852 if (c < 0 || c > MCHAR_MAX)
853 MERROR (MERROR_IM, -1);
855 else if (MPLIST_PLIST_P (plist)
856 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
858 MPlist *pl = MPLIST_PLIST (plist);
859 MSymbol action_name = MPLIST_SYMBOL (pl);
861 pl = MPLIST_NEXT (pl);
863 if (action_name == M_candidates)
865 /* This is an already regularised action. */
868 if (action_name == Minsert)
870 if (MPLIST_MTEXT_P (pl))
872 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
873 MERROR (MERROR_IM, -1);
875 else if (MPLIST_INTEGER_P (pl))
877 int c = MPLIST_INTEGER (pl);
879 if (c < 0 || c > MCHAR_MAX)
880 MERROR (MERROR_IM, -1);
882 else if (MPLIST_PLIST_P (pl))
884 MPLIST_DO (pl, MPLIST_PLIST (pl))
886 if (MPLIST_PLIST_P (pl))
890 MPLIST_DO (elt, MPLIST_PLIST (pl))
891 if (! MPLIST_MTEXT_P (elt)
892 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
893 MERROR (MERROR_IM, -1);
897 if (! MPLIST_MTEXT_P (pl)
898 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
899 MERROR (MERROR_IM, -1);
903 else if (! MPLIST_SYMBOL_P (pl))
904 MERROR (MERROR_IM, -1);
906 else if (action_name == Mselect
907 || action_name == Mdelete
908 || action_name == Mmove)
910 if (parse_expression (pl) < 0)
913 else if (action_name == Mmark
914 || action_name == Mcall
915 || action_name == Mshift)
917 if (! MPLIST_SYMBOL_P (pl))
918 MERROR (MERROR_IM, -1);
920 else if (action_name == Mundo)
922 if (! MPLIST_TAIL_P (pl))
924 if (! MPLIST_SYMBOL_P (pl)
925 && ! MPLIST_INTEGER_P (pl))
926 MERROR (MERROR_IM, -1);
929 else if (action_name == Mpushback)
931 if (MPLIST_MTEXT_P (pl))
933 MText *mt = MPLIST_MTEXT (pl);
935 if (mtext_nchars (mt) != mtext_nbytes (mt))
936 MERROR (MERROR_IM, -1);
938 else if (MPLIST_PLIST_P (pl))
942 MPLIST_DO (p, MPLIST_PLIST (pl))
943 if (! MPLIST_SYMBOL_P (p))
944 MERROR (MERROR_IM, -1);
946 else if (! MPLIST_INTEGER_P (pl))
947 MERROR (MERROR_IM, -1);
949 else if (action_name == Mset || action_name == Madd
950 || action_name == Msub || action_name == Mmul
951 || action_name == Mdiv)
953 if (! MPLIST_SYMBOL_P (pl))
954 MERROR (MERROR_IM, -1);
955 if (parse_expression (MPLIST_NEXT (pl)) < 0)
958 else if (action_name == Mequal || action_name == Mless
959 || action_name == Mgreater || action_name == Mless_equal
960 || action_name == Mgreater_equal)
962 if (parse_expression (pl) < 0
963 || parse_expression (MPLIST_NEXT (pl)) < 0)
965 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
966 if (! MPLIST_PLIST_P (pl))
967 MERROR (MERROR_IM, -1);
968 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
969 MERROR (MERROR_IM, -1);
970 pl = MPLIST_NEXT (pl);
971 if (MPLIST_PLIST_P (pl)
972 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
973 MERROR (MERROR_IM, -1);
975 else if (action_name == Mshow || action_name == Mhide
976 || action_name == Mcommit || action_name == Munhandle
977 || action_name == Mpop)
979 else if (action_name == Mcond)
982 if (! MPLIST_PLIST_P (pl))
983 MERROR (MERROR_IM, -1);
985 else if (! macros || ! mplist_get (macros, action_name))
986 MERROR (MERROR_IM, -1);
988 else if (! MPLIST_SYMBOL_P (plist))
989 MERROR (MERROR_IM, -1);
996 resolve_command (MPlist *cmds, MSymbol command)
1000 if (! cmds || ! (plist = mplist__assq (cmds, command)))
1002 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
1003 plist = MPLIST_NEXT (plist);
1004 plist = MPLIST_NEXT (plist);
1005 plist = MPLIST_NEXT (plist);
1009 /* Load a translation into MAP from PLIST.
1010 PLIST has this form:
1011 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
1014 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
1015 MPlist *branch_actions, MPlist *macros)
1020 if (MPLIST_MTEXT_P (keylist))
1022 MText *mt = MPLIST_MTEXT (keylist);
1024 len = mtext_nchars (mt);
1025 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
1027 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1028 for (i = 0; i < len; i++)
1029 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1035 if (MFAILP (MPLIST_PLIST_P (keylist)))
1037 elt = MPLIST_PLIST (keylist);
1038 len = MPLIST_LENGTH (elt);
1039 if (MFAILP (len > 0))
1041 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1042 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1044 if (MPLIST_INTEGER_P (elt))
1046 int c = MPLIST_INTEGER (elt);
1048 if (MFAILP (c >= 0 && c < 0x100))
1050 keyseq[i] = one_char_symbol[c];
1054 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1056 keyseq[i] = MPLIST_SYMBOL (elt);
1061 for (i = 0; i < len; i++)
1063 MIMMap *deeper = NULL;
1066 deeper = mplist_get (map->submaps, keyseq[i]);
1068 map->submaps = mplist ();
1071 /* Fixme: It is better to make all deeper maps at once. */
1072 MSTRUCT_CALLOC (deeper, MERROR_IM);
1073 mplist_put (map->submaps, keyseq[i], deeper);
1078 /* We reach a terminal map. */
1079 if (map->map_actions
1080 || map->branch_actions)
1081 /* This map is already defined. We avoid overriding it. */
1084 if (! MPLIST_TAIL_P (map_actions))
1086 if (parse_action_list (map_actions, macros) < 0)
1087 MERROR (MERROR_IM, -1);
1088 map->map_actions = map_actions;
1092 map->branch_actions = branch_actions;
1093 M17N_OBJECT_REF (branch_actions);
1099 /* Load a branch from PLIST into MAP. PLIST has this form:
1100 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1103 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1106 MPlist *branch_actions;
1108 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1110 map_name = MPLIST_SYMBOL (plist);
1111 plist = MPLIST_NEXT (plist);
1112 if (MPLIST_TAIL_P (plist))
1113 branch_actions = NULL;
1114 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1117 branch_actions = plist;
1118 if (map_name == Mnil)
1120 map->branch_actions = branch_actions;
1122 M17N_OBJECT_REF (branch_actions);
1124 else if (map_name == Mt)
1126 map->map_actions = branch_actions;
1128 M17N_OBJECT_REF (branch_actions);
1130 else if (im_info->maps)
1132 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1133 if (! plist && im_info->configured_vars)
1135 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1137 if (p && MPLIST_PLIST_P (p))
1139 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1140 if (MPLIST_SYMBOL_P (p))
1141 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1146 MPLIST_DO (plist, plist)
1148 MPlist *keylist, *map_actions;
1150 if (! MPLIST_PLIST_P (plist))
1151 MERROR (MERROR_IM, -1);
1152 keylist = MPLIST_PLIST (plist);
1153 map_actions = MPLIST_NEXT (keylist);
1154 if (MPLIST_SYMBOL_P (keylist))
1156 MSymbol command = MPLIST_SYMBOL (keylist);
1159 if (MFAILP (command != Mat_reload))
1161 pl = resolve_command (im_info->configured_cmds, command);
1165 load_translation (map, pl, map_actions, branch_actions,
1169 load_translation (map, keylist, map_actions, branch_actions,
1178 /* Load a macro from PLIST into IM_INFO->macros.
1179 PLIST has this from:
1180 PLIST ::= ( MACRO-NAME ACTION * )
1181 IM_INFO->macros is a plist of macro names vs action list. */
1184 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1189 if (! MPLIST_SYMBOL_P (plist))
1190 MERROR (MERROR_IM, -1);
1191 name = MPLIST_SYMBOL (plist);
1192 plist = MPLIST_NEXT (plist);
1193 if (MPLIST_TAIL_P (plist)
1194 || parse_action_list (plist, im_info->macros) < 0)
1195 MERROR (MERROR_IM, -1);
1196 pl = mplist_get (im_info->macros, name);
1197 M17N_OBJECT_UNREF (pl);
1198 mplist_put (im_info->macros, name, plist);
1199 M17N_OBJECT_REF (plist);
1203 /* Load an external module from PLIST into IM_INFO->externals.
1204 PLIST has this form:
1205 PLIST ::= ( MODULE-NAME FUNCTION * )
1206 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1209 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1214 MIMExternalModule *external;
1218 if (MPLIST_MTEXT_P (plist))
1219 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1220 else if (MPLIST_SYMBOL_P (plist))
1221 module = MPLIST_SYMBOL (plist);
1222 module_file = alloca (strlen (MSYMBOL_NAME (module))
1223 + strlen (DLOPEN_SHLIB_EXT) + 1);
1224 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1226 handle = dlopen (module_file, RTLD_NOW);
1227 if (MFAILP (handle))
1229 fprintf (stderr, "%s\n", dlerror ());
1232 func_list = mplist ();
1233 MPLIST_DO (plist, MPLIST_NEXT (plist))
1235 if (! MPLIST_SYMBOL_P (plist))
1236 MERROR_GOTO (MERROR_IM, err_label);
1237 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1240 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1243 MSTRUCT_MALLOC (external, MERROR_IM);
1244 external->handle = handle;
1245 external->func_list = func_list;
1246 mplist_add (im_info->externals, module, external);
1251 M17N_OBJECT_UNREF (func_list);
1256 free_map (MIMMap *map, int top)
1261 M17N_OBJECT_UNREF (map->map_actions);
1264 MPLIST_DO (plist, map->submaps)
1265 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1266 M17N_OBJECT_UNREF (map->submaps);
1268 M17N_OBJECT_UNREF (map->branch_actions);
1273 free_state (void *object)
1275 MIMState *state = object;
1277 M17N_OBJECT_UNREF (state->title);
1279 free_map (state->map, 1);
1283 /** Load a state from PLIST into a newly allocated state object.
1284 PLIST has this form:
1285 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1286 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1287 Return the state object. */
1290 load_state (MInputMethodInfo *im_info, MPlist *plist)
1294 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1296 M17N_OBJECT (state, free_state, MERROR_IM);
1297 state->name = MPLIST_SYMBOL (plist);
1298 plist = MPLIST_NEXT (plist);
1299 if (MPLIST_MTEXT_P (plist))
1301 state->title = MPLIST_MTEXT (plist);
1302 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1303 Mlanguage, im_info->language);
1304 M17N_OBJECT_REF (state->title);
1305 plist = MPLIST_NEXT (plist);
1307 MSTRUCT_CALLOC (state->map, MERROR_IM);
1308 MPLIST_DO (plist, plist)
1310 if (MFAILP (MPLIST_PLIST_P (plist)))
1312 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1317 /* Return a newly created IM_INFO for an input method specified by
1318 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1320 static MInputMethodInfo *
1321 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1324 MInputMethodInfo *im_info;
1327 if (name == Mnil && extra == Mnil)
1328 language = Mt, extra = Mglobal;
1329 MSTRUCT_CALLOC (im_info, MERROR_IM);
1331 im_info->language = language;
1332 im_info->name = name;
1333 im_info->extra = extra;
1336 mplist_add (plist, Mplist, elt);
1337 M17N_OBJECT_UNREF (elt);
1338 elt = mplist_add (elt, Msymbol, language);
1339 elt = mplist_add (elt, Msymbol, name);
1340 elt = mplist_add (elt, Msymbol, extra);
1341 mplist_add (elt, Mt, im_info);
1347 fini_im_info (MInputMethodInfo *im_info)
1351 M17N_OBJECT_UNREF (im_info->cmds);
1352 M17N_OBJECT_UNREF (im_info->configured_cmds);
1353 M17N_OBJECT_UNREF (im_info->bc_cmds);
1354 M17N_OBJECT_UNREF (im_info->vars);
1355 M17N_OBJECT_UNREF (im_info->configured_vars);
1356 M17N_OBJECT_UNREF (im_info->bc_vars);
1357 M17N_OBJECT_UNREF (im_info->description);
1358 M17N_OBJECT_UNREF (im_info->title);
1359 if (im_info->states)
1361 MPLIST_DO (plist, im_info->states)
1363 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1365 M17N_OBJECT_UNREF (state);
1367 M17N_OBJECT_UNREF (im_info->states);
1370 if (im_info->macros)
1372 MPLIST_DO (plist, im_info->macros)
1373 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1374 M17N_OBJECT_UNREF (im_info->macros);
1377 if (im_info->externals)
1379 MPLIST_DO (plist, im_info->externals)
1381 MIMExternalModule *external = MPLIST_VAL (plist);
1383 dlclose (external->handle);
1384 M17N_OBJECT_UNREF (external->func_list);
1386 MPLIST_KEY (plist) = Mt;
1388 M17N_OBJECT_UNREF (im_info->externals);
1392 MPLIST_DO (plist, im_info->maps)
1394 MPlist *p = MPLIST_PLIST (plist);
1396 M17N_OBJECT_UNREF (p);
1398 M17N_OBJECT_UNREF (im_info->maps);
1405 free_im_info (MInputMethodInfo *im_info)
1407 fini_im_info (im_info);
1412 free_im_list (MPlist *plist)
1416 MPLIST_DO (pl, plist)
1418 MInputMethodInfo *im_info;
1420 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1421 im_info = MPLIST_VAL (elt);
1422 free_im_info (im_info);
1424 M17N_OBJECT_UNREF (plist);
1427 static MInputMethodInfo *
1428 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1430 if (name == Mnil && extra == Mnil)
1431 language = Mt, extra = Mglobal;
1432 while ((plist = mplist__assq (plist, language)))
1434 MPlist *elt = MPLIST_PLIST (plist);
1436 plist = MPLIST_NEXT (plist);
1437 elt = MPLIST_NEXT (elt);
1438 if (MPLIST_SYMBOL (elt) != name)
1440 elt = MPLIST_NEXT (elt);
1441 if (MPLIST_SYMBOL (elt) != extra)
1443 elt = MPLIST_NEXT (elt);
1444 return MPLIST_VAL (elt);
1449 static void load_im_info (MPlist *, MInputMethodInfo *);
1451 #define get_custom_info(im_info) \
1453 ? lookup_im_info (im_custom_list, (im_info)->language, \
1454 (im_info)->name, (im_info)->extra) \
1457 #define get_config_info(im_info) \
1459 ? lookup_im_info (im_config_list, (im_info)->language, \
1460 (im_info)->name, (im_info)->extra) \
1464 update_custom_info (void)
1470 if (mdatabase__check (im_custom_mdb) > 0)
1475 MDatabaseInfo *custom_dir_info;
1476 char custom_path[PATH_MAX + 1];
1478 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1479 if (! custom_dir_info->filename
1480 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1482 strcpy (custom_path, custom_dir_info->filename);
1483 strcat (custom_path, CUSTOM_FILE);
1484 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1490 free_im_list (im_custom_list);
1491 im_custom_list = NULL;
1493 plist = mdatabase_load (im_custom_mdb);
1496 im_custom_list = mplist ();
1498 MPLIST_DO (pl, plist)
1500 MSymbol language, name, extra;
1501 MInputMethodInfo *im_info;
1502 MPlist *im_data, *p;
1504 if (! MPLIST_PLIST_P (pl))
1506 p = MPLIST_PLIST (pl);
1507 im_data = MPLIST_NEXT (p);
1508 if (! MPLIST_PLIST_P (p))
1510 p = MPLIST_PLIST (p);
1511 if (! MPLIST_SYMBOL_P (p)
1512 || MPLIST_SYMBOL (p) != Minput_method)
1514 p = MPLIST_NEXT (p);
1515 if (! MPLIST_SYMBOL_P (p))
1517 language = MPLIST_SYMBOL (p);
1518 p = MPLIST_NEXT (p);
1519 if (! MPLIST_SYMBOL_P (p))
1521 name = MPLIST_SYMBOL (p);
1522 p = MPLIST_NEXT (p);
1523 if (MPLIST_TAIL_P (p))
1525 else if (MPLIST_SYMBOL_P (p))
1526 extra = MPLIST_SYMBOL (p);
1527 if (language == Mnil || (name == Mnil && extra == Mnil))
1529 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1530 load_im_info (im_data, im_info);
1532 M17N_OBJECT_UNREF (plist);
1537 update_global_info (void)
1543 int ret = mdatabase__check (global_info->mdb);
1547 fini_im_info (global_info);
1551 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1555 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1557 if (! global_info->mdb
1558 || ! (plist = mdatabase_load (global_info->mdb)))
1561 load_im_info (plist, global_info);
1562 M17N_OBJECT_UNREF (plist);
1567 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1568 and EXTRA. KEY, if not Mnil, tells which kind of information about
1569 the input method is necessary, and the returned IM_INFO may contain
1570 only that information. */
1572 static MInputMethodInfo *
1573 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1576 MInputMethodInfo *im_info;
1579 if (name == Mnil && extra == Mnil)
1580 language = Mt, extra = Mglobal;
1581 im_info = lookup_im_info (im_info_list, language, name, extra);
1584 if (key == Mnil ? im_info->states != NULL
1585 : key == Mcommand ? im_info->cmds != NULL
1586 : key == Mvariable ? im_info->vars != NULL
1587 : key == Mtitle ? im_info->title != NULL
1588 : key == Mdescription ? im_info->description != NULL
1590 /* IM_INFO already contains required information. */
1592 /* We have not yet loaded required information. */
1596 mdb = mdatabase_find (Minput_method, language, name, extra);
1599 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1604 plist = mdatabase_load (im_info->mdb);
1608 mplist_push (load_im_info_keys, key, Mt);
1609 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1610 mplist_pop (load_im_info_keys);
1614 MERROR (MERROR_IM, im_info);
1615 update_global_info ();
1616 load_im_info (plist, im_info);
1617 M17N_OBJECT_UNREF (plist);
1620 if (! im_info->cmds)
1621 im_info->cmds = mplist ();
1622 if (! im_info->vars)
1623 im_info->vars = mplist ();
1624 if (! im_info->states)
1625 im_info->states = mplist ();
1627 if (! im_info->title
1628 && (key == Mnil || key == Mtitle))
1629 im_info->title = (name == Mnil ? mtext ()
1630 : mtext_from_data (MSYMBOL_NAME (name),
1631 MSYMBOL_NAMELEN (name),
1632 MTEXT_FORMAT_US_ASCII));
1636 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1637 If updated, but got unloadable, return -1. Otherwise, update
1638 contents of IM_INFO from the new database, and return 1. */
1641 reload_im_info (MInputMethodInfo *im_info)
1646 update_custom_info ();
1647 update_global_info ();
1648 check = mdatabase__check (im_info->mdb);
1651 plist = mdatabase_load (im_info->mdb);
1654 fini_im_info (im_info);
1655 load_im_info (plist, im_info);
1656 M17N_OBJECT_UNREF (plist);
1657 if (! im_info->cmds)
1658 im_info->cmds = mplist ();
1659 if (! im_info->vars)
1660 im_info->vars = mplist ();
1661 if (! im_info->title)
1663 MSymbol name = im_info->name;
1665 im_info->title = (name == Mnil ? mtext ()
1666 : mtext_from_data (MSYMBOL_NAME (name),
1667 MSYMBOL_NAMELEN (name),
1668 MTEXT_FORMAT_US_ASCII));
1673 static MInputMethodInfo *
1674 get_im_info_by_tags (MPlist *plist)
1679 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1680 i++, plist = MPLIST_NEXT (plist))
1681 tag[i] = MPLIST_SYMBOL (plist);
1686 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1691 check_description (MPlist *plist)
1695 if (MPLIST_MTEXT_P (plist))
1697 if (MPLIST_PLIST_P (plist))
1699 MPlist *pl = MPLIST_PLIST (plist);
1701 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1703 pl =MPLIST_NEXT (pl);
1704 if (MFAILP (MPLIST_MTEXT_P (pl)))
1706 mt = MPLIST_MTEXT (pl);
1707 M17N_OBJECT_REF (mt);
1710 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1712 if (translated == (char *) MTEXT_DATA (mt))
1713 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1714 if (translated != (char *) MTEXT_DATA (mt))
1716 M17N_OBJECT_UNREF (mt);
1717 mt = mtext__from_data (translated, strlen (translated),
1718 MTEXT_FORMAT_UTF_8, 1);
1722 mplist_set (plist, Mtext, mt);
1723 M17N_OBJECT_UNREF (mt);
1726 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1732 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1736 check_command_keyseq (MPlist *keyseq)
1738 if (MPLIST_PLIST_P (keyseq))
1740 MPlist *p = MPLIST_PLIST (keyseq);
1743 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1747 if (MPLIST_MTEXT_P (keyseq))
1749 MText *mt = MPLIST_MTEXT (keyseq);
1752 for (i = 0; i < mtext_nchars (mt); i++)
1753 if (mtext_ref_char (mt, i) >= 256)
1760 /* Load command defitions from PLIST into IM_INFO->cmds.
1762 PLIST is well-formed and has this form;
1763 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1764 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1765 M-text or a plist of symbols.
1767 The returned list has the same form, but for each element...
1769 (1) If DESCRIPTION and the rest are omitted, the element is not
1770 stored in the returned list.
1772 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1773 description in global_info->cmds (if any). */
1776 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1780 im_info->cmds = tail = mplist ();
1782 MPLIST_DO (plist, MPLIST_NEXT (plist))
1784 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1787 if (MFAILP (MPLIST_PLIST_P (plist)))
1789 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1790 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1792 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1793 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1795 if (MFAILP (im_info != global_info))
1796 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1800 if (! check_description (p))
1801 mplist_set (p, Msymbol, Mnil);
1802 p = MPLIST_NEXT (p);
1803 while (! MPLIST_TAIL_P (p))
1805 if (MFAILP (check_command_keyseq (p)))
1806 mplist__pop_unref (p);
1808 p = MPLIST_NEXT (p);
1811 tail = mplist_add (tail, Mplist, pl);
1816 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1817 MPlist *config_cmds)
1819 MPlist *global = NULL, *custom = NULL, *config = NULL;
1820 MSymbol name = MPLIST_SYMBOL (plist);
1822 MPlist *description, *keyseq;
1824 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1825 global = MPLIST_NEXT (MPLIST_PLIST (global));
1827 plist = MPLIST_NEXT (plist);
1828 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1830 description = plist;
1831 plist = MPLIST_NEXT (plist);
1835 description = global;
1836 if (! MPLIST_TAIL_P (plist))
1837 plist = MPLIST_NEXT (plist);
1839 if (MPLIST_TAIL_P (plist) && global)
1841 keyseq = MPLIST_NEXT (global);
1842 status = Minherited;
1850 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1852 status = Mconfigured;
1853 config = MPLIST_NEXT (MPLIST_PLIST (config));
1854 if (! MPLIST_TAIL_P (config))
1857 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1859 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1861 if (MPLIST_TAIL_P (this_keyseq))
1862 mplist__pop_unref (custom);
1865 status = Mcustomized;
1866 keyseq = this_keyseq;
1871 mplist_add (plist, Msymbol, name);
1873 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1875 mplist_add (plist, Msymbol, Mnil);
1876 mplist_add (plist, Msymbol, status);
1877 mplist__conc (plist, keyseq);
1882 config_all_commands (MInputMethodInfo *im_info)
1884 MPlist *global_cmds, *custom_cmds, *config_cmds;
1885 MInputMethodInfo *temp;
1886 MPlist *tail, *plist;
1888 M17N_OBJECT_UNREF (im_info->configured_cmds);
1890 if (MPLIST_TAIL_P (im_info->cmds)
1894 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1895 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1896 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1898 im_info->configured_cmds = tail = mplist ();
1899 MPLIST_DO (plist, im_info->cmds)
1901 MPlist *pl = config_command (MPLIST_PLIST (plist),
1902 global_cmds, custom_cmds, config_cmds);
1905 tail = mplist_add (tail, Mplist, pl);
1906 M17N_OBJECT_UNREF (pl);
1911 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1912 valid, return 0 if not. */
1915 check_variable_value (MPlist *val, MPlist *global)
1917 MSymbol type = MPLIST_KEY (val);
1918 MPlist *valids = MPLIST_NEXT (val);
1920 if (type != Minteger && type != Mtext && type != Msymbol)
1924 if (MPLIST_KEY (global) != Mt
1925 && MPLIST_KEY (global) != MPLIST_KEY (val))
1927 if (MPLIST_TAIL_P (valids))
1928 valids = MPLIST_NEXT (global);
1930 if (MPLIST_TAIL_P (valids))
1933 if (type == Minteger)
1935 int n = MPLIST_INTEGER (val);
1937 MPLIST_DO (valids, valids)
1939 if (MPLIST_INTEGER_P (valids))
1941 if (n == MPLIST_INTEGER (valids))
1944 else if (MPLIST_PLIST_P (valids))
1946 MPlist *p = MPLIST_PLIST (valids);
1947 int min_bound, max_bound;
1949 if (! MPLIST_INTEGER_P (p))
1950 MERROR (MERROR_IM, 0);
1951 min_bound = MPLIST_INTEGER (p);
1952 p = MPLIST_NEXT (p);
1953 if (! MPLIST_INTEGER_P (p))
1954 MERROR (MERROR_IM, 0);
1955 max_bound = MPLIST_INTEGER (p);
1956 if (n >= min_bound && n <= max_bound)
1961 else if (type == Msymbol)
1963 MSymbol sym = MPLIST_SYMBOL (val);
1965 MPLIST_DO (valids, valids)
1967 if (! MPLIST_SYMBOL_P (valids))
1968 MERROR (MERROR_IM, 0);
1969 if (sym == MPLIST_SYMBOL (valids))
1975 MText *mt = MPLIST_MTEXT (val);
1977 MPLIST_DO (valids, valids)
1979 if (! MPLIST_MTEXT_P (valids))
1980 MERROR (MERROR_IM, 0);
1981 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1986 return (! MPLIST_TAIL_P (valids));
1989 /* Load variable defitions from PLIST into IM_INFO->vars.
1991 PLIST is well-formed and has this form;
1992 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1994 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1996 The returned list has the same form, but for each element...
1998 (1) If DESCRIPTION and the rest are omitted, the element is not
1999 stored in the returned list.
2001 (2) If DESCRIPTION is nil, it is complemented by the corresponding
2002 description in global_info->vars (if any). */
2005 load_variables (MInputMethodInfo *im_info, MPlist *plist)
2007 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
2008 ? global_info->vars : NULL);
2011 im_info->vars = tail = mplist ();
2012 MPLIST_DO (plist, MPLIST_NEXT (plist))
2016 if (MFAILP (MPLIST_PLIST_P (plist)))
2018 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
2019 if (MFAILP (MPLIST_SYMBOL_P (pl)))
2021 if (im_info == global_info)
2023 /* Loading a global variable. */
2024 p = MPLIST_NEXT (pl);
2025 if (MPLIST_TAIL_P (p))
2026 mplist_add (p, Msymbol, Mnil);
2029 if (! check_description (p))
2030 mplist_set (p, Msymbol, Mnil);
2031 p = MPLIST_NEXT (p);
2032 if (MFAILP (! MPLIST_TAIL_P (p)
2033 && check_variable_value (p, NULL)))
2034 mplist_set (p, Mt, NULL);
2037 else if (im_info->mdb)
2039 /* Loading a local variable. */
2040 MSymbol name = MPLIST_SYMBOL (pl);
2041 MPlist *global = NULL;
2044 && (p = mplist__assq (global_vars, name)))
2046 /* P ::= ((NAME DESC ...) ...) */
2047 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2048 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2049 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2052 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2053 if (! MPLIST_TAIL_P (p))
2055 if (! check_description (p))
2056 mplist_set (p, Msymbol, Mnil);
2057 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2058 if (MFAILP (! MPLIST_TAIL_P (p)))
2059 mplist_set (p, Mt, NULL);
2062 MPlist *valid_values = MPLIST_NEXT (p);
2064 if (! MPLIST_TAIL_P (valid_values)
2065 ? MFAILP (check_variable_value (p, NULL))
2066 : global && MFAILP (check_variable_value (p, global)))
2067 mplist_set (p, Mt, NULL);
2073 /* Loading a variable customization. */
2074 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2075 if (MFAILP (! MPLIST_TAIL_P (p)))
2077 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2078 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2079 || MPLIST_MTEXT_P (p)))
2082 tail = mplist_add (tail, Mplist, pl);
2087 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2088 MPlist *config_vars)
2090 MPlist *global = NULL, *custom = NULL, *config = NULL;
2091 MSymbol name = MPLIST_SYMBOL (plist);
2093 MPlist *description = NULL, *value, *valids;
2097 global = mplist__assq (global_vars, name);
2099 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2102 plist = MPLIST_NEXT (plist);
2103 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2104 description = plist;
2106 description = global;
2108 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2110 if (MPLIST_TAIL_P (plist))
2112 /* Inherit from global (if any). */
2116 if (MPLIST_KEY (value) == Mt)
2118 valids = MPLIST_NEXT (global);
2119 status = Minherited;
2131 value = plist = MPLIST_NEXT (plist);
2132 valids = MPLIST_NEXT (value);
2133 if (MPLIST_KEY (value) == Mt)
2135 if (! MPLIST_TAIL_P (valids))
2138 valids = MPLIST_NEXT (global);
2142 if (config_vars && (config = mplist__assq (config_vars, name)))
2144 status = Mconfigured;
2145 config = MPLIST_NEXT (MPLIST_PLIST (config));
2146 if (! MPLIST_TAIL_P (config))
2149 if (MFAILP (check_variable_value (value, global ? global : plist)))
2153 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2155 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2157 if (MPLIST_TAIL_P (this_value))
2158 mplist__pop_unref (custom);
2162 if (MFAILP (check_variable_value (value, global ? global : plist)))
2164 status = Mcustomized;
2169 mplist_add (plist, Msymbol, name);
2171 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2173 mplist_add (plist, Msymbol, Mnil);
2174 mplist_add (plist, Msymbol, status);
2176 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2178 mplist_add (plist, Mt, NULL);
2179 if (valids && ! MPLIST_TAIL_P (valids))
2180 mplist__conc (plist, valids);
2184 /* Return a configured variable definition list based on
2185 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2186 get it from global_info->vars. */
2189 config_all_variables (MInputMethodInfo *im_info)
2191 MPlist *global_vars, *custom_vars, *config_vars;
2192 MInputMethodInfo *temp;
2193 MPlist *tail, *plist;
2195 M17N_OBJECT_UNREF (im_info->configured_vars);
2197 if (MPLIST_TAIL_P (im_info->vars)
2201 global_vars = im_info != global_info ? global_info->vars : NULL;
2202 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2203 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2205 im_info->configured_vars = tail = mplist ();
2206 MPLIST_DO (plist, im_info->vars)
2208 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2209 global_vars, custom_vars, config_vars);
2212 tail = mplist_add (tail, Mplist, pl);
2213 M17N_OBJECT_UNREF (pl);
2218 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2219 CONFIG contains configuration information of the input method. */
2222 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2226 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2228 load_commands (im_info, MPLIST_PLIST (pl));
2229 config_all_commands (im_info);
2230 pl = mplist_pop (pl);
2231 M17N_OBJECT_UNREF (pl);
2234 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2236 load_variables (im_info, MPLIST_PLIST (pl));
2237 config_all_variables (im_info);
2238 pl = mplist_pop (pl);
2239 M17N_OBJECT_UNREF (pl);
2242 MPLIST_DO (plist, plist)
2243 if (MPLIST_PLIST_P (plist))
2245 MPlist *elt = MPLIST_PLIST (plist);
2248 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2250 key = MPLIST_SYMBOL (elt);
2255 elt = MPLIST_NEXT (elt);
2256 if (MFAILP (MPLIST_MTEXT_P (elt)))
2258 im_info->title = MPLIST_MTEXT (elt);
2259 M17N_OBJECT_REF (im_info->title);
2261 else if (key == Mmap)
2263 pl = mplist__from_alist (MPLIST_NEXT (elt));
2266 if (! im_info->maps)
2270 mplist__conc (im_info->maps, pl);
2271 M17N_OBJECT_UNREF (pl);
2274 else if (key == Mmacro)
2276 if (! im_info->macros)
2277 im_info->macros = mplist ();
2278 MPLIST_DO (elt, MPLIST_NEXT (elt))
2280 if (MFAILP (MPLIST_PLIST_P (elt)))
2282 load_macros (im_info, MPLIST_PLIST (elt));
2285 else if (key == Mmodule)
2287 if (! im_info->externals)
2288 im_info->externals = mplist ();
2289 MPLIST_DO (elt, MPLIST_NEXT (elt))
2291 if (MFAILP (MPLIST_PLIST_P (elt)))
2293 load_external_module (im_info, MPLIST_PLIST (elt));
2296 else if (key == Mstate)
2298 MPLIST_DO (elt, MPLIST_NEXT (elt))
2302 if (MFAILP (MPLIST_PLIST_P (elt)))
2304 pl = MPLIST_PLIST (elt);
2305 if (! im_info->states)
2306 im_info->states = mplist ();
2307 state = load_state (im_info, MPLIST_PLIST (elt));
2310 mplist_put (im_info->states, state->name, state);
2313 else if (key == Minclude)
2315 /* elt ::= include (tag1 tag2 ...) key item ... */
2317 MInputMethodInfo *temp;
2319 elt = MPLIST_NEXT (elt);
2320 if (MFAILP (MPLIST_PLIST_P (elt)))
2322 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2325 elt = MPLIST_NEXT (elt);
2326 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2328 key = MPLIST_SYMBOL (elt);
2329 elt = MPLIST_NEXT (elt);
2332 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2334 if (! im_info->maps)
2335 im_info->maps = mplist ();
2336 MPLIST_DO (pl, temp->maps)
2338 p = MPLIST_VAL (pl);
2339 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2340 M17N_OBJECT_REF (p);
2343 else if (key == Mmacro)
2345 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2347 if (! im_info->macros)
2348 im_info->macros = mplist ();
2349 MPLIST_DO (pl, temp->macros)
2351 p = MPLIST_VAL (pl);
2352 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2353 M17N_OBJECT_REF (p);
2356 else if (key == Mstate)
2358 if (! temp->states || MPLIST_TAIL_P (temp->states))
2360 if (! im_info->states)
2361 im_info->states = mplist ();
2362 MPLIST_DO (pl, temp->states)
2364 MIMState *state = MPLIST_VAL (pl);
2366 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2367 M17N_OBJECT_REF (state);
2371 else if (key == Mdescription)
2373 if (im_info->description)
2375 elt = MPLIST_NEXT (elt);
2376 if (! check_description (elt))
2378 im_info->description = MPLIST_MTEXT (elt);
2379 M17N_OBJECT_REF (im_info->description);
2382 im_info->tick = time (NULL);
2387 static int take_action_list (MInputContext *ic, MPlist *action_list);
2388 static void preedit_commit (MInputContext *ic, int need_prefix);
2391 shift_state (MInputContext *ic, MSymbol state_name)
2393 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2394 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2395 MIMState *orig_state = ic_info->state, *state;
2397 /* Find a state to shift to. If not found, shift to the initial
2399 if (state_name == Mt)
2401 if (! ic_info->prev_state)
2403 state = ic_info->prev_state;
2405 else if (state_name == Mnil)
2407 state = (MIMState *) MPLIST_VAL (im_info->states);
2411 state = (MIMState *) mplist_get (im_info->states, state_name);
2413 state = (MIMState *) MPLIST_VAL (im_info->states);
2419 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2420 MSYMBOL_NAME (orig_state->name),
2421 MSYMBOL_NAME (state->name));
2423 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2426 /* Enter the new state. */
2427 ic_info->state = state;
2428 ic_info->map = state->map;
2429 ic_info->state_key_head = ic_info->key_head;
2430 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2432 /* We have shifted to the initial state. */
2433 preedit_commit (ic, 0);
2434 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2435 ic_info->state_pos = ic->cursor_pos;
2436 if (state != orig_state)
2438 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2440 /* Shifted to the initial state. */
2441 ic_info->prev_state = NULL;
2442 M17N_OBJECT_UNREF (ic_info->vars_saved);
2443 ic_info->vars_saved = mplist_copy (ic_info->vars);
2446 ic_info->prev_state = orig_state;
2449 ic->status = state->title;
2451 ic->status = im_info->title;
2452 ic->status_changed = 1;
2453 if (ic_info->map == ic_info->state->map
2454 && ic_info->map->map_actions)
2456 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2457 MSYMBOL_NAME (state->name));
2458 take_action_list (ic, ic_info->map->map_actions);
2463 /* Find a candidate group that contains a candidate number INDEX from
2464 PLIST. Set START_INDEX to the first candidate number of the group,
2465 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2466 candidate group number if they are non-NULL. If INDEX is -1, find
2467 the last candidate group. */
2470 find_candidates_group (MPlist *plist, int index,
2471 int *start_index, int *end_index, int *group_index)
2473 int i = 0, gidx = 0, len;
2475 MPLIST_DO (plist, plist)
2477 if (MPLIST_MTEXT_P (plist))
2478 len = mtext_nchars (MPLIST_MTEXT (plist));
2480 len = mplist_length (MPLIST_PLIST (plist));
2481 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2487 *end_index = i + len;
2489 *group_index = gidx;
2498 /* Adjust markers for the change of preedit text.
2499 If FROM == TO, the change is insertion of INS chars.
2500 If FROM < TO and INS == 0, the change is deletion of the range.
2501 If FROM < TO and INS > 0, the change is replacement. */
2504 adjust_markers (MInputContext *ic, int from, int to, int ins)
2506 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2511 MPLIST_DO (markers, ic_info->markers)
2512 if (MPLIST_INTEGER (markers) > from)
2513 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2514 if (ic->cursor_pos >= from)
2515 ic->cursor_pos += ins;
2519 MPLIST_DO (markers, ic_info->markers)
2521 if (MPLIST_INTEGER (markers) >= to)
2522 MPLIST_VAL (markers)
2523 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2524 else if (MPLIST_INTEGER (markers) > from)
2525 MPLIST_VAL (markers) = (void *) from;
2527 if (ic->cursor_pos >= to)
2528 ic->cursor_pos += ins - (to - from);
2529 else if (ic->cursor_pos > from)
2530 ic->cursor_pos = from;
2536 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2538 int nchars = mt ? mtext_nchars (mt) : 1;
2542 mtext_ins (ic->preedit, pos, mt);
2543 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2547 mtext_ins_char (ic->preedit, pos, c, 1);
2549 MDEBUG_PRINT1 ("('%c')", c);
2551 MDEBUG_PRINT1 ("(U+%04X)", c);
2553 adjust_markers (ic, pos, pos, nchars);
2554 ic->preedit_changed = 1;
2559 preedit_delete (MInputContext *ic, int from, int to)
2561 mtext_del (ic->preedit, from, to);
2562 adjust_markers (ic, from, to, 0);
2563 ic->preedit_changed = 1;
2567 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2571 mtext_del (ic->preedit, from, to);
2574 mtext_ins (ic->preedit, from, mt);
2575 ins = mtext_nchars (mt);
2579 mtext_ins_char (ic->preedit, from, c, 1);
2582 adjust_markers (ic, from, to, ins);
2583 ic->preedit_changed = 1;
2588 preedit_commit (MInputContext *ic, int need_prefix)
2590 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2591 int preedit_len = mtext_nchars (ic->preedit);
2593 if (preedit_len > 0)
2597 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2598 Mcandidate_list, NULL, 0);
2599 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2600 Mcandidate_index, NULL, 0);
2601 mtext_cat (ic->produced, ic->preedit);
2607 MDEBUG_PRINT1 ("\n [IM] [%s]",
2608 MSYMBOL_NAME (ic_info->state->name));
2609 MDEBUG_PRINT (" (commit");
2610 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2611 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2615 mtext_reset (ic->preedit);
2616 mtext_reset (ic_info->preedit_saved);
2617 MPLIST_DO (p, ic_info->markers)
2619 ic->cursor_pos = ic_info->state_pos = 0;
2620 ic->preedit_changed = 1;
2621 ic_info->commit_key_head = ic_info->key_head;
2623 if (ic->candidate_list)
2625 M17N_OBJECT_UNREF (ic->candidate_list);
2626 ic->candidate_list = NULL;
2627 ic->candidate_index = 0;
2628 ic->candidate_from = ic->candidate_to = 0;
2629 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2630 if (ic->candidate_show)
2632 ic->candidate_show = 0;
2633 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2639 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2641 int code = marker_code (sym, 0);
2643 if (mt && (code == '[' || code == ']'))
2647 if (code == '[' && current > 0)
2649 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2653 else if (code == ']' && current < mtext_nchars (mt))
2655 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2661 return (code == '<' ? 0
2662 : code == '>' ? limit
2663 : code == '-' ? current - 1
2664 : code == '+' ? current + 1
2665 : code == '=' ? current
2666 : code - '0' > limit ? limit
2670 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2674 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2676 int from = mtext_property_start (prop);
2677 int to = mtext_property_end (prop);
2679 MPlist *candidate_list = mtext_property_value (prop);
2680 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2682 int ingroup_index = idx - start;
2685 candidate_list = mplist_copy (candidate_list);
2686 if (MPLIST_MTEXT_P (group))
2688 mt = MPLIST_MTEXT (group);
2689 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2697 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2698 i++, plist = MPLIST_NEXT (plist));
2699 mt = MPLIST_MTEXT (plist);
2700 preedit_replace (ic, from, to, mt, 0);
2701 to = from + mtext_nchars (mt);
2703 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2704 M17N_OBJECT_UNREF (candidate_list);
2705 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2706 ic->cursor_pos = to;
2710 get_select_charset (MInputContextInfo * ic_info)
2712 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2715 if (! MPLIST_VAL (plist))
2717 sym = MPLIST_SYMBOL (plist);
2720 return MCHARSET (sym);
2724 adjust_candidates (MPlist *plist, MCharset *charset)
2728 /* plist ::= MTEXT ... | PLIST ... */
2729 plist = mplist_copy (plist);
2730 if (MPLIST_MTEXT_P (plist))
2733 while (! MPLIST_TAIL_P (pl))
2735 /* pl ::= MTEXT ... */
2736 MText *mt = MPLIST_MTEXT (pl);
2740 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2742 c = mtext_ref_char (mt, i);
2743 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2747 mt = mtext_dup (mt);
2748 mplist_set (pl, Mtext, mt);
2749 M17N_OBJECT_UNREF (mt);
2752 mtext_del (mt, i, i + 1);
2755 if (mtext_len (mt) > 0)
2756 pl = MPLIST_NEXT (pl);
2760 M17N_OBJECT_UNREF (mt);
2764 else /* MPLIST_PLIST_P (plist) */
2767 while (! MPLIST_TAIL_P (pl))
2769 /* pl ::= (MTEXT ...) ... */
2770 MPlist *p = MPLIST_PLIST (pl);
2772 /* p ::= MTEXT ... */
2776 while (! MPLIST_TAIL_P (p0))
2778 MText *mt = MPLIST_MTEXT (p0);
2781 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2783 c = mtext_ref_char (mt, i);
2784 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2789 p0 = MPLIST_NEXT (p0);
2796 p = mplist_copy (p);
2797 mplist_set (pl, Mplist, p);
2798 M17N_OBJECT_UNREF (p);
2802 p0 = MPLIST_NEXT (p0);
2805 M17N_OBJECT_UNREF (mt);
2808 if (! MPLIST_TAIL_P (p))
2809 pl = MPLIST_NEXT (pl);
2813 M17N_OBJECT_UNREF (p);
2817 if (MPLIST_TAIL_P (plist))
2819 M17N_OBJECT_UNREF (plist);
2826 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2828 MCharset *charset = get_select_charset (ic_info);
2833 plist = resolve_variable (ic_info, Mcandidates_group_size);
2834 column = MPLIST_INTEGER (plist);
2836 plist = MPLIST_PLIST (args);
2838 plist = adjust_candidates (plist, charset);
2840 if (plist && column > 0)
2842 if (MPLIST_MTEXT_P (plist))
2844 MText *mt = MPLIST_MTEXT (plist);
2845 MPlist *next = MPLIST_NEXT (plist);
2847 if (MPLIST_TAIL_P (next))
2848 M17N_OBJECT_REF (mt);
2851 mt = mtext_dup (mt);
2852 while (! MPLIST_TAIL_P (next))
2854 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2855 next = MPLIST_NEXT (next);
2859 M17N_OBJECT_UNREF (plist);
2861 len = mtext_nchars (mt);
2863 mplist_add (plist, Mtext, mt);
2866 for (i = 0; i < len; i += column)
2868 int to = (i + column < len ? i + column : len);
2869 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2871 mplist_add (plist, Mtext, sub);
2872 M17N_OBJECT_UNREF (sub);
2875 M17N_OBJECT_UNREF (mt);
2877 else if (! MPLIST_TAIL_P (plist))
2879 MPlist *tail = plist;
2880 MPlist *new = mplist ();
2881 MPlist *this = mplist ();
2884 MPLIST_DO (tail, tail)
2886 MPlist *p = MPLIST_PLIST (tail);
2890 MText *mt = MPLIST_MTEXT (p);
2892 if (count == column)
2894 mplist_add (new, Mplist, this);
2895 M17N_OBJECT_UNREF (this);
2899 mplist_add (this, Mtext, mt);
2903 mplist_add (new, Mplist, this);
2904 M17N_OBJECT_UNREF (this);
2905 mplist_set (plist, Mnil, NULL);
2906 MPLIST_DO (tail, new)
2908 MPlist *elt = MPLIST_PLIST (tail);
2910 mplist_add (plist, Mplist, elt);
2912 M17N_OBJECT_UNREF (new);
2921 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2923 MPlist *action = NULL;
2927 if (MPLIST_SYMBOL_P (action_list))
2929 MSymbol var = MPLIST_SYMBOL (action_list);
2932 MPLIST_DO (p, ic_info->vars)
2933 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2935 if (MPLIST_TAIL_P (p))
2937 action = MPLIST_NEXT (MPLIST_PLIST (p));
2938 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2941 if (MPLIST_PLIST_P (action_list))
2943 action = MPLIST_PLIST (action_list);
2944 if (MPLIST_SYMBOL_P (action))
2946 name = MPLIST_SYMBOL (action);
2947 args = MPLIST_NEXT (action);
2949 && MPLIST_PLIST_P (args))
2950 mplist_set (action, Msymbol, M_candidates);
2952 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2955 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2956 mplist_push (action, Msymbol, M_candidates);
2957 mplist_set (action_list, Mplist, action);
2958 M17N_OBJECT_UNREF (action);
2961 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2964 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2965 mplist_push (action, Msymbol, Minsert);
2966 mplist_set (action_list, Mplist, action);
2967 M17N_OBJECT_UNREF (action);
2972 /* Perform list of actions in ACTION_LIST for the current input
2973 context IC. If unhandle action was not performed, return 0.
2974 Otherwise, return -1. */
2977 take_action_list (MInputContext *ic, MPlist *action_list)
2979 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2980 MPlist *candidate_list = ic->candidate_list;
2981 int candidate_index = ic->candidate_index;
2982 int candidate_show = ic->candidate_show;
2983 MTextProperty *prop;
2985 MPLIST_DO (action_list, action_list)
2987 MPlist *action = regularize_action (action_list, ic_info);
2993 name = MPLIST_SYMBOL (action);
2994 args = MPLIST_NEXT (action);
2996 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2997 if (name == Minsert)
2999 if (MPLIST_SYMBOL_P (args))
3001 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3002 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3005 if (MPLIST_MTEXT_P (args))
3006 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3007 else /* MPLIST_INTEGER_P (args)) */
3008 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3010 else if (name == M_candidates)
3012 MPlist *plist = get_candidate_list (ic_info, args);
3015 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
3017 if (MPLIST_MTEXT_P (plist))
3019 preedit_insert (ic, ic->cursor_pos, NULL,
3020 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3023 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
3027 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3029 preedit_insert (ic, ic->cursor_pos, mt, 0);
3030 len = mtext_nchars (mt);
3032 plist = mplist_copy (plist);
3033 mtext_put_prop (ic->preedit,
3034 ic->cursor_pos - len, ic->cursor_pos,
3035 Mcandidate_list, plist);
3036 M17N_OBJECT_UNREF (plist);
3037 mtext_put_prop (ic->preedit,
3038 ic->cursor_pos - len, ic->cursor_pos,
3039 Mcandidate_index, (void *) 0);
3041 else if (name == Mselect)
3044 int code, idx, gindex;
3045 int pos = ic->cursor_pos;
3047 int idx_decided = 0;
3050 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3053 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3054 group = find_candidates_group (mtext_property_value (prop), idx,
3055 &start, &end, &gindex);
3056 if (MPLIST_SYMBOL_P (args))
3058 code = marker_code (MPLIST_SYMBOL (args), 0);
3061 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3062 if (! MPLIST_INTEGER_P (args))
3064 idx = start + MPLIST_INTEGER (args);
3065 if (idx < start || idx >= end)
3073 if (code != '[' && code != ']')
3078 ? new_index (NULL, ic->candidate_index - start,
3079 end - start - 1, MPLIST_SYMBOL (args),
3081 : MPLIST_INTEGER (args)));
3084 find_candidates_group (mtext_property_value (prop), -1,
3089 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3094 int ingroup_index = idx - start;
3097 group = mtext_property_value (prop);
3098 len = mplist_length (group);
3111 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3112 idx += (MPLIST_MTEXT_P (group)
3113 ? mtext_nchars (MPLIST_MTEXT (group))
3114 : mplist_length (MPLIST_PLIST (group)));
3115 len = (MPLIST_MTEXT_P (group)
3116 ? mtext_nchars (MPLIST_MTEXT (group))
3117 : mplist_length (MPLIST_PLIST (group)));
3118 if (ingroup_index >= len)
3119 ingroup_index = len - 1;
3120 idx += ingroup_index;
3122 update_candidate (ic, prop, idx);
3123 MDEBUG_PRINT1 ("(%d)", idx);
3125 else if (name == Mshow)
3126 ic->candidate_show = 1;
3127 else if (name == Mhide)
3128 ic->candidate_show = 0;
3129 else if (name == Mdelete)
3131 int len = mtext_nchars (ic->preedit);
3135 if (MPLIST_SYMBOL_P (args)
3136 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3138 to = ic->cursor_pos + pos;
3141 delete_surrounding_text (ic, to);
3146 delete_surrounding_text (ic, to - len);
3152 to = (MPLIST_SYMBOL_P (args)
3153 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3155 : MPLIST_INTEGER (args));
3160 pos = to - ic->cursor_pos;
3162 MDEBUG_PRINT1 ("(%d)", pos);
3163 if (to < ic->cursor_pos)
3164 preedit_delete (ic, to, ic->cursor_pos);
3165 else if (to > ic->cursor_pos)
3166 preedit_delete (ic, ic->cursor_pos, to);
3168 else if (name == Mmove)
3170 int len = mtext_nchars (ic->preedit);
3172 = (MPLIST_SYMBOL_P (args)
3173 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3175 : MPLIST_INTEGER (args));
3181 if (pos != ic->cursor_pos)
3183 ic->cursor_pos = pos;
3184 ic->preedit_changed = 1;
3186 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3188 else if (name == Mmark)
3190 int code = marker_code (MPLIST_SYMBOL (args), 0);
3194 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3195 (void *) ic->cursor_pos);
3196 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3199 else if (name == Mpushback)
3201 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3205 if (MPLIST_SYMBOL_P (args))
3207 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3208 if (MPLIST_INTEGER_P (args))
3209 num = MPLIST_INTEGER (args);
3214 num = MPLIST_INTEGER (args);
3217 ic_info->key_head -= num;
3219 ic_info->key_head = 0;
3221 ic_info->key_head = - num;
3222 if (ic_info->key_head > ic_info->used)
3223 ic_info->key_head = ic_info->used;
3225 else if (MPLIST_MTEXT_P (args))
3227 MText *mt = MPLIST_MTEXT (args);
3228 int i, len = mtext_nchars (mt);
3231 ic_info->key_head--;
3232 for (i = 0; i < len; i++)
3234 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3235 if (ic_info->key_head + i < ic_info->used)
3236 ic_info->keys[ic_info->key_head + i] = key;
3238 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3243 MPlist *plist = MPLIST_PLIST (args), *pl;
3247 ic_info->key_head--;
3249 MPLIST_DO (pl, plist)
3251 key = MPLIST_SYMBOL (pl);
3252 if (ic_info->key_head < ic_info->used)
3253 ic_info->keys[ic_info->key_head + i] = key;
3255 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3260 else if (name == Mpop)
3262 if (ic_info->key_head < ic_info->used)
3263 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3265 else if (name == Mcall)
3267 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3268 MIMExternalFunc func = NULL;
3269 MSymbol module, func_name;
3270 MPlist *func_args, *val;
3273 module = MPLIST_SYMBOL (args);
3274 args = MPLIST_NEXT (args);
3275 func_name = MPLIST_SYMBOL (args);
3277 if (im_info->externals)
3279 MIMExternalModule *external
3280 = (MIMExternalModule *) mplist_get (im_info->externals,
3283 func = ((MIMExternalFunc)
3284 mplist_get_func (external->func_list, func_name));
3288 func_args = mplist ();
3289 mplist_add (func_args, Mt, ic);
3290 MPLIST_DO (args, MPLIST_NEXT (args))
3294 if (MPLIST_KEY (args) == Msymbol
3295 && MPLIST_KEY (args) != Mnil
3296 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3298 code = new_index (ic, ic->cursor_pos,
3299 mtext_nchars (ic->preedit),
3300 MPLIST_SYMBOL (args), ic->preedit);
3301 mplist_add (func_args, Minteger, (void *) code);
3304 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3306 val = (func) (func_args);
3307 M17N_OBJECT_UNREF (func_args);
3308 if (val && ! MPLIST_TAIL_P (val))
3309 ret = take_action_list (ic, val);
3310 M17N_OBJECT_UNREF (val);
3314 else if (name == Mshift)
3316 shift_state (ic, MPLIST_SYMBOL (args));
3318 else if (name == Mundo)
3320 int intarg = (MPLIST_TAIL_P (args)
3322 : integer_value (ic, args, 0));
3324 mtext_reset (ic->preedit);
3325 mtext_reset (ic_info->preedit_saved);
3326 mtext_reset (ic->produced);
3327 M17N_OBJECT_UNREF (ic_info->vars);
3328 ic_info->vars = mplist_copy (ic_info->vars_saved);
3329 ic->cursor_pos = ic_info->state_pos = 0;
3330 ic_info->state_key_head = ic_info->key_head
3331 = ic_info->commit_key_head = 0;
3333 shift_state (ic, Mnil);
3336 if (MPLIST_TAIL_P (args))
3341 ic_info->used += intarg;
3344 ic_info->used = intarg;
3347 else if (name == Mset || name == Madd || name == Msub
3348 || name == Mmul || name == Mdiv)
3350 MSymbol sym = MPLIST_SYMBOL (args);
3351 MPlist *value = resolve_variable (ic_info, sym);
3355 val1 = MPLIST_INTEGER (value);
3356 args = MPLIST_NEXT (args);
3357 val2 = resolve_expression (ic, args);
3359 val1 = val2, op = "=";
3360 else if (name == Madd)
3361 val1 += val2, op = "+=";
3362 else if (name == Msub)
3363 val1 -= val2, op = "-=";
3364 else if (name == Mmul)
3365 val1 *= val2, op = "*=";
3367 val1 /= val2, op = "/=";
3368 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3369 MSYMBOL_NAME (sym), op, val1, val1);
3370 mplist_set (value, Minteger, (void *) val1);
3372 else if (name == Mequal || name == Mless || name == Mgreater
3373 || name == Mless_equal || name == Mgreater_equal)
3376 MPlist *actions1, *actions2;
3379 val1 = resolve_expression (ic, args);
3380 args = MPLIST_NEXT (args);
3381 val2 = resolve_expression (ic, args);
3382 args = MPLIST_NEXT (args);
3383 actions1 = MPLIST_PLIST (args);
3384 args = MPLIST_NEXT (args);
3385 if (MPLIST_TAIL_P (args))
3388 actions2 = MPLIST_PLIST (args);
3389 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3390 if (name == Mequal ? val1 == val2
3391 : name == Mless ? val1 < val2
3392 : name == Mgreater ? val1 > val2
3393 : name == Mless_equal ? val1 <= val2
3396 MDEBUG_PRINT ("ok");
3397 ret = take_action_list (ic, actions1);
3401 MDEBUG_PRINT ("no");
3403 ret = take_action_list (ic, actions2);
3408 else if (name == Mcond)
3412 MPLIST_DO (args, args)
3417 if (! MPLIST_PLIST (args))
3419 cond = MPLIST_PLIST (args);
3420 if (resolve_expression (ic, cond) != 0)
3422 MDEBUG_PRINT1 ("(%dth)", idx);
3423 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3429 else if (name == Mcommit)
3431 preedit_commit (ic, 0);
3433 else if (name == Munhandle)
3435 preedit_commit (ic, 0);
3440 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3444 && (actions = mplist_get (im_info->macros, name)))
3446 if (take_action_list (ic, actions) < 0)
3452 if (ic->candidate_list)
3454 M17N_OBJECT_UNREF (ic->candidate_list);
3455 ic->candidate_list = NULL;
3457 if (ic->cursor_pos > 0
3458 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3461 ic->candidate_list = mtext_property_value (prop);
3462 M17N_OBJECT_REF (ic->candidate_list);
3464 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3466 ic->candidate_from = mtext_property_start (prop);
3467 ic->candidate_to = mtext_property_end (prop);
3470 if (candidate_list != ic->candidate_list)
3471 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3472 if (candidate_index != ic->candidate_index)
3473 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3474 if (candidate_show != ic->candidate_show)
3475 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3480 /* Handle the input key KEY in the current state and map specified in
3481 the input context IC. If KEY is handled correctly, return 0.
3482 Otherwise, return -1. */
3485 handle_key (MInputContext *ic)
3487 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3488 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3489 MIMMap *map = ic_info->map;
3490 MIMMap *submap = NULL;
3491 MSymbol key = ic_info->keys[ic_info->key_head];
3492 MSymbol alias = Mnil;
3495 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3496 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3500 submap = mplist_get (map->submaps, key);
3503 && (alias = msymbol_get (alias, M_key_alias))
3505 submap = mplist_get (map->submaps, alias);
3510 if (! alias || alias == key)
3511 MDEBUG_PRINT (" submap-found");
3513 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3514 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3515 ic->preedit_changed = 1;
3516 ic->cursor_pos = ic_info->state_pos;
3517 ic_info->key_head++;
3518 ic_info->map = map = submap;
3519 if (map->map_actions)
3521 MDEBUG_PRINT (" map-actions:");
3522 if (take_action_list (ic, map->map_actions) < 0)
3524 MDEBUG_PRINT ("\n");
3528 else if (map->submaps)
3530 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3532 MSymbol key = ic_info->keys[i];
3533 char *name = msymbol_name (key);
3535 if (! name[0] || ! name[1])
3536 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3540 /* If this is the terminal map or we have shifted to another
3541 state, perform branch actions (if any). */
3542 if (! map->submaps || map != ic_info->map)
3544 if (map->branch_actions)
3546 MDEBUG_PRINT (" branch-actions:");
3547 if (take_action_list (ic, map->branch_actions) < 0)
3549 MDEBUG_PRINT ("\n");
3553 /* If MAP is still not the root map, shift to the current
3555 if (ic_info->map != ic_info->state->map)
3556 shift_state (ic, ic_info->state->name);
3561 /* MAP can not handle KEY. */
3563 /* Perform branch actions if any. */
3564 if (map->branch_actions)
3566 MDEBUG_PRINT (" branch-actions:");
3567 if (take_action_list (ic, map->branch_actions) < 0)
3569 MDEBUG_PRINT ("\n");
3574 if (map == ic_info->map)
3576 /* The above branch actions didn't change the state. */
3578 /* If MAP is the root map of the initial state, and there
3579 still exist an unhandled key, it means that the current
3580 input method can not handle it. */
3581 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3582 && ic_info->key_head < ic_info->used)
3584 MDEBUG_PRINT (" unhandled\n");
3588 if (map != ic_info->state->map)
3590 /* MAP is not the root map. Shift to the root map of the
3592 shift_state (ic, ic_info->state->name);
3594 else if (! map->branch_actions)
3596 /* MAP is the root map without any default branch
3597 actions. Shift to the initial state. */
3598 shift_state (ic, Mnil);
3602 MDEBUG_PRINT ("\n");
3606 /* Initialize IC->ic_info. */
3609 init_ic_info (MInputContext *ic)
3611 MInputMethodInfo *im_info = ic->im->info;
3612 MInputContextInfo *ic_info = ic->info;
3615 MLIST_INIT1 (ic_info, keys, 8);;
3617 ic_info->markers = mplist ();
3619 ic_info->vars = mplist ();
3620 if (im_info->configured_vars)
3621 MPLIST_DO (plist, im_info->configured_vars)
3623 MPlist *pl = MPLIST_PLIST (plist);
3624 MSymbol name = MPLIST_SYMBOL (pl);
3626 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3627 if (MPLIST_KEY (pl) != Mt)
3629 MPlist *p = mplist ();
3631 mplist_push (ic_info->vars, Mplist, p);
3632 M17N_OBJECT_UNREF (p);
3633 mplist_add (p, Msymbol, name);
3634 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3637 ic_info->vars_saved = mplist_copy (ic_info->vars);
3639 if (im_info->externals)
3641 MPlist *func_args = mplist (), *plist;
3643 mplist_add (func_args, Mt, ic);
3644 MPLIST_DO (plist, im_info->externals)
3646 MIMExternalModule *external = MPLIST_VAL (plist);
3647 MIMExternalFunc func
3648 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3653 M17N_OBJECT_UNREF (func_args);
3656 ic_info->preedit_saved = mtext ();
3657 ic_info->tick = im_info->tick;
3660 /* Finalize IC->ic_info. */
3663 fini_ic_info (MInputContext *ic)
3665 MInputMethodInfo *im_info = ic->im->info;
3666 MInputContextInfo *ic_info = ic->info;
3668 if (im_info->externals)
3670 MPlist *func_args = mplist (), *plist;
3672 mplist_add (func_args, Mt, ic);
3673 MPLIST_DO (plist, im_info->externals)
3675 MIMExternalModule *external = MPLIST_VAL (plist);
3676 MIMExternalFunc func
3677 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3682 M17N_OBJECT_UNREF (func_args);
3685 MLIST_FREE1 (ic_info, keys);
3686 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3687 M17N_OBJECT_UNREF (ic_info->markers);
3688 M17N_OBJECT_UNREF (ic_info->vars);
3689 M17N_OBJECT_UNREF (ic_info->vars_saved);
3690 M17N_OBJECT_UNREF (ic_info->preceding_text);
3691 M17N_OBJECT_UNREF (ic_info->following_text);
3693 memset (ic_info, 0, sizeof (MInputContextInfo));
3697 re_init_ic (MInputContext *ic, int reload)
3699 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3700 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3701 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3703 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3704 preedit_changed = mtext_nchars (ic->preedit) > 0;
3705 cursor_pos_changed = ic->cursor_pos > 0;
3706 candidates_changed = 0;
3707 if (ic->candidate_list)
3709 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3710 M17N_OBJECT_UNREF (ic->candidate_list);
3711 ic->candidate_list = NULL;
3713 if (ic->candidate_show)
3715 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3716 ic->candidate_show = 0;
3718 if (ic->candidate_index > 0)
3720 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3721 ic->candidate_index = 0;
3722 ic->candidate_from = ic->candidate_to = 0;
3724 if (mtext_nchars (ic->produced) > 0)
3725 mtext_reset (ic->produced);
3726 if (mtext_nchars (ic->preedit) > 0)
3727 mtext_reset (ic->preedit);
3729 M17N_OBJECT_UNREF (ic->plist);
3730 ic->plist = mplist ();
3734 reload_im_info (im_info);
3735 if (! im_info->states)
3737 struct MIMState *state;
3739 M17N_OBJECT (state, free_state, MERROR_IM);
3740 state->name = msymbol ("init");
3741 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3742 MSTRUCT_CALLOC (state->map, MERROR_IM);
3743 im_info->states = mplist ();
3744 mplist_add (im_info->states, state->name, state);
3747 shift_state (ic, Mnil);
3749 ic->status_changed = status_changed;
3750 ic->preedit_changed = preedit_changed;
3751 ic->cursor_pos_changed = cursor_pos_changed;
3752 ic->candidates_changed = candidates_changed;
3756 reset_ic (MInputContext *ic, MSymbol ignore)
3758 MDEBUG_PRINT ("\n [IM] reset\n");
3763 open_im (MInputMethod *im)
3765 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3767 if (! im_info || ! im_info->states)
3768 MERROR (MERROR_IM, -1);
3775 close_im (MInputMethod *im)
3781 create_ic (MInputContext *ic)
3783 MInputContextInfo *ic_info;
3785 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3788 shift_state (ic, Mnil);
3793 destroy_ic (MInputContext *ic)
3800 check_reload (MInputContext *ic, MSymbol key)
3802 MInputMethodInfo *im_info = ic->im->info;
3803 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3807 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3811 MPLIST_DO (plist, plist)
3813 MSymbol this_key, alias;
3815 if (MPLIST_MTEXT_P (plist))
3817 MText *mt = MPLIST_MTEXT (plist);
3818 int c = mtext_ref_char (mt, 0);
3822 this_key = one_char_symbol[c];
3826 MPlist *pl = MPLIST_PLIST (plist);
3828 this_key = MPLIST_SYMBOL (pl);
3832 && (alias = msymbol_get (alias, M_key_alias))
3833 && alias != this_key);
3837 if (MPLIST_TAIL_P (plist))
3840 MDEBUG_PRINT ("\n [IM] reload");
3846 /** Handle the input key KEY in the current state and map of IC->info.
3847 If KEY is handled but no text is produced, return 0, otherwise
3853 filter (MInputContext *ic, MSymbol key, void *arg)
3855 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3856 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3859 if (check_reload (ic, key))
3862 if (! ic_info->state)
3864 ic_info->key_unhandled = 1;
3867 mtext_reset (ic->produced);
3868 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3869 M17N_OBJECT_UNREF (ic_info->preceding_text);
3870 M17N_OBJECT_UNREF (ic_info->following_text);
3871 ic_info->preceding_text = ic_info->following_text = NULL;
3872 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3873 ic_info->key_unhandled = 0;
3876 if (handle_key (ic) < 0)
3878 /* KEY was not handled. Delete it from the current key sequence. */
3879 if (ic_info->used > 0)
3881 memmove (ic_info->keys, ic_info->keys + 1,
3882 sizeof (int) * (ic_info->used - 1));
3884 if (ic_info->state_key_head > 0)
3885 ic_info->state_key_head--;
3886 if (ic_info->commit_key_head > 0)
3887 ic_info->commit_key_head--;
3889 /* This forces returning 1. */
3890 ic_info->key_unhandled = 1;
3896 reset_ic (ic, Mnil);
3897 ic_info->key_unhandled = 1;
3900 /* Break the loop if all keys were handled. */
3901 } while (ic_info->key_head < ic_info->used);
3903 /* If the current map is the root of the initial state, we should
3904 produce any preedit text in ic->produced. */
3905 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3906 preedit_commit (ic, 1);
3908 if (mtext_nchars (ic->produced) > 0)
3912 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3913 MSYMBOL_NAME (ic_info->state->name));
3914 for (i = 0; i < mtext_nchars (ic->produced); i++)
3915 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3919 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3920 Mlanguage, ic->im->language);
3922 if (ic_info->commit_key_head > 0)
3924 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3925 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3926 ic_info->used -= ic_info->commit_key_head;
3927 ic_info->key_head -= ic_info->commit_key_head;
3928 ic_info->state_key_head -= ic_info->commit_key_head;
3929 ic_info->commit_key_head = 0;
3931 if (ic_info->key_unhandled)
3934 ic_info->key_head = ic_info->state_key_head
3935 = ic_info->commit_key_head = 0;
3938 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3942 /** Return 1 if the last event or key was not handled, otherwise
3945 There is no need of looking up because ic->produced should already
3946 contain the produced text (if any).
3951 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3953 mtext_cat (mt, ic->produced);
3954 mtext_reset (ic->produced);
3955 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3959 /* Input method command handler. */
3961 /* List of all (global and local) commands.
3962 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3963 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3964 Global commands are stored as (t (t COMMAND ...)) */
3967 /* Input method variable handler. */
3970 /* Support functions for mdebug_dump_im. */
3973 dump_im_map (MPlist *map_list, int indent)
3976 MSymbol key = MPLIST_KEY (map_list);
3977 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3979 prefix = (char *) alloca (indent + 1);
3980 memset (prefix, 32, indent);
3981 prefix[indent] = '\0';
3983 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3984 if (map->map_actions)
3985 mdebug_dump_plist (map->map_actions, indent + 2);
3988 MPLIST_DO (map_list, map->submaps)
3990 fprintf (stderr, "\n%s ", prefix);
3991 dump_im_map (map_list, indent + 2);
3994 if (map->branch_actions)
3996 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3997 mdebug_dump_plist (map->branch_actions, indent + 4);
3998 fprintf (stderr, ")");
4000 fprintf (stderr, ")");
4005 dump_im_state (MIMState *state, int indent)
4010 prefix = (char *) alloca (indent + 1);
4011 memset (prefix, 32, indent);
4012 prefix[indent] = '\0';
4014 fprintf (stderr, "(%s", msymbol_name (state->name));
4015 if (state->map->submaps)
4017 MPLIST_DO (map_list, state->map->submaps)
4019 fprintf (stderr, "\n%s ", prefix);
4020 dump_im_map (map_list, indent + 2);
4023 fprintf (stderr, ")");
4031 Minput_driver = msymbol ("input-driver");
4033 Minput_preedit_start = msymbol ("input-preedit-start");
4034 Minput_preedit_done = msymbol ("input-preedit-done");
4035 Minput_preedit_draw = msymbol ("input-preedit-draw");
4036 Minput_status_start = msymbol ("input-status-start");
4037 Minput_status_done = msymbol ("input-status-done");
4038 Minput_status_draw = msymbol ("input-status-draw");
4039 Minput_candidates_start = msymbol ("input-candidates-start");
4040 Minput_candidates_done = msymbol ("input-candidates-done");
4041 Minput_candidates_draw = msymbol ("input-candidates-draw");
4042 Minput_set_spot = msymbol ("input-set-spot");
4043 Minput_focus_move = msymbol ("input-focus-move");
4044 Minput_focus_in = msymbol ("input-focus-in");
4045 Minput_focus_out = msymbol ("input-focus-out");
4046 Minput_toggle = msymbol ("input-toggle");
4047 Minput_reset = msymbol ("input-reset");
4048 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4049 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4050 Mcustomized = msymbol ("customized");
4051 Mconfigured = msymbol ("configured");
4052 Minherited = msymbol ("inherited");
4054 minput_default_driver.open_im = open_im;
4055 minput_default_driver.close_im = close_im;
4056 minput_default_driver.create_ic = create_ic;
4057 minput_default_driver.destroy_ic = destroy_ic;
4058 minput_default_driver.filter = filter;
4059 minput_default_driver.lookup = lookup;
4060 minput_default_driver.callback_list = mplist ();
4061 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4062 M17N_FUNC (reset_ic));
4063 minput_driver = &minput_default_driver;
4065 fully_initialized = 0;
4072 if (fully_initialized)
4074 free_im_list (im_info_list);
4076 free_im_list (im_custom_list);
4078 free_im_list (im_config_list);
4079 M17N_OBJECT_UNREF (load_im_info_keys);
4082 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4083 M17N_OBJECT_UNREF (minput_driver->callback_list);
4088 minput__char_to_key (int c)
4090 if (c < 0 || c >= 0x100)
4093 return one_char_symbol[c];
4097 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4102 /*** @addtogroup m17nInputMethod */
4107 @name Variables: Predefined symbols for callback commands.
4109 These are the predefined symbols that are used as the @c COMMAND
4110 argument of callback functions of an input method driver (see
4111 #MInputDriver::callback_list).
4113 Most of them do not require extra argument nor return any value;
4114 exceptions are these:
4116 Minput_get_surrounding_text: When a callback function assigned for
4117 this command is called, the first element of #MInputContext::plist
4118 has key #Minteger and the value specifies which portion of the
4119 surrounding text should be retrieved. If the value is positive,
4120 it specifies the number of characters following the current cursor
4121 position. If the value is negative, the absolute value specifies
4122 the number of characters preceding the current cursor position.
4123 If the value is zero, it means that the caller just wants to know
4124 if the surrounding text is currently supported or not.
4126 If the surrounding text is currently supported, the callback
4127 function must set the key of this element to #Mtext and the value
4128 to the retrieved M-text. The length of the M-text may be shorter
4129 than the requested number of characters, if the available text is
4130 not that long. The length can be zero in the worst case. Or, the
4131 length may be longer if an application thinks it is more efficient
4132 to return that length.
4134 If the surrounding text is not currently supported, the callback
4135 function should return without changing the first element of
4136 #MInputContext::plist.
4138 Minput_delete_surrounding_text: When a callback function assigned
4139 for this command is called, the first element of
4140 #MInputContext::plist has key #Minteger and the value specifies
4141 which portion of the surrounding text should be deleted in the
4142 same way as the case of Minput_get_surrounding_text. The callback
4143 function must delete the specified text. It should not alter
4144 #MInputContext::plist. */
4146 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4148 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4149 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4151 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4153 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4154 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4155 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4156 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4157 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4158 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4159 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4161 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4162 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4163 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4164 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4165 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4167 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4168 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4170 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4171 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4172 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4173 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4174 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4175 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4179 MSymbol Minput_preedit_start;
4180 MSymbol Minput_preedit_done;
4181 MSymbol Minput_preedit_draw;
4182 MSymbol Minput_status_start;
4183 MSymbol Minput_status_done;
4184 MSymbol Minput_status_draw;
4185 MSymbol Minput_candidates_start;
4186 MSymbol Minput_candidates_done;
4187 MSymbol Minput_candidates_draw;
4188 MSymbol Minput_set_spot;
4189 MSymbol Minput_toggle;
4190 MSymbol Minput_reset;
4191 MSymbol Minput_get_surrounding_text;
4192 MSymbol Minput_delete_surrounding_text;
4198 @name Variables: Predefined symbols for special input events.
4200 These are the predefined symbols that are used as the @c KEY
4201 argument of minput_filter (). */
4203 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4205 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4210 MSymbol Minput_focus_out;
4211 MSymbol Minput_focus_in;
4212 MSymbol Minput_focus_move;
4218 @name Variables: Predefined symbols used in input method information.
4220 These are the predefined symbols describing status of input method
4221 command and variable, and are used in a return value of
4222 minput_get_command () and minput_get_variable (). */
4224 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4226 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4227 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4231 MSymbol Mcustomized;
4232 MSymbol Mconfigured;
4238 @brief The default driver for internal input methods.
4240 The variable #minput_default_driver is the default driver for
4241 internal input methods.
4243 The member MInputDriver::open_im () searches the m17n database for
4244 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4245 $NAME\> and loads it.
4247 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4248 programmers responsibility to set it to a plist of proper callback
4249 functions. Otherwise, no feedback information (e.g. preedit text)
4250 can be shown to users.
4252 The macro M17N_INIT () sets the variable #minput_driver to the
4253 pointer to this driver so that all internal input methods use it.
4255 Therefore, unless @c minput_driver is set differently, the driver
4256 dependent arguments $ARG of the functions whose name begins with
4257 "minput_" are all ignored. */
4259 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4261 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4263 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4264 \< #Minput_method, $LANGUAGE, $NAME\>
4265 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4267 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4268 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4269 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4270 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4272 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4273 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4275 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4276 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4278 MInputDriver minput_default_driver;
4282 @brief The driver for internal input methods.
4284 The variable #minput_driver is a pointer to the input method
4285 driver that is used by internal input methods. The macro
4286 M17N_INIT () initializes it to a pointer to #minput_default_driver
4287 if <m17n<EM></EM>.h> is included. */
4289 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4291 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4292 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4293 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4294 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4296 MInputDriver *minput_driver;
4298 MSymbol Minput_driver;
4313 @brief Open an input method.
4315 The minput_open_im () function opens an input method whose
4316 language and name match $LANGUAGE and $NAME, and returns a pointer
4317 to the input method object newly allocated.
4319 This function at first decides a driver for the input method as
4322 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4323 #minput_driver is used.
4325 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4326 driver pointed to by the property value is used to open the input
4327 method. If $NAME has no such a property, @c NULL is returned.
4329 Then, the member MInputDriver::open_im () of the driver is
4332 $ARG is set in the member @c arg of the structure MInputMethod so
4333 that the driver can refer to it. */
4335 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4337 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4338 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4340 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4342 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4343 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4345 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4346 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4347 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4349 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4351 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4353 @latexonly \IPAlabel{minput_open} @endlatexonly
4358 minput_open_im (MSymbol language, MSymbol name, void *arg)
4361 MInputDriver *driver;
4365 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4366 msymbol_name (language), msymbol_name (name));
4370 MERROR (MERROR_IM, NULL);
4371 driver = minput_driver;
4375 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4377 MERROR (MERROR_IM, NULL);
4380 MSTRUCT_CALLOC (im, MERROR_IM);
4381 im->language = language;
4384 im->driver = *driver;
4385 if ((*im->driver.open_im) (im) < 0)
4387 MDEBUG_PRINT (" failed\n");
4391 MDEBUG_PRINT (" ok\n");
4398 @brief Close an input method.
4400 The minput_close_im () function closes the input method $IM, which
4401 must have been created by minput_open_im (). */
4404 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4406 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4407 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4410 minput_close_im (MInputMethod *im)
4412 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4413 msymbol_name (im->name), msymbol_name (im->language));
4414 (*im->driver.close_im) (im);
4416 MDEBUG_PRINT (" done\n");
4422 @brief Create an input context.
4424 The minput_create_ic () function creates an input context object
4425 associated with input method $IM, and calls callback functions
4426 corresponding to #Minput_preedit_start, #Minput_status_start, and
4427 #Minput_status_draw in this order.
4430 If an input context is successfully created, minput_create_ic ()
4431 returns a pointer to it. Otherwise it returns @c NULL. */
4434 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4436 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4437 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4438 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4439 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4442 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4443 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4447 minput_create_ic (MInputMethod *im, void *arg)
4451 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4452 msymbol_name (im->name), msymbol_name (im->language));
4453 MSTRUCT_CALLOC (ic, MERROR_IM);
4456 ic->preedit = mtext ();
4457 ic->candidate_list = NULL;
4458 ic->produced = mtext ();
4459 ic->spot.x = ic->spot.y = 0;
4461 ic->plist = mplist ();
4462 if ((*im->driver.create_ic) (ic) < 0)
4464 MDEBUG_PRINT (" failed\n");
4465 M17N_OBJECT_UNREF (ic->preedit);
4466 M17N_OBJECT_UNREF (ic->produced);
4467 M17N_OBJECT_UNREF (ic->plist);
4472 if (im->driver.callback_list)
4474 minput_callback (ic, Minput_preedit_start);
4475 minput_callback (ic, Minput_status_start);
4476 minput_callback (ic, Minput_status_draw);
4479 MDEBUG_PRINT (" ok\n");
4486 @brief Destroy an input context.
4488 The minput_destroy_ic () function destroys the input context $IC,
4489 which must have been created by minput_create_ic (). It calls
4490 callback functions corresponding to #Minput_preedit_done,
4491 #Minput_status_done, and #Minput_candidates_done in this order. */
4494 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4496 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4497 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4498 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4499 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4500 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4504 minput_destroy_ic (MInputContext *ic)
4506 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4507 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4508 if (ic->im->driver.callback_list)
4510 minput_callback (ic, Minput_preedit_done);
4511 minput_callback (ic, Minput_status_done);
4512 minput_callback (ic, Minput_candidates_done);
4514 (*ic->im->driver.destroy_ic) (ic);
4515 M17N_OBJECT_UNREF (ic->preedit);
4516 M17N_OBJECT_UNREF (ic->produced);
4517 M17N_OBJECT_UNREF (ic->plist);
4518 MDEBUG_PRINT (" done\n");
4525 @brief Filter an input key.
4527 The minput_filter () function filters input key $KEY according to
4528 input context $IC, and calls callback functions corresponding to
4529 #Minput_preedit_draw, #Minput_status_draw, and
4530 #Minput_candidates_draw if the preedit text, the status, and the
4531 current candidate are changed respectively.
4533 To make the input method commit the current preedit text (if any)
4534 and shift to the initial state, call this function with #Mnil as
4537 To inform the input method about the focus-out event, call this
4538 function with #Minput_focus_out as $KEY.
4540 To inform the input method about the focus-in event, call this
4541 function with #Minput_focus_in as $KEY.
4543 To inform the input method about the focus-move event (i.e. input
4544 spot change within the same input context), call this function
4545 with #Minput_focus_move as $KEY.
4548 If $KEY is filtered out, this function returns 1. In that case,
4549 the caller should discard the key. Otherwise, it returns 0, and
4550 the caller should handle the key, for instance, by calling the
4551 function minput_lookup () with the same key. */
4554 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4556 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4557 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4558 #Minput_preedit_draw, #Minput_status_draw,
4559 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4562 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4563 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4564 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4565 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4567 @latexonly \IPAlabel{minput_filter} @endlatexonly
4571 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4578 if (ic->im->driver.callback_list
4579 && mtext_nchars (ic->preedit) > 0)
4580 minput_callback (ic, Minput_preedit_draw);
4582 ret = (*ic->im->driver.filter) (ic, key, arg);
4584 if (ic->im->driver.callback_list)
4586 if (ic->preedit_changed)
4587 minput_callback (ic, Minput_preedit_draw);
4588 if (ic->status_changed)
4589 minput_callback (ic, Minput_status_draw);
4590 if (ic->candidates_changed)
4591 minput_callback (ic, Minput_candidates_draw);
4600 @brief Look up a text produced in the input context.
4602 The minput_lookup () function looks up a text in the input context
4603 $IC. $KEY must be identical to the one that was used in the previous call of
4606 If a text was produced by the input method, it is concatenated
4609 This function calls #MInputDriver::lookup .
4612 If $KEY was correctly handled by the input method, this function
4613 returns 0. Otherwise, it returns -1, even though some text
4614 might be produced in $MT. */
4617 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4619 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4620 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4622 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4625 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4628 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4629 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4630 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4632 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4635 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4637 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4642 @brief Set the spot of the input context.
4644 The minput_set_spot () function sets the spot of input context $IC
4645 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4646 The semantics of these values depends on the input method driver.
4648 For instance, a driver designed to work in a CUI environment may
4649 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4650 $DESCENT . A driver designed to work in a window system may
4651 interpret $X and $Y as the pixel offsets relative to the origin of the
4652 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4653 descent pixels of the line at ($X . $Y ).
4655 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4657 $MT and $POS are the M-text and the character position at the spot.
4658 $MT may be @c NULL, in which case, the input method cannot get
4659 information about the text around the spot. */
4662 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4664 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4665 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4666 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4668 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4669 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4670 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4671 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4672 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4673 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4675 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4677 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4678 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4682 minput_set_spot (MInputContext *ic, int x, int y,
4683 int ascent, int descent, int fontsize,
4688 ic->spot.ascent = ascent;
4689 ic->spot.descent = descent;
4690 ic->spot.fontsize = fontsize;
4693 if (ic->im->driver.callback_list)
4694 minput_callback (ic, Minput_set_spot);
4699 @brief Toggle input method.
4701 The minput_toggle () function toggles the input method associated
4702 with input context $IC. */
4704 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4706 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4707 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4711 minput_toggle (MInputContext *ic)
4713 if (ic->im->driver.callback_list)
4714 minput_callback (ic, Minput_toggle);
4715 ic->active = ! ic->active;
4721 @brief Reset an input context.
4723 The minput_reset_ic () function resets input context $IC by
4724 calling a callback function corresponding to #Minput_reset. It
4725 resets the status of $IC to its initial one. As the
4726 current preedit text is deleted without commitment, if necessary,
4727 call minput_filter () with the arg @r key #Mnil to force the input
4728 method to commit the preedit in advance. */
4731 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4733 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4734 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4735 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4736 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4737 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4738 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4741 minput_reset_ic (MInputContext *ic)
4743 if (ic->im->driver.callback_list)
4744 minput_callback (ic, Minput_reset);
4750 @brief Get title and icon filename of an input method.
4752 The minput_get_title_icon () function returns a plist containing a
4753 title and icon filename (if any) of an input method specified by
4754 $LANGUAGE and $NAME.
4756 The first element of the plist has key #Mtext and the value is an
4757 M-text of the title for identifying the input method. The second
4758 element (if any) has key #Mtext and the value is an M-text of the
4759 icon image (absolute) filename for the same purpose.
4762 If there exists a specified input method and it defines an title,
4763 a plist is returned. Otherwise, NULL is returned. The caller
4764 must free the plist by m17n_object_unref (). */
4766 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4768 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4769 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4772 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4773 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4774 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4777 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4778 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4779 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4782 minput_get_title_icon (MSymbol language, MSymbol name)
4784 MInputMethodInfo *im_info;
4791 im_info = get_im_info (language, name, Mnil, Mtitle);
4792 if (! im_info || !im_info->title)
4794 mt = mtext_get_prop (im_info->title, 0, Mtext);
4796 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4799 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4802 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4803 (char *) MSYMBOL_NAME (name));
4804 file = mdatabase__find_file (buf);
4805 if (! file && language == Mt)
4807 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4808 file = mdatabase__find_file (buf);
4813 mplist_add (plist, Mtext, im_info->title);
4816 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4818 mplist_add (plist, Mtext, mt);
4819 M17N_OBJECT_UNREF (mt);
4827 @brief Get description text of an input method.
4829 The minput_get_description () function returns an M-text that
4830 describes the input method specified by $LANGUAGE and $NAME.
4833 If the specified input method has a description text, a pointer to
4834 #MText is returned. The caller has to free it by m17n_object_unref ().
4835 If the input method does not have a description text, @c NULL is
4838 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4840 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4841 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4844 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4845 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4846 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4847 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4850 minput_get_description (MSymbol language, MSymbol name)
4852 MInputMethodInfo *im_info;
4860 extra = language, language = Mt;
4862 im_info = get_im_info (language, name, extra, Mdescription);
4863 if (! im_info || ! im_info->description)
4865 M17N_OBJECT_REF (im_info->description);
4866 return im_info->description;
4872 @brief Get information about input method command(s).
4874 The minput_get_command () function returns information about
4875 the command $COMMAND of the input method specified by $LANGUAGE and
4876 $NAME. An input method command is a pseudo key event to which one
4877 or more actual input key sequences are assigned.
4879 There are two kinds of commands, global and local. A global
4880 command has a global definition, and the description and the key
4881 assignment may be inherited by a local command. Each input method
4882 defines a local command which has a local key assignment. It may
4883 also declare a local command that inherits the definition of a
4884 global command of the same name.
4886 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4887 information about a global command. Otherwise information about a
4888 local command is returned.
4890 If $COMMAND is #Mnil, information about all commands is returned.
4892 The return value is a @e well-formed plist (@ref m17nPlist) of this
4895 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4897 @c NAME is a symbol representing the command name.
4899 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4900 command has no description.
4902 @c STATUS is a symbol representing how the key assignment is decided.
4903 The value is #Mnil (the default key assignment), #Mcustomized (the
4904 key assignment is customized by per-user customization file), or
4905 #Mconfigured (the key assignment is set by the call of
4906 minput_config_command ()). For a local command only, it may also
4907 be #Minherited (the key assignment is inherited from the
4908 corresponding global command).
4910 @c KEYSEQ is a plist of one or more symbols representing a key
4911 sequence assigned to the command. If there's no KEYSEQ, the
4912 command is currently disabled (i.e. no key sequence can trigger
4913 actions of the command).
4915 If $COMMAND is not #Mnil, the first element of the returned plist
4916 contains the information about $COMMAND.
4920 If the requested information was found, a pointer to a non-empty
4921 plist is returned. As the plist is kept in the library, the
4922 caller must not modify nor free it.
4924 Otherwise (the specified input method or the specified command
4925 does not exist), @c NULL is returned. */
4927 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4929 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4930 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4931 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4932 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4934 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4935 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4936 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4937 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4938 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4940 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4941 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4944 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4946 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4949 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4951 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4953 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4956 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4957 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4958 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4959 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4960 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4961 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4964 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4965 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4966 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4967 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4969 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4970 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4974 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4975 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4978 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4983 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4985 /* Return a description of the command COMMAND of the input method
4986 specified by LANGUAGE and NAME. */
4987 MPlist *cmd = minput_get_command (langauge, name, command);
4992 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4993 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4994 return (mplist_key (plist) == Mtext
4995 ? (MText *) mplist_value (plist)
5001 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5003 MInputMethodInfo *im_info;
5007 im_info = get_im_info (language, name, Mnil, Mcommand);
5009 || ! im_info->configured_cmds
5010 || MPLIST_TAIL_P (im_info->configured_cmds))
5012 if (command == Mnil)
5013 return im_info->configured_cmds;
5014 return mplist__assq (im_info->configured_cmds, command);
5020 @brief Configure the key sequence of an input method command.
5022 The minput_config_command () function assigns a list of key
5023 sequences $KEYSEQLIST to the command $COMMAND of the input method
5024 specified by $LANGUAGE and $NAME.
5026 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5027 sequences, and each key sequence must be a plist of symbols.
5029 If $KEYSEQLIST is an empty plist, any configuration and
5030 customization of the command are cancelled, and default key
5031 sequences become effective.
5033 If $KEYSEQLIST is NULL, the configuration of the command is
5034 canceled, and the original key sequences (what saved in per-user
5035 customization file, or the default one) become effective.
5037 In the latter two cases, $COMMAND can be #Mnil to make all the
5038 commands of the input method the target of the operation.
5040 If $NAME is #Mnil, this function configures the key assignment of a
5041 global command, not that of a specific input method.
5043 The configuration takes effect for input methods opened or
5044 re-opened later in the current session. In order to make the
5045 configuration take effect for the future session, it must be saved
5046 in a per-user customization file by the function
5047 minput_save_config ().
5050 If the operation was successful, this function returns 0,
5051 otherwise returns -1. The operation fails in these cases:
5053 <li>$KEYSEQLIST is not in a valid form.
5054 <li>$COMMAND is not available for the input method.
5055 <li>$LANGUAGE and $NAME do not specify an existing input method.
5059 minput_get_commands (), minput_save_config ().
5062 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5064 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5065 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5066 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5068 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5069 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5071 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5072 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5074 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5075 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5076 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5078 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5079 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5081 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5082 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5084 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5085 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5086 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5087 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5091 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5093 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5094 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5095 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5099 minput_get_commands (), minput_save_config ().
5103 /* Add "C-x u" to the "start" command of Unicode input method. */
5105 MSymbol start_command = msymbol ("start");
5106 MSymbol unicode = msymbol ("unicode");
5107 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5109 /* At first get the current key-sequence assignment. */
5110 cmd = minput_get_command (Mt, unicode, start_command);
5113 /* The input method does not have the command "start". Here
5114 should come some error handling code. */
5116 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5117 Extract the part (KEY-SEQUENCE ...). */
5118 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5119 /* Copy it because we should not modify it directly. */
5120 key_seq_list = mplist_copy (plist);
5122 key_seq = mplist ();
5123 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5124 mplist_add (key_seq, Msymbol, msymbol ("u"));
5125 mplist_add (key_seq_list, Mplist, key_seq);
5126 m17n_object_unref (key_seq);
5128 minput_config_command (Mt, unicode, start_command, key_seq_list);
5129 m17n_object_unref (key_seq_list);
5134 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5137 MInputMethodInfo *im_info, *config;
5142 im_info = get_im_info (language, name, Mnil, Mcommand);
5144 MERROR (MERROR_IM, -1);
5145 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5147 || ! mplist__assq (im_info->configured_cmds, command)))
5148 MERROR (MERROR_IM, -1);
5149 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5151 MPLIST_DO (plist, keyseqlist)
5152 if (! check_command_keyseq (plist))
5153 MERROR (MERROR_IM, -1);
5156 config = get_config_info (im_info);
5159 if (! im_config_list)
5160 im_config_list = mplist ();
5161 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5162 config->cmds = mplist ();
5163 config->vars = mplist ();
5166 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5167 /* Nothing to do. */
5170 if (command == Mnil)
5174 /* Cancal the configuration. */
5175 if (MPLIST_TAIL_P (config->cmds))
5177 mplist_set (config->cmds, Mnil, NULL);
5181 /* Cancal the customization. */
5182 MInputMethodInfo *custom = get_custom_info (im_info);
5184 if (MPLIST_TAIL_P (config->cmds)
5185 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5186 /* Nothing to do. */
5188 mplist_set (config->cmds, Mnil, NULL);
5189 MPLIST_DO (plist, custom->cmds)
5191 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5193 mplist_add (plist, Msymbol, command);
5194 mplist_push (config->cmds, Mplist, plist);
5195 M17N_OBJECT_UNREF (plist);
5201 plist = mplist__assq (config->cmds, command);
5204 /* Cancel the configuration. */
5207 mplist__pop_unref (plist);
5209 else if (MPLIST_TAIL_P (keyseqlist))
5211 /* Cancel the customization. */
5212 MInputMethodInfo *custom = get_custom_info (im_info);
5213 int no_custom = (! custom || ! custom->cmds
5214 || ! mplist__assq (custom->cmds, command));
5220 mplist_add (config->cmds, Mplist, plist);
5221 M17N_OBJECT_UNREF (plist);
5222 plist = mplist_add (plist, Msymbol, command);
5227 mplist__pop_unref (plist);
5230 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5231 plist = MPLIST_NEXT (plist);
5232 mplist_set (plist, Mnil, NULL);
5242 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5243 if (! MPLIST_TAIL_P (plist))
5244 mplist_set (plist, Mnil, NULL);
5249 mplist_add (config->cmds, Mplist, plist);
5250 M17N_OBJECT_UNREF (plist);
5251 plist = mplist_add (plist, Msymbol, command);
5252 plist = MPLIST_NEXT (plist);
5254 MPLIST_DO (keyseqlist, keyseqlist)
5256 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5257 plist = mplist_add (plist, Mplist, pl);
5258 M17N_OBJECT_UNREF (pl);
5262 config_all_commands (im_info);
5263 im_info->tick = time (NULL);
5270 @brief Get information about input method variable(s).
5272 The minput_get_variable () function returns information about
5273 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5274 An input method variable controls behavior of an input method.
5276 There are two kinds of variables, global and local. A global
5277 variable has a global definition, and the description and the value
5278 may be inherited by a local variable. Each input method defines a
5279 local variable which has local value. It may also declare a
5280 local variable that inherits definition of a global variable of
5283 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5284 variable is returned. Otherwise information about a local variable
5287 If $VARIABLE is #Mnil, information about all variables is
5290 The return value is a @e well-formed plist (@ref m17nPlist) of this
5293 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5295 @c NAME is a symbol representing the variable name.
5297 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5298 variable has no description.
5300 @c STATUS is a symbol representing how the value is decided. The
5301 value is #Mnil (the default value), #Mcustomized (the value is
5302 customized by per-user customization file), or #Mconfigured (the
5303 value is set by the call of minput_config_variable ()). For a
5304 local variable only, it may also be #Minherited (the value is
5305 inherited from the corresponding global variable).
5307 @c VALUE is the initial value of the variable. If the key of this
5308 element is #Mt, the variable has no initial value. Otherwise, the
5309 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5312 @c VALID-VALUEs (if any) specify which values the variable can have.
5313 They have the same type (i.e. having the same key) as @c VALUE except
5314 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5315 may be a plist of two integers specifying the range of possible
5318 If there no @c VALID-VALUE, the variable can have any value as long
5319 as the type is the same as @c VALUE.
5321 If $VARIABLE is not #Mnil, the first element of the returned plist
5322 contains the information about $VARIABLE.
5326 If the requested information was found, a pointer to a non-empty
5327 plist is returned. As the plist is kept in the library, the
5328 caller must not modify nor free it.
5330 Otherwise (the specified input method or the specified variable
5331 does not exist), @c NULL is returned. */
5333 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5335 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5336 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5337 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5339 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5340 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5341 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5342 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5345 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5346 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5348 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5350 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5352 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5355 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5357 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5360 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5361 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5362 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5363 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5364 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5365 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5367 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5368 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5369 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5371 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5372 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5373 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5374 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5376 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5379 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5380 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5384 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5385 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5388 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5392 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5394 MInputMethodInfo *im_info;
5398 im_info = get_im_info (language, name, Mnil, Mvariable);
5399 if (! im_info || ! im_info->configured_vars)
5401 if (variable == Mnil)
5402 return im_info->configured_vars;
5403 return mplist__assq (im_info->configured_vars, variable);
5409 @brief Configure the value of an input method variable.
5411 The minput_config_variable () function assigns $VALUE to the
5412 variable $VARIABLE of the input method specified by $LANGUAGE and
5415 If $VALUE is a non-empty plist, it must be a plist of one element
5416 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5417 the corresponding type. That value is assigned to the variable.
5419 If $VALUE is an empty plist, any configuration and customization
5420 of the variable are canceled, and the default value is assigned to
5423 If $VALUE is NULL, the configuration of the variable is canceled,
5424 and the original value (what saved in per-user customization file,
5425 or the default value) is assigned to the variable.
5427 In the latter two cases, $VARIABLE can be #Mnil to make all the
5428 variables of the input method the target of the operation.
5430 If $NAME is #Mnil, this function configures the value of global
5431 variable, not that of a specific input method.
5433 The configuration takes effect for input methods opened or
5434 re-opened later in the current session. To make the configuration
5435 take effect for the future session, it must be saved in a per-user
5436 customization file by the function minput_save_config ().
5440 If the operation was successful, this function returns 0,
5441 otherwise returns -1. The operation fails in these cases:
5443 <li>$VALUE is not in a valid form, the type does not match the
5444 definition, or the value is our of range.
5445 <li>$VARIABLE is not available for the input method.
5446 <li>$LANGUAGE and $NAME do not specify an existing input method.
5450 minput_get_variable (), minput_save_config (). */
5452 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5454 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5455 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5457 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5458 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5459 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5461 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5462 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5464 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5465 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5467 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5468 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5470 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5471 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5473 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5474 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5475 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5476 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5480 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5482 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5483 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5484 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5488 minput_get_commands (), minput_save_config ().
5491 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5494 MInputMethodInfo *im_info, *config;
5499 im_info = get_im_info (language, name, Mnil, Mvariable);
5501 MERROR (MERROR_IM, -1);
5502 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5504 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5505 MERROR (MERROR_IM, -1);
5507 if (value && ! MPLIST_TAIL_P (value))
5509 plist = MPLIST_PLIST (plist);
5510 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5511 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5512 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5513 if (MPLIST_KEY (plist) != Mt
5514 && ! check_variable_value (value, plist))
5515 MERROR (MERROR_IM, -1);
5518 config = get_config_info (im_info);
5521 if (! im_config_list)
5522 im_config_list = mplist ();
5523 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5524 config->cmds = mplist ();
5525 config->vars = mplist ();
5528 if (! value && MPLIST_TAIL_P (config->vars))
5529 /* Nothing to do. */
5532 if (variable == Mnil)
5536 /* Cancel the configuration. */
5537 if (MPLIST_TAIL_P (config->vars))
5539 mplist_set (config->vars, Mnil, NULL);
5543 /* Cancel the customization. */
5544 MInputMethodInfo *custom = get_custom_info (im_info);
5546 if (MPLIST_TAIL_P (config->vars)
5547 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5548 /* Nothing to do. */
5550 mplist_set (config->vars, Mnil, NULL);
5551 MPLIST_DO (plist, custom->vars)
5553 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5555 mplist_add (plist, Msymbol, variable);
5556 mplist_push (config->vars, Mplist, plist);
5557 M17N_OBJECT_UNREF (plist);
5563 plist = mplist__assq (config->vars, variable);
5566 /* Cancel the configuration. */
5569 mplist__pop_unref (plist);
5571 else if (MPLIST_TAIL_P (value))
5573 /* Cancel the customization. */
5574 MInputMethodInfo *custom = get_custom_info (im_info);
5575 int no_custom = (! custom || ! custom->vars
5576 || ! mplist__assq (custom->vars, variable));
5582 mplist_add (config->vars, Mplist, plist);
5583 M17N_OBJECT_UNREF (plist);
5584 plist = mplist_add (plist, Msymbol, variable);
5589 mplist__pop_unref (plist);
5592 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5593 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5594 mplist_set (plist, Mnil ,NULL);
5602 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5603 if (! MPLIST_TAIL_P (plist))
5604 mplist_set (plist, Mnil, NULL);
5609 mplist_add (config->vars, Mplist, plist);
5610 M17N_OBJECT_UNREF (plist);
5611 plist = mplist_add (plist, Msymbol, variable);
5612 plist = MPLIST_NEXT (plist);
5614 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5617 config_all_variables (im_info);
5618 im_info->tick = time (NULL);
5625 @brief Get the name of per-user customization file.
5627 The minput_config_file () function returns the absolute path name
5628 of per-user customization file into which minput_save_config ()
5629 save configurations. It is usually @c config.mic under the
5630 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5631 directory). It is not assured that the file of the returned name
5632 exists nor is readable/writable. If minput_save_config () fails
5633 and returns -1, an application program might check the file, make
5634 it writable (if possible), and try minput_save_config () again.
5638 This function returns a string. As the string is kept in the
5639 library, the caller must not modify nor free it.
5642 minput_save_config ()
5645 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5647 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5648 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5649 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5650 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5651 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5652 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5653 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5658 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5659 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5662 minput_save_config ()
5666 minput_config_file ()
5670 return mdatabase__file (im_custom_mdb);
5676 @brief Save configurations in per-user customization file.
5678 The minput_save_config () function saves the configurations done
5679 so far in the current session into the per-user customization
5684 If the operation was successful, 1 is returned. If the per-user
5685 customization file is currently locked, 0 is returned. In that
5686 case, the caller may wait for a while and try again. If the
5687 configuration file is not writable, -1 is returned. In that case,
5688 the caller may check the name of the file by calling
5689 minput_config_file (), make it writable if possible, and try
5693 minput_config_file () */
5695 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5697 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5698 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5702 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5703 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5704 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5705 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5709 minput_config_file () */
5712 minput_save_config (void)
5714 MPlist *data, *tail, *plist, *p, *elt;
5718 ret = mdatabase__lock (im_custom_mdb);
5721 if (! im_config_list)
5723 update_custom_info ();
5724 if (! im_custom_list)
5725 im_custom_list = mplist ();
5727 /* At first, reflect configuration in customization. */
5728 MPLIST_DO (plist, im_config_list)
5730 MPlist *pl = MPLIST_PLIST (plist);
5731 MSymbol language, name, extra, command, variable;
5732 MInputMethodInfo *custom, *config;
5734 language = MPLIST_SYMBOL (pl);
5735 pl = MPLIST_NEXT (pl);
5736 name = MPLIST_SYMBOL (pl);
5737 pl = MPLIST_NEXT (pl);
5738 extra = MPLIST_SYMBOL (pl);
5739 pl = MPLIST_NEXT (pl);
5740 config = MPLIST_VAL (pl);
5741 custom = get_custom_info (config);
5743 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5745 MPLIST_DO (pl, config->cmds)
5747 elt = MPLIST_PLIST (pl);
5748 command = MPLIST_SYMBOL (elt);
5750 p = mplist__assq (custom->cmds, command);
5752 custom->cmds = mplist (), p = NULL;
5753 elt = MPLIST_NEXT (elt);
5756 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5757 mplist_set (p, Mnil, NULL);
5762 mplist_add (custom->cmds, Mplist, p);
5763 M17N_OBJECT_UNREF (p);
5764 mplist_add (p, Msymbol, command);
5765 p = mplist_add (p, Msymbol, Mnil);
5766 p = MPLIST_NEXT (p);
5768 mplist__conc (p, elt);
5771 MPLIST_DO (pl, config->vars)
5773 elt = MPLIST_PLIST (pl);
5774 variable = MPLIST_SYMBOL (elt);
5776 p = mplist__assq (custom->vars, variable);
5778 custom->vars = mplist (), p = NULL;
5779 elt = MPLIST_NEXT (elt);
5782 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5783 mplist_set (p, Mnil, NULL);
5788 mplist_add (custom->vars, Mplist, p);
5789 M17N_OBJECT_UNREF (p);
5790 mplist_add (p, Msymbol, variable);
5791 p = mplist_add (p, Msymbol, Mnil);
5792 p = MPLIST_NEXT (p);
5794 mplist__conc (p, elt);
5797 free_im_list (im_config_list);
5798 im_config_list = NULL;
5800 /* Next, reflect customization to the actual plist to be written. */
5801 data = tail = mplist ();
5802 MPLIST_DO (plist, im_custom_list)
5804 MPlist *pl = MPLIST_PLIST (plist);
5805 MSymbol language, name, extra;
5806 MInputMethodInfo *custom, *im_info;
5808 language = MPLIST_SYMBOL (pl);
5809 pl = MPLIST_NEXT (pl);
5810 name = MPLIST_SYMBOL (pl);
5811 pl = MPLIST_NEXT (pl);
5812 extra = MPLIST_SYMBOL (pl);
5813 pl = MPLIST_NEXT (pl);
5814 custom = MPLIST_VAL (pl);
5815 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5816 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5818 im_info = lookup_im_info (im_info_list, language, name, extra);
5822 config_all_commands (im_info);
5824 config_all_variables (im_info);
5828 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5830 MPLIST_DO (p, custom->cmds)
5831 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5833 if (! MPLIST_TAIL_P (p))
5837 mplist_add (elt, Mplist, pl);
5838 M17N_OBJECT_UNREF (pl);
5839 pl = mplist_add (pl, Msymbol, Mcommand);
5840 MPLIST_DO (p, custom->cmds)
5841 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5842 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5845 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5847 MPLIST_DO (p, custom->vars)
5848 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5850 if (! MPLIST_TAIL_P (p))
5855 mplist_add (elt, Mplist, pl);
5856 M17N_OBJECT_UNREF (pl);
5857 pl = mplist_add (pl, Msymbol, Mvariable);
5858 MPLIST_DO (p, custom->vars)
5859 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5860 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5866 mplist_push (elt, Mplist, pl);
5867 M17N_OBJECT_UNREF (pl);
5868 pl = mplist_add (pl, Msymbol, Minput_method);
5869 pl = mplist_add (pl, Msymbol, language);
5870 pl = mplist_add (pl, Msymbol, name);
5872 pl = mplist_add (pl, Msymbol, extra);
5873 tail = mplist_add (tail, Mplist, elt);
5874 M17N_OBJECT_UNREF (elt);
5878 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5879 ret = mdatabase__save (im_custom_mdb, data);
5880 mdatabase__unlock (im_custom_mdb);
5881 M17N_OBJECT_UNREF (data);
5882 return (ret < 0 ? -1 : 1);
5889 @name Obsolete functions
5892 @name Obsolete ¤Ê´Ø¿ô
5898 @brief Get a list of variables of an input method (obsolete).
5900 This function is obsolete. Use minput_get_variable () instead.
5902 The minput_get_variables () function returns a plist (#MPlist) of
5903 variables used to control the behavior of the input method
5904 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5905 (@ref m17nPlist) of the following format:
5908 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5909 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5913 @c VARNAME is a symbol representing the variable name.
5915 @c DOC-MTEXT is an M-text describing the variable.
5917 @c DEFAULT-VALUE is the default value of the variable. It is a
5918 symbol, integer, or M-text.
5920 @c VALUEs (if any) specifies the possible values of the variable.
5921 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5922 @c TO), where @c FROM and @c TO specifies a range of possible
5925 For instance, suppose an input method has the variables:
5927 @li name:intvar, description:"value is an integer",
5928 initial value:0, value-range:0..3,10,20
5930 @li name:symvar, description:"value is a symbol",
5931 initial value:nil, value-range:a, b, c, nil
5933 @li name:txtvar, description:"value is an M-text",
5934 initial value:empty text, no value-range (i.e. any text)
5936 Then, the returned plist is as follows.
5939 (intvar ("value is an integer" 0 (0 3) 10 20)
5940 symvar ("value is a symbol" nil a b c nil)
5941 txtvar ("value is an M-text" ""))
5945 If the input method uses any variables, a pointer to #MPlist is
5946 returned. As the plist is kept in the library, the caller must not
5947 modify nor free it. If the input method does not use any
5948 variable, @c NULL is returned. */
5950 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5952 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5953 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5954 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5958 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5959 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5963 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5965 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5967 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5970 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5971 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5972 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5974 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5976 @li name:intvar, ÀâÌÀ:"value is an integer",
5977 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5979 @li name:symvar, ÀâÌÀ:"value is a symbol",
5980 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5982 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5983 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5985 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5988 (intvar ("value is an integer" 0 (0 3) 10 20)
5989 symvar ("value is a symbol" nil a b c nil)
5990 txtvar ("value is an M-text" ""))
5994 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5995 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5996 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5999 minput_get_variables (MSymbol language, MSymbol name)
6001 MInputMethodInfo *im_info;
6006 im_info = get_im_info (language, name, Mnil, Mvariable);
6007 if (! im_info || ! im_info->configured_vars)
6010 M17N_OBJECT_UNREF (im_info->bc_vars);
6011 im_info->bc_vars = mplist ();
6012 MPLIST_DO (vars, im_info->configured_vars)
6014 MPlist *plist = MPLIST_PLIST (vars);
6015 MPlist *elt = mplist ();
6017 mplist_push (im_info->bc_vars, Mplist, elt);
6018 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6019 elt = MPLIST_NEXT (elt);
6020 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6021 M17N_OBJECT_UNREF (elt);
6023 return im_info->bc_vars;
6029 @brief Set the initial value of an input method variable.
6031 The minput_set_variable () function sets the initial value of
6032 input method variable $VARIABLE to $VALUE for the input method
6033 specified by $LANGUAGE and $NAME.
6035 By default, the initial value is 0.
6037 This setting gets effective in a newly opened input method.
6040 If the operation was successful, 0 is returned. Otherwise -1 is
6041 returned, and #merror_code is set to #MERROR_IM. */
6043 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6045 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6046 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6047 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6049 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6051 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6054 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6055 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6058 minput_set_variable (MSymbol language, MSymbol name,
6059 MSymbol variable, void *value)
6062 MInputMethodInfo *im_info;
6067 if (variable == Mnil)
6068 MERROR (MERROR_IM, -1);
6069 plist = minput_get_variable (language, name, variable);
6070 plist = MPLIST_PLIST (plist);
6071 plist = MPLIST_NEXT (plist);
6073 mplist_add (pl, MPLIST_KEY (plist), value);
6074 ret = minput_config_variable (language, name, variable, pl);
6075 M17N_OBJECT_UNREF (pl);
6078 im_info = get_im_info (language, name, Mnil, Mvariable);
6087 @brief Get information about input method commands.
6089 The minput_get_commands () function returns information about
6090 input method commands of the input method specified by $LANGUAGE
6091 and $NAME. An input method command is a pseudo key event to which
6092 one or more actual input key sequences are assigned.
6094 There are two kinds of commands, global and local. Global
6095 commands are used by multiple input methods for the same purpose,
6096 and have global key assignments. Local commands are used only by
6097 a specific input method, and have only local key assignments.
6099 Each input method may locally change key assignments for global
6100 commands. The global key assignment for a global command is
6101 effective only when the current input method does not have local
6102 key assignments for that command.
6104 If $NAME is #Mnil, information about global commands is returned.
6105 In this case $LANGUAGE is ignored.
6107 If $NAME is not #Mnil, information about those commands that have
6108 local key assignments in the input method specified by $LANGUAGE
6109 and $NAME is returned.
6112 If no input method commands are found, this function returns @c NULL.
6114 Otherwise, a pointer to a plist is returned. The key of each
6115 element in the plist is a symbol representing a command, and the
6116 value is a plist of the form COMMAND-INFO described below.
6118 The first element of COMMAND-INFO has the key #Mtext, and the
6119 value is an M-text describing the command.
6121 If there are no more elements, that means no key sequences are
6122 assigned to the command. Otherwise, each of the remaining
6123 elements has the key #Mplist, and the value is a plist whose keys are
6124 #Msymbol and values are symbols representing input keys, which are
6125 currently assigned to the command.
6127 As the returned plist is kept in the library, the caller must not
6128 modify nor free it. */
6130 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6132 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6133 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6134 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6135 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6137 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6138 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6139 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6140 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6142 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6143 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6144 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6147 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6148 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6150 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6151 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6155 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6157 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6158 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6159 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6161 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6162 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6163 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6166 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6167 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6168 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6169 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6170 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6172 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6173 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6176 minput_get_commands (MSymbol language, MSymbol name)
6178 MInputMethodInfo *im_info;
6183 im_info = get_im_info (language, name, Mnil, Mcommand);
6184 if (! im_info || ! im_info->configured_vars)
6186 M17N_OBJECT_UNREF (im_info->bc_cmds);
6187 im_info->bc_cmds = mplist ();
6188 MPLIST_DO (cmds, im_info->configured_cmds)
6190 MPlist *plist = MPLIST_PLIST (cmds);
6191 MPlist *elt = mplist ();
6193 mplist_push (im_info->bc_cmds, Mplist, elt);
6194 mplist_add (elt, MPLIST_SYMBOL (plist),
6195 mplist_copy (MPLIST_NEXT (plist)));
6196 M17N_OBJECT_UNREF (elt);
6198 return im_info->bc_cmds;
6204 @brief Assign a key sequence to an input method command (obsolete).
6206 This function is obsolete. Use minput_config_command () instead.
6208 The minput_assign_command_keys () function assigns input key
6209 sequence $KEYSEQ to input method command $COMMAND for the input
6210 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6211 key sequence is assigned globally no matter what $LANGUAGE is.
6212 Otherwise the key sequence is assigned locally.
6214 Each element of $KEYSEQ must have the key $Msymbol and the value
6215 must be a symbol representing an input key.
6217 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6218 globally or locally.
6220 This assignment gets effective in a newly opened input method.
6223 If the operation was successful, 0 is returned. Otherwise -1 is
6224 returned, and #merror_code is set to #MERROR_IM. */
6226 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6228 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6229 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6230 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6231 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6232 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6234 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6235 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6237 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6238 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6240 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6244 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6245 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6248 minput_assign_command_keys (MSymbol language, MSymbol name,
6249 MSymbol command, MPlist *keyseq)
6255 if (command == Mnil)
6256 MERROR (MERROR_IM, -1);
6261 if (! check_command_keyseq (keyseq))
6262 MERROR (MERROR_IM, -1);
6264 mplist_add (plist, Mplist, keyseq);
6269 ret = minput_config_command (language, name, command, keyseq);
6270 M17N_OBJECT_UNREF (keyseq);
6277 @brief Call a callback function
6279 The minput_callback () functions calls a callback function
6280 $COMMAND assigned for the input context $IC. The caller must set
6281 specific elements in $IC->plist if the callback function requires.
6284 If there exists a specified callback function, 0 is returned.
6285 Otherwise -1 is returned. By side effects, $IC->plist may be
6289 minput_callback (MInputContext *ic, MSymbol command)
6291 MInputCallbackFunc func;
6293 if (! ic->im->driver.callback_list)
6295 func = ((MInputCallbackFunc)
6296 mplist_get_func (ic->im->driver.callback_list, command));
6299 (func) (ic, command);
6306 /*** @addtogroup m17nDebug */
6312 @brief Dump an input method.
6314 The mdebug_dump_im () function prints the input method $IM in a
6315 human readable way to the stderr. $INDENT specifies how many
6316 columns to indent the lines but the first one.
6319 This function returns $IM. */
6321 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6323 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6324 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6327 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6330 mdebug_dump_im (MInputMethod *im, int indent)
6332 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6335 prefix = (char *) alloca (indent + 1);
6336 memset (prefix, 32, indent);
6337 prefix[indent] = '\0';
6339 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6340 msymbol_name (im->name));
6341 mdebug_dump_mtext (im_info->title, 0, 0);
6342 if (im->name != Mnil)
6346 MPLIST_DO (state, im_info->states)
6348 fprintf (stderr, "\n%s ", prefix);
6349 dump_im_state (MPLIST_VAL (state), indent + 2);
6352 fprintf (stderr, ")");