1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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 @anchor 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 #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 #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> ³°ÉôÆþÎϥ᥽¥Ã¥É @anchor foreign-input-method
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï #Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 #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 /** Symbols to load an input method data. */
171 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
173 /** Symbols for actions. */
174 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
175 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
176 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
177 static MSymbol Mless_equal, Mgreater_equal;
178 static MSymbol Mcond;
179 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
181 /** Special action symbol. */
182 static MSymbol Mat_reload;
184 static MSymbol M_candidates;
186 static MSymbol Mcandidate_list, Mcandidate_index;
188 static MSymbol Minit, Mfini;
190 /** Symbols for variables. */
191 static MSymbol Mcandidates_group_size, Mcandidates_charset;
193 /** Symbols for key events. */
194 static MSymbol one_char_symbol[256];
196 static MSymbol M_key_alias;
198 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
200 static MSymbol M_gettext;
202 /** Structure to hold a map. */
206 /** List of actions to take when we reach the map. In a root map,
207 the actions are executed only when there is no more key. */
210 /** List of deeper maps. If NULL, this is a terminal map. */
213 /** List of actions to take when we leave the map successfully. In
214 a root map, the actions are executed only when none of submaps
215 handle the current key. */
216 MPlist *branch_actions;
219 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
224 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
231 /** Name of the state. */
234 /** Title of the state, or NULL. */
237 /** Key translation map of the state. Built by merging all maps of
242 #define CUSTOM_FILE "config.mic"
244 static MPlist *load_im_info_keys;
246 /* List of input method information. The format is:
247 (LANGUAGE NAME t:IM_INFO ... ... ...) */
248 static MPlist *im_info_list;
250 /* Database for user's customization file. */
251 static MDatabase *im_custom_mdb;
253 /* List of input method information loaded from im_custom_mdb. The
254 format is the same as im_info_list. */
255 static MPlist *im_custom_list;
257 /* List of input method information configured by
258 minput_config_command and minput_config_variable. The format is
259 the same as im_info_list. */
260 static MPlist *im_config_list;
262 /* Global input method information. It points into the element of
263 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
265 static MInputMethodInfo *global_info;
267 static int update_global_info (void);
268 static int update_custom_info (void);
269 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
276 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
277 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
278 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
280 char buf[6], buf2[32], buf3[2];
282 /* Maximum case: '\215', C-M-m, C-M-M, M-Return, C-A-m, C-A-M, A-Return
283 plus one for cyclic alias. */
286 M_key_alias = msymbol (" key-alias");
290 /* Aliases for 0x00-0x1F */
294 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
298 alias[j++] = msymbol (buf3);
299 alias[j++] = one_char_symbol[i] = msymbol (buf);
300 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
304 /* Ex: `Escape' == `C-[' */
305 alias[j++] = msymbol (key_names[i]);
307 if (buf[2] >= 'A' && buf[2] <= 'Z')
309 /* Ex: `C-a' == `C-A' */
311 alias[j++] = msymbol (buf);
315 /* Establish cyclic alias chain. */
318 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
321 /* Aliases for 0x20-0x7E */
323 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
325 one_char_symbol[i] = msymbol (buf + 2);
326 if (i >= 'A' && i <= 'Z')
328 /* Ex: `A' == `S-A' == `S-a'. */
329 alias[0] = alias[3] = one_char_symbol[i];
330 alias[1] = msymbol (buf);
332 alias[2] = msymbol (buf);
334 for (j = 0; j < 3; j++)
335 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
339 /* Aliases for 0x7F */
341 alias[0] = alias[3] = msymbol (buf3);
342 alias[1] = one_char_symbol[127] = msymbol ("Delete");
343 alias[2] = msymbol ("C-?");
344 for (j = 0; j < 3; j++)
345 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
347 /* Aliases for 0x80-0x9F */
349 /* buf[1] = '-'; -- already done */
353 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
357 alias[j++] = msymbol (buf3);
358 /* `C-M-a' == `C-A-a' */
360 alias[j++] = one_char_symbol[i] = msymbol (buf);
362 alias[j++] = msymbol (buf);
363 if (key_names[i - 128])
365 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
367 strcpy (buf2 + 2, key_names[i - 128]);
368 alias[j++] = msymbol (buf2);
370 alias[j++] = msymbol (buf2);
372 if (buf[4] >= 'A' && buf[4] <= 'Z')
374 /* Ex: `C-M-a' == `C-M-A'. */
377 alias[j++] = msymbol (buf);
379 alias[j++] = msymbol (buf);
383 /* Establish cyclic alias chain. */
386 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
389 /* Aliases for 0xA0-0xFF */
390 for (i = 160, buf[4] = ' '; i < 255; i++, buf[4]++)
394 alias[j++] = msymbol (buf3);
396 alias[j++] = one_char_symbol[i] = msymbol (buf + 2);
398 alias[j++] = msymbol (buf + 2);
401 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
404 buf3[0] = (char) 255;
405 alias[0] = alias[3] = msymbol (buf3);
406 alias[1] = one_char_symbol[255] = msymbol ("M-Delete");
407 alias[2] = msymbol ("A-Delete");
408 for (j = 0; j < 3; j++)
409 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
411 /* Aliases for keys that can't be mapped to one-char-symbol
413 /* buf is already set to "C-?-". */
414 for (i = ' '; i <= '~'; i++)
428 alias[0] = alias[2] = msymbol (buf);
430 alias[1] = msymbol (buf);
431 for (j = 0; j < 2; j++)
432 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
435 Minput_method = msymbol ("input-method");
436 Mtitle = msymbol ("title");
437 Mmacro = msymbol ("macro");
438 Mmodule = msymbol ("module");
439 Mmap = msymbol ("map");
440 Mstate = msymbol ("state");
441 Minclude = msymbol ("include");
442 Minsert = msymbol ("insert");
443 M_candidates = msymbol (" candidates");
444 Mdelete = msymbol ("delete");
445 Mmove = msymbol ("move");
446 Mmark = msymbol ("mark");
447 Mpushback = msymbol ("pushback");
448 Mpop = msymbol ("pop");
449 Mundo = msymbol ("undo");
450 Mcall = msymbol ("call");
451 Mshift = msymbol ("shift");
452 Mselect = msymbol ("select");
453 Mshow = msymbol ("show");
454 Mhide = msymbol ("hide");
455 Mcommit = msymbol ("commit");
456 Munhandle = msymbol ("unhandle");
457 Mset = msymbol ("set");
458 Madd = msymbol ("add");
459 Msub = msymbol ("sub");
460 Mmul = msymbol ("mul");
461 Mdiv = msymbol ("div");
462 Mequal = msymbol ("=");
463 Mless = msymbol ("<");
464 Mgreater = msymbol (">");
465 Mless_equal = msymbol ("<=");
466 Mgreater_equal = msymbol (">=");
467 Mcond = msymbol ("cond");
468 Mplus = msymbol ("+");
469 Mminus = msymbol ("-");
470 Mstar = msymbol ("*");
471 Mslash = msymbol ("/");
472 Mand = msymbol ("&");
474 Mnot = msymbol ("!");
476 Mat_reload = msymbol ("-reload");
478 Mcandidates_group_size = msymbol ("candidates-group-size");
479 Mcandidates_charset = msymbol ("candidates-charset");
481 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
482 Mcandidate_index = msymbol (" candidate-index");
484 Minit = msymbol ("init");
485 Mfini = msymbol ("fini");
487 Mdescription = msymbol ("description");
488 Mcommand = msymbol ("command");
489 Mvariable = msymbol ("variable");
490 Mglobal = msymbol ("global");
491 Mconfig = msymbol ("config");
492 M_gettext = msymbol ("_");
494 load_im_info_keys = mplist ();
495 mplist_add (load_im_info_keys, Mstate, Mnil);
496 mplist_push (load_im_info_keys, Mmap, Mnil);
498 im_info_list = mplist ();
499 im_config_list = im_custom_list = NULL;
500 im_custom_mdb = NULL;
501 update_custom_info ();
503 update_global_info ();
505 fully_initialized = 1;
508 #define MINPUT__INIT() \
510 if (! fully_initialized) \
511 fully_initialize (); \
516 marker_code (MSymbol sym, int surrounding)
522 name = MSYMBOL_NAME (sym);
523 return (name[0] != '@' ? -1
524 : (((name[1] >= '0' && name[1] <= '9')
525 || name[1] == '<' || name[1] == '>' || name[1] == '='
526 || name[1] == '[' || name[1] == ']'
528 && name[2] == '\0') ? name[1]
529 : (name[1] != '+' && name[1] != '-') ? -1
530 : (name[2] == '\0' || surrounding) ? name[1]
535 /* Return a plist containing an integer value of VAR. The plist must
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, int *pos)
665 name = MSYMBOL_NAME (sym);
667 && (name[1] == '-' ? (name[2] >= '1' && name[2] <= '9')
668 : name[1] == '+' ? (name[2] >= '0' && name[2] <= '9')
671 *pos = name[1] == '-' ? - atoi (name + 2) : atoi (name + 2);
678 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
680 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
682 MText *preedit = ic->preedit;
683 int len = mtext_nchars (preedit);
685 if (MPLIST_INTEGER_P (arg))
686 return MPLIST_INTEGER (arg);
688 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
691 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
693 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
696 return ic_info->key_head;
697 if ((code == '-' || code == '+'))
699 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
703 pos = atoi (name + 1);
704 if (pos == 0 && code == '-')
705 return get_preceding_char (ic, 0);
706 pos = ic->cursor_pos + pos;
709 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
710 return mtext_ref_char (ic->produced,
711 mtext_len (ic->produced) + pos);
712 return get_preceding_char (ic, - pos);
715 return get_following_char (ic, pos - len);
718 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
720 else if (code >= '0' && code <= '9')
722 else if (code == '=')
723 pos = ic->cursor_pos;
724 else if (code == '[')
725 pos = ic->cursor_pos - 1;
726 else if (code == ']')
727 pos = ic->cursor_pos + 1;
728 else if (code == '<')
730 else if (code == '>')
732 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
736 parse_expression (MPlist *plist)
740 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
742 if (! MPLIST_PLIST_P (plist))
744 plist = MPLIST_PLIST (plist);
745 op = MPLIST_SYMBOL (plist);
746 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
747 && op != Mand && op != Mor && op != Mnot
748 && op != Mless && op != Mgreater && op != Mequal
749 && op != Mless_equal && op != Mgreater_equal)
750 MERROR (MERROR_IM, -1);
751 MPLIST_DO (plist, MPLIST_NEXT (plist))
752 if (parse_expression (plist) < 0)
758 resolve_expression (MInputContext *ic, MPlist *plist)
763 if (MPLIST_INTEGER_P (plist))
764 return MPLIST_INTEGER (plist);
765 if (MPLIST_SYMBOL_P (plist))
766 return integer_value (ic, plist, 1);
767 if (! MPLIST_PLIST_P (plist))
769 plist = MPLIST_PLIST (plist);
770 if (! MPLIST_SYMBOL_P (plist))
772 op = MPLIST_SYMBOL (plist);
773 plist = MPLIST_NEXT (plist);
774 val = resolve_expression (ic, plist);
776 MPLIST_DO (plist, MPLIST_NEXT (plist))
777 val += resolve_expression (ic, plist);
778 else if (op == Mminus)
779 MPLIST_DO (plist, MPLIST_NEXT (plist))
780 val -= resolve_expression (ic, plist);
781 else if (op == Mstar)
782 MPLIST_DO (plist, MPLIST_NEXT (plist))
783 val *= resolve_expression (ic, plist);
784 else if (op == Mslash)
785 MPLIST_DO (plist, MPLIST_NEXT (plist))
786 val /= resolve_expression (ic, plist);
788 MPLIST_DO (plist, MPLIST_NEXT (plist))
789 val &= resolve_expression (ic, plist);
791 MPLIST_DO (plist, MPLIST_NEXT (plist))
792 val |= resolve_expression (ic, plist);
795 else if (op == Mless)
796 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
797 else if (op == Mequal)
798 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
799 else if (op == Mgreater)
800 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
801 else if (op == Mless_equal)
802 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
803 else if (op == Mgreater_equal)
804 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
808 /* Parse PLIST as an action list. PLIST should have this form:
809 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
810 Return 0 if successfully parsed, otherwise return -1. */
813 parse_action_list (MPlist *plist, MPlist *macros)
815 MPLIST_DO (plist, plist)
817 if (MPLIST_MTEXT_P (plist))
819 /* This is a short form of (insert MTEXT). */
820 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
821 MERROR (MERROR_IM, -1); */
823 else if (MPLIST_PLIST_P (plist)
824 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
825 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
829 /* This is a short form of (insert (GROUPS *)). */
830 MPLIST_DO (pl, MPLIST_PLIST (plist))
832 if (MPLIST_PLIST_P (pl))
836 MPLIST_DO (elt, MPLIST_PLIST (pl))
837 if (! MPLIST_MTEXT_P (elt)
838 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
839 MERROR (MERROR_IM, -1);
843 if (! MPLIST_MTEXT_P (pl)
844 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
845 MERROR (MERROR_IM, -1);
849 else if (MPLIST_INTEGER_P (plist))
851 int c = MPLIST_INTEGER (plist);
853 if (c < 0 || c > MCHAR_MAX)
854 MERROR (MERROR_IM, -1);
856 else if (MPLIST_PLIST_P (plist)
857 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
859 MPlist *pl = MPLIST_PLIST (plist);
860 MSymbol action_name = MPLIST_SYMBOL (pl);
862 pl = MPLIST_NEXT (pl);
864 if (action_name == M_candidates)
866 /* This is an already regularised action. */
869 if (action_name == Minsert)
871 if (MPLIST_MTEXT_P (pl))
873 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
874 MERROR (MERROR_IM, -1);
876 else if (MPLIST_INTEGER_P (pl))
878 int c = MPLIST_INTEGER (pl);
880 if (c < 0 || c > MCHAR_MAX)
881 MERROR (MERROR_IM, -1);
883 else if (MPLIST_PLIST_P (pl))
885 MPLIST_DO (pl, MPLIST_PLIST (pl))
887 if (MPLIST_PLIST_P (pl))
891 MPLIST_DO (elt, MPLIST_PLIST (pl))
892 if (! MPLIST_MTEXT_P (elt)
893 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
894 MERROR (MERROR_IM, -1);
898 if (! MPLIST_MTEXT_P (pl)
899 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
900 MERROR (MERROR_IM, -1);
904 else if (! MPLIST_SYMBOL_P (pl))
905 MERROR (MERROR_IM, -1);
907 else if (action_name == Mselect
908 || action_name == Mdelete
909 || action_name == Mmove)
911 if (parse_expression (pl) < 0)
914 else if (action_name == Mmark
915 || action_name == Mcall
916 || action_name == Mshift)
918 if (! MPLIST_SYMBOL_P (pl))
919 MERROR (MERROR_IM, -1);
921 else if (action_name == Mundo)
923 if (! MPLIST_TAIL_P (pl))
925 if (! MPLIST_SYMBOL_P (pl)
926 && ! MPLIST_INTEGER_P (pl))
927 MERROR (MERROR_IM, -1);
930 else if (action_name == Mpushback)
932 if (MPLIST_MTEXT_P (pl))
934 MText *mt = MPLIST_MTEXT (pl);
936 if (mtext_nchars (mt) != mtext_nbytes (mt))
937 MERROR (MERROR_IM, -1);
939 else if (MPLIST_PLIST_P (pl))
943 MPLIST_DO (p, MPLIST_PLIST (pl))
944 if (! MPLIST_SYMBOL_P (p))
945 MERROR (MERROR_IM, -1);
947 else if (! MPLIST_INTEGER_P (pl))
948 MERROR (MERROR_IM, -1);
950 else if (action_name == Mset || action_name == Madd
951 || action_name == Msub || action_name == Mmul
952 || action_name == Mdiv)
954 if (! MPLIST_SYMBOL_P (pl))
955 MERROR (MERROR_IM, -1);
956 if (parse_expression (MPLIST_NEXT (pl)) < 0)
959 else if (action_name == Mequal || action_name == Mless
960 || action_name == Mgreater || action_name == Mless_equal
961 || action_name == Mgreater_equal)
963 if (parse_expression (pl) < 0
964 || parse_expression (MPLIST_NEXT (pl)) < 0)
966 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
967 if (! MPLIST_PLIST_P (pl))
968 MERROR (MERROR_IM, -1);
969 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
970 MERROR (MERROR_IM, -1);
971 pl = MPLIST_NEXT (pl);
972 if (MPLIST_PLIST_P (pl)
973 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
974 MERROR (MERROR_IM, -1);
976 else if (action_name == Mshow || action_name == Mhide
977 || action_name == Mcommit || action_name == Munhandle
978 || action_name == Mpop)
980 else if (action_name == Mcond)
983 if (! MPLIST_PLIST_P (pl))
984 MERROR (MERROR_IM, -1);
986 else if (! macros || ! mplist_get (macros, action_name))
987 MERROR (MERROR_IM, -1);
989 else if (! MPLIST_SYMBOL_P (plist))
990 MERROR (MERROR_IM, -1);
997 resolve_command (MPlist *cmds, MSymbol command)
1001 if (! cmds || ! (plist = mplist__assq (cmds, command)))
1003 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
1004 plist = MPLIST_NEXT (plist);
1005 plist = MPLIST_NEXT (plist);
1006 plist = MPLIST_NEXT (plist);
1010 /* Load a translation into MAP from PLIST.
1011 PLIST has this form:
1012 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
1015 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
1016 MPlist *branch_actions, MPlist *macros)
1021 if (MPLIST_MTEXT_P (keylist))
1023 MText *mt = MPLIST_MTEXT (keylist);
1025 len = mtext_nchars (mt);
1026 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
1028 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1029 for (i = 0; i < len; i++)
1030 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1036 if (MFAILP (MPLIST_PLIST_P (keylist)))
1038 elt = MPLIST_PLIST (keylist);
1039 len = MPLIST_LENGTH (elt);
1040 if (MFAILP (len > 0))
1042 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1043 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1045 if (MPLIST_INTEGER_P (elt))
1047 int c = MPLIST_INTEGER (elt);
1049 if (MFAILP (c >= 0 && c < 0x100))
1051 keyseq[i] = one_char_symbol[c];
1055 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1057 keyseq[i] = MPLIST_SYMBOL (elt);
1062 for (i = 0; i < len; i++)
1064 MIMMap *deeper = NULL;
1067 deeper = mplist_get (map->submaps, keyseq[i]);
1069 map->submaps = mplist ();
1072 /* Fixme: It is better to make all deeper maps at once. */
1073 MSTRUCT_CALLOC (deeper, MERROR_IM);
1074 mplist_put (map->submaps, keyseq[i], deeper);
1079 /* We reach a terminal map. */
1080 if (map->map_actions
1081 || map->branch_actions)
1082 /* This map is already defined. We avoid overriding it. */
1085 if (! MPLIST_TAIL_P (map_actions))
1087 if (parse_action_list (map_actions, macros) < 0)
1088 MERROR (MERROR_IM, -1);
1089 map->map_actions = map_actions;
1093 map->branch_actions = branch_actions;
1094 M17N_OBJECT_REF (branch_actions);
1100 /* Load a branch from PLIST into MAP. PLIST has this form:
1101 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1104 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1107 MPlist *branch_actions;
1109 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1111 map_name = MPLIST_SYMBOL (plist);
1112 plist = MPLIST_NEXT (plist);
1113 if (MPLIST_TAIL_P (plist))
1114 branch_actions = NULL;
1115 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1118 branch_actions = plist;
1119 if (map_name == Mnil)
1121 map->branch_actions = branch_actions;
1123 M17N_OBJECT_REF (branch_actions);
1125 else if (map_name == Mt)
1127 map->map_actions = branch_actions;
1129 M17N_OBJECT_REF (branch_actions);
1131 else if (im_info->maps)
1133 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1134 if (! plist && im_info->configured_vars)
1136 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1138 if (p && MPLIST_PLIST_P (p))
1140 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1141 if (MPLIST_SYMBOL_P (p))
1142 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1147 MPLIST_DO (plist, plist)
1149 MPlist *keylist, *map_actions;
1151 if (! MPLIST_PLIST_P (plist))
1152 MERROR (MERROR_IM, -1);
1153 keylist = MPLIST_PLIST (plist);
1154 map_actions = MPLIST_NEXT (keylist);
1155 if (MPLIST_SYMBOL_P (keylist))
1157 MSymbol command = MPLIST_SYMBOL (keylist);
1160 if (MFAILP (command != Mat_reload))
1162 pl = resolve_command (im_info->configured_cmds, command);
1166 load_translation (map, pl, map_actions, branch_actions,
1170 load_translation (map, keylist, map_actions, branch_actions,
1179 /* Load a macro from PLIST into IM_INFO->macros.
1180 PLIST has this form:
1181 PLIST ::= ( MACRO-NAME ACTION * )
1182 IM_INFO->macros is a plist of macro names vs action list. */
1185 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1190 if (! MPLIST_SYMBOL_P (plist))
1191 MERROR (MERROR_IM, -1);
1192 name = MPLIST_SYMBOL (plist);
1193 plist = MPLIST_NEXT (plist);
1194 if (MFAILP (! MPLIST_TAIL_P (plist)))
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 (M17N_MODULE_DIR) + 1
1223 + strlen (MSYMBOL_NAME (module))
1224 + strlen (DLOPEN_SHLIB_EXT) + 1);
1225 sprintf (module_file, "%s/%s%s",
1226 M17N_MODULE_DIR, MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1228 handle = dlopen (module_file, RTLD_NOW);
1229 if (MFAILP (handle))
1231 fprintf (stderr, "%s\n", dlerror ());
1234 func_list = mplist ();
1235 MPLIST_DO (plist, MPLIST_NEXT (plist))
1237 if (! MPLIST_SYMBOL_P (plist))
1238 MERROR_GOTO (MERROR_IM, err_label);
1239 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1242 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1245 MSTRUCT_MALLOC (external, MERROR_IM);
1246 external->handle = handle;
1247 external->func_list = func_list;
1248 mplist_add (im_info->externals, module, external);
1253 M17N_OBJECT_UNREF (func_list);
1258 free_map (MIMMap *map, int top)
1263 M17N_OBJECT_UNREF (map->map_actions);
1266 MPLIST_DO (plist, map->submaps)
1267 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1268 M17N_OBJECT_UNREF (map->submaps);
1270 M17N_OBJECT_UNREF (map->branch_actions);
1275 free_state (void *object)
1277 MIMState *state = object;
1279 M17N_OBJECT_UNREF (state->title);
1281 free_map (state->map, 1);
1285 /** Load a state from PLIST into a newly allocated state object.
1286 PLIST has this form:
1287 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1288 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1289 Return the state object. */
1292 load_state (MInputMethodInfo *im_info, MPlist *plist)
1296 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1298 M17N_OBJECT (state, free_state, MERROR_IM);
1299 state->name = MPLIST_SYMBOL (plist);
1300 plist = MPLIST_NEXT (plist);
1301 if (MPLIST_MTEXT_P (plist))
1303 state->title = MPLIST_MTEXT (plist);
1304 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1305 Mlanguage, im_info->language);
1306 M17N_OBJECT_REF (state->title);
1307 plist = MPLIST_NEXT (plist);
1309 MSTRUCT_CALLOC (state->map, MERROR_IM);
1310 MPLIST_DO (plist, plist)
1312 if (MFAILP (MPLIST_PLIST_P (plist)))
1314 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1319 /* Return a newly created IM_INFO for an input method specified by
1320 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1322 static MInputMethodInfo *
1323 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1326 MInputMethodInfo *im_info;
1329 if (name == Mnil && extra == Mnil)
1330 language = Mt, extra = Mglobal;
1331 MSTRUCT_CALLOC (im_info, MERROR_IM);
1333 im_info->language = language;
1334 im_info->name = name;
1335 im_info->extra = extra;
1338 mplist_add (plist, Mplist, elt);
1339 M17N_OBJECT_UNREF (elt);
1340 elt = mplist_add (elt, Msymbol, language);
1341 elt = mplist_add (elt, Msymbol, name);
1342 elt = mplist_add (elt, Msymbol, extra);
1343 mplist_add (elt, Mt, im_info);
1349 fini_im_info (MInputMethodInfo *im_info)
1353 M17N_OBJECT_UNREF (im_info->cmds);
1354 M17N_OBJECT_UNREF (im_info->configured_cmds);
1355 M17N_OBJECT_UNREF (im_info->bc_cmds);
1356 M17N_OBJECT_UNREF (im_info->vars);
1357 M17N_OBJECT_UNREF (im_info->configured_vars);
1358 M17N_OBJECT_UNREF (im_info->bc_vars);
1359 M17N_OBJECT_UNREF (im_info->description);
1360 M17N_OBJECT_UNREF (im_info->title);
1361 if (im_info->states)
1363 MPLIST_DO (plist, im_info->states)
1365 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1367 M17N_OBJECT_UNREF (state);
1369 M17N_OBJECT_UNREF (im_info->states);
1372 if (im_info->macros)
1374 MPLIST_DO (plist, im_info->macros)
1375 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1376 M17N_OBJECT_UNREF (im_info->macros);
1379 if (im_info->externals)
1381 MPLIST_DO (plist, im_info->externals)
1383 MIMExternalModule *external = MPLIST_VAL (plist);
1385 dlclose (external->handle);
1386 M17N_OBJECT_UNREF (external->func_list);
1388 MPLIST_KEY (plist) = Mt;
1390 M17N_OBJECT_UNREF (im_info->externals);
1394 MPLIST_DO (plist, im_info->maps)
1396 MPlist *p = MPLIST_PLIST (plist);
1398 M17N_OBJECT_UNREF (p);
1400 M17N_OBJECT_UNREF (im_info->maps);
1407 free_im_info (MInputMethodInfo *im_info)
1409 fini_im_info (im_info);
1414 free_im_list (MPlist *plist)
1418 MPLIST_DO (pl, plist)
1420 MInputMethodInfo *im_info;
1422 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1423 im_info = MPLIST_VAL (elt);
1424 free_im_info (im_info);
1426 M17N_OBJECT_UNREF (plist);
1429 static MInputMethodInfo *
1430 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1432 if (name == Mnil && extra == Mnil)
1433 language = Mt, extra = Mglobal;
1434 while ((plist = mplist__assq (plist, language)))
1436 MPlist *elt = MPLIST_PLIST (plist);
1438 plist = MPLIST_NEXT (plist);
1439 elt = MPLIST_NEXT (elt);
1440 if (MPLIST_SYMBOL (elt) != name)
1442 elt = MPLIST_NEXT (elt);
1443 if (MPLIST_SYMBOL (elt) != extra)
1445 elt = MPLIST_NEXT (elt);
1446 return MPLIST_VAL (elt);
1451 static void load_im_info (MPlist *, MInputMethodInfo *);
1453 #define get_custom_info(im_info) \
1455 ? lookup_im_info (im_custom_list, (im_info)->language, \
1456 (im_info)->name, (im_info)->extra) \
1459 #define get_config_info(im_info) \
1461 ? lookup_im_info (im_config_list, (im_info)->language, \
1462 (im_info)->name, (im_info)->extra) \
1466 update_custom_info (void)
1472 if (mdatabase__check (im_custom_mdb) > 0)
1477 MDatabaseInfo *custom_dir_info;
1478 char custom_path[PATH_MAX + 1];
1480 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1481 if (! custom_dir_info->filename
1482 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1484 strcpy (custom_path, custom_dir_info->filename);
1485 strcat (custom_path, CUSTOM_FILE);
1486 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1492 free_im_list (im_custom_list);
1493 im_custom_list = NULL;
1495 plist = mdatabase_load (im_custom_mdb);
1498 im_custom_list = mplist ();
1500 MPLIST_DO (pl, plist)
1502 MSymbol language, name, extra;
1503 MInputMethodInfo *im_info;
1504 MPlist *im_data, *p;
1506 if (! MPLIST_PLIST_P (pl))
1508 p = MPLIST_PLIST (pl);
1509 im_data = MPLIST_NEXT (p);
1510 if (! MPLIST_PLIST_P (p))
1512 p = MPLIST_PLIST (p);
1513 if (! MPLIST_SYMBOL_P (p)
1514 || MPLIST_SYMBOL (p) != Minput_method)
1516 p = MPLIST_NEXT (p);
1517 if (! MPLIST_SYMBOL_P (p))
1519 language = MPLIST_SYMBOL (p);
1520 p = MPLIST_NEXT (p);
1521 if (! MPLIST_SYMBOL_P (p))
1523 name = MPLIST_SYMBOL (p);
1524 p = MPLIST_NEXT (p);
1525 if (MPLIST_TAIL_P (p))
1527 else if (MPLIST_SYMBOL_P (p))
1528 extra = MPLIST_SYMBOL (p);
1529 if (language == Mnil || (name == Mnil && extra == Mnil))
1531 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1532 load_im_info (im_data, im_info);
1534 M17N_OBJECT_UNREF (plist);
1539 update_global_info (void)
1545 int ret = mdatabase__check (global_info->mdb);
1549 fini_im_info (global_info);
1553 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1557 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1559 if (! global_info->mdb
1560 || ! (plist = mdatabase_load (global_info->mdb)))
1563 load_im_info (plist, global_info);
1564 M17N_OBJECT_UNREF (plist);
1569 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1570 and EXTRA. KEY, if not Mnil, tells which kind of information about
1571 the input method is necessary, and the returned IM_INFO may contain
1572 only that information. */
1574 static MInputMethodInfo *
1575 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1578 MInputMethodInfo *im_info;
1581 if (name == Mnil && extra == Mnil)
1582 language = Mt, extra = Mglobal;
1583 im_info = lookup_im_info (im_info_list, language, name, extra);
1586 if (key == Mnil ? im_info->states != NULL
1587 : key == Mcommand ? im_info->cmds != NULL
1588 : key == Mvariable ? im_info->vars != NULL
1589 : key == Mtitle ? im_info->title != NULL
1590 : key == Mdescription ? im_info->description != NULL
1592 /* IM_INFO already contains required information. */
1594 /* We have not yet loaded required information. */
1598 mdb = mdatabase_find (Minput_method, language, name, extra);
1601 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1606 plist = mdatabase_load (im_info->mdb);
1610 mplist_push (load_im_info_keys, key, Mt);
1611 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1612 mplist_pop (load_im_info_keys);
1616 MERROR (MERROR_IM, im_info);
1617 update_global_info ();
1618 load_im_info (plist, im_info);
1619 M17N_OBJECT_UNREF (plist);
1622 if (! im_info->cmds)
1623 im_info->cmds = mplist ();
1624 if (! im_info->vars)
1625 im_info->vars = mplist ();
1626 if (! im_info->states)
1627 im_info->states = mplist ();
1629 if (! im_info->title
1630 && (key == Mnil || key == Mtitle))
1631 im_info->title = (name == Mnil ? mtext ()
1632 : mtext_from_data (MSYMBOL_NAME (name),
1633 MSYMBOL_NAMELEN (name),
1634 MTEXT_FORMAT_US_ASCII));
1638 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1639 If updated, but got unloadable, return -1. Otherwise, update
1640 contents of IM_INFO from the new database, and return 1. */
1643 reload_im_info (MInputMethodInfo *im_info)
1648 update_custom_info ();
1649 update_global_info ();
1650 check = mdatabase__check (im_info->mdb);
1653 plist = mdatabase_load (im_info->mdb);
1656 fini_im_info (im_info);
1657 load_im_info (plist, im_info);
1658 M17N_OBJECT_UNREF (plist);
1659 if (! im_info->cmds)
1660 im_info->cmds = mplist ();
1661 if (! im_info->vars)
1662 im_info->vars = mplist ();
1663 if (! im_info->title)
1665 MSymbol name = im_info->name;
1667 im_info->title = (name == Mnil ? mtext ()
1668 : mtext_from_data (MSYMBOL_NAME (name),
1669 MSYMBOL_NAMELEN (name),
1670 MTEXT_FORMAT_US_ASCII));
1675 static MInputMethodInfo *
1676 get_im_info_by_tags (MPlist *plist)
1681 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1682 i++, plist = MPLIST_NEXT (plist))
1683 tag[i] = MPLIST_SYMBOL (plist);
1688 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1693 check_description (MPlist *plist)
1697 if (MPLIST_MTEXT_P (plist))
1699 if (MPLIST_PLIST_P (plist))
1701 MPlist *pl = MPLIST_PLIST (plist);
1703 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1705 pl =MPLIST_NEXT (pl);
1706 if (MFAILP (MPLIST_MTEXT_P (pl)))
1708 mt = MPLIST_MTEXT (pl);
1709 M17N_OBJECT_REF (mt);
1712 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1714 if (translated == (char *) MTEXT_DATA (mt))
1715 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1716 if (translated != (char *) MTEXT_DATA (mt))
1718 M17N_OBJECT_UNREF (mt);
1719 mt = mtext__from_data (translated, strlen (translated),
1720 MTEXT_FORMAT_UTF_8, 1);
1724 mplist_set (plist, Mtext, mt);
1725 M17N_OBJECT_UNREF (mt);
1728 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1734 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1738 check_command_keyseq (MPlist *keyseq)
1740 if (MPLIST_PLIST_P (keyseq))
1742 MPlist *p = MPLIST_PLIST (keyseq);
1745 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1749 if (MPLIST_MTEXT_P (keyseq))
1751 MText *mt = MPLIST_MTEXT (keyseq);
1754 for (i = 0; i < mtext_nchars (mt); i++)
1755 if (mtext_ref_char (mt, i) >= 256)
1762 /* Load command defitions from PLIST into IM_INFO->cmds.
1764 PLIST is well-formed and has this form;
1765 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1766 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1767 M-text or a plist of symbols.
1769 The returned list has the same form, but for each element...
1771 (1) If DESCRIPTION and the rest are omitted, the element is not
1772 stored in the returned list.
1774 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1775 description in global_info->cmds (if any). */
1778 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1782 im_info->cmds = tail = mplist ();
1784 MPLIST_DO (plist, MPLIST_NEXT (plist))
1786 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1789 if (MFAILP (MPLIST_PLIST_P (plist)))
1791 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1792 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1794 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1795 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1797 if (MFAILP (im_info != global_info))
1798 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1802 if (! check_description (p))
1803 mplist_set (p, Msymbol, Mnil);
1804 p = MPLIST_NEXT (p);
1805 while (! MPLIST_TAIL_P (p))
1807 if (MFAILP (check_command_keyseq (p)))
1808 mplist__pop_unref (p);
1810 p = MPLIST_NEXT (p);
1813 tail = mplist_add (tail, Mplist, pl);
1818 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1819 MPlist *config_cmds)
1821 MPlist *global = NULL, *custom = NULL, *config = NULL;
1822 MSymbol name = MPLIST_SYMBOL (plist);
1824 MPlist *description, *keyseq;
1826 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1827 global = MPLIST_NEXT (MPLIST_PLIST (global));
1829 plist = MPLIST_NEXT (plist);
1830 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1832 description = plist;
1833 plist = MPLIST_NEXT (plist);
1837 description = global;
1838 if (! MPLIST_TAIL_P (plist))
1839 plist = MPLIST_NEXT (plist);
1841 if (MPLIST_TAIL_P (plist) && global)
1843 keyseq = MPLIST_NEXT (global);
1844 status = Minherited;
1852 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1854 status = Mconfigured;
1855 config = MPLIST_NEXT (MPLIST_PLIST (config));
1856 if (! MPLIST_TAIL_P (config))
1859 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1861 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1863 if (MPLIST_TAIL_P (this_keyseq))
1864 mplist__pop_unref (custom);
1867 status = Mcustomized;
1868 keyseq = this_keyseq;
1873 mplist_add (plist, Msymbol, name);
1875 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1877 mplist_add (plist, Msymbol, Mnil);
1878 mplist_add (plist, Msymbol, status);
1879 mplist__conc (plist, keyseq);
1884 config_all_commands (MInputMethodInfo *im_info)
1886 MPlist *global_cmds, *custom_cmds, *config_cmds;
1887 MInputMethodInfo *temp;
1888 MPlist *tail, *plist;
1890 M17N_OBJECT_UNREF (im_info->configured_cmds);
1892 if (MPLIST_TAIL_P (im_info->cmds)
1896 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1897 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1898 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1900 im_info->configured_cmds = tail = mplist ();
1901 MPLIST_DO (plist, im_info->cmds)
1903 MPlist *pl = config_command (MPLIST_PLIST (plist),
1904 global_cmds, custom_cmds, config_cmds);
1907 tail = mplist_add (tail, Mplist, pl);
1908 M17N_OBJECT_UNREF (pl);
1913 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1914 valid, return 0 if not. */
1917 check_variable_value (MPlist *val, MPlist *global)
1919 MSymbol type = MPLIST_KEY (val);
1920 MPlist *valids = MPLIST_NEXT (val);
1922 if (type != Minteger && type != Mtext && type != Msymbol)
1926 if (MPLIST_KEY (global) != Mt
1927 && MPLIST_KEY (global) != MPLIST_KEY (val))
1929 if (MPLIST_TAIL_P (valids))
1930 valids = MPLIST_NEXT (global);
1932 if (MPLIST_TAIL_P (valids))
1935 if (type == Minteger)
1937 int n = MPLIST_INTEGER (val);
1939 MPLIST_DO (valids, valids)
1941 if (MPLIST_INTEGER_P (valids))
1943 if (n == MPLIST_INTEGER (valids))
1946 else if (MPLIST_PLIST_P (valids))
1948 MPlist *p = MPLIST_PLIST (valids);
1949 int min_bound, max_bound;
1951 if (! MPLIST_INTEGER_P (p))
1952 MERROR (MERROR_IM, 0);
1953 min_bound = MPLIST_INTEGER (p);
1954 p = MPLIST_NEXT (p);
1955 if (! MPLIST_INTEGER_P (p))
1956 MERROR (MERROR_IM, 0);
1957 max_bound = MPLIST_INTEGER (p);
1958 if (n >= min_bound && n <= max_bound)
1963 else if (type == Msymbol)
1965 MSymbol sym = MPLIST_SYMBOL (val);
1967 MPLIST_DO (valids, valids)
1969 if (! MPLIST_SYMBOL_P (valids))
1970 MERROR (MERROR_IM, 0);
1971 if (sym == MPLIST_SYMBOL (valids))
1977 MText *mt = MPLIST_MTEXT (val);
1979 MPLIST_DO (valids, valids)
1981 if (! MPLIST_MTEXT_P (valids))
1982 MERROR (MERROR_IM, 0);
1983 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1988 return (! MPLIST_TAIL_P (valids));
1991 /* Load variable defitions from PLIST into IM_INFO->vars.
1993 PLIST is well-formed and has this form;
1994 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1996 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1998 The returned list has the same form, but for each element...
2000 (1) If DESCRIPTION and the rest are omitted, the element is not
2001 stored in the returned list.
2003 (2) If DESCRIPTION is nil, it is complemented by the corresponding
2004 description in global_info->vars (if any). */
2007 load_variables (MInputMethodInfo *im_info, MPlist *plist)
2009 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
2010 ? global_info->vars : NULL);
2013 im_info->vars = tail = mplist ();
2014 MPLIST_DO (plist, MPLIST_NEXT (plist))
2018 if (MFAILP (MPLIST_PLIST_P (plist)))
2020 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
2021 if (MFAILP (MPLIST_SYMBOL_P (pl)))
2023 if (im_info == global_info)
2025 /* Loading a global variable. */
2026 p = MPLIST_NEXT (pl);
2027 if (MPLIST_TAIL_P (p))
2028 mplist_add (p, Msymbol, Mnil);
2031 if (! check_description (p))
2032 mplist_set (p, Msymbol, Mnil);
2033 p = MPLIST_NEXT (p);
2034 if (MFAILP (! MPLIST_TAIL_P (p)
2035 && check_variable_value (p, NULL)))
2036 mplist_set (p, Mt, NULL);
2039 else if (im_info->mdb)
2041 /* Loading a local variable. */
2042 MSymbol name = MPLIST_SYMBOL (pl);
2043 MPlist *global = NULL;
2046 && (p = mplist__assq (global_vars, name)))
2048 /* P ::= ((NAME DESC ...) ...) */
2049 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2050 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2051 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2054 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2055 if (! MPLIST_TAIL_P (p))
2057 if (! check_description (p))
2058 mplist_set (p, Msymbol, Mnil);
2059 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2060 if (MFAILP (! MPLIST_TAIL_P (p)))
2061 mplist_set (p, Mt, NULL);
2064 MPlist *valid_values = MPLIST_NEXT (p);
2066 if (! MPLIST_TAIL_P (valid_values)
2067 ? MFAILP (check_variable_value (p, NULL))
2068 : global && MFAILP (check_variable_value (p, global)))
2069 mplist_set (p, Mt, NULL);
2075 /* Loading a variable customization. */
2076 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2077 if (MFAILP (! MPLIST_TAIL_P (p)))
2079 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2080 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2081 || MPLIST_MTEXT_P (p)))
2084 tail = mplist_add (tail, Mplist, pl);
2089 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2090 MPlist *config_vars)
2092 MPlist *global = NULL, *custom = NULL, *config = NULL;
2093 MSymbol name = MPLIST_SYMBOL (plist);
2095 MPlist *description = NULL, *value, *valids;
2099 global = mplist__assq (global_vars, name);
2101 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2104 plist = MPLIST_NEXT (plist);
2105 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2106 description = plist;
2108 description = global;
2110 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2112 if (MPLIST_TAIL_P (plist))
2114 /* Inherit from global (if any). */
2118 if (MPLIST_KEY (value) == Mt)
2120 valids = MPLIST_NEXT (global);
2121 status = Minherited;
2133 value = plist = MPLIST_NEXT (plist);
2134 valids = MPLIST_NEXT (value);
2135 if (MPLIST_KEY (value) == Mt)
2137 if (! MPLIST_TAIL_P (valids))
2140 valids = MPLIST_NEXT (global);
2144 if (config_vars && (config = mplist__assq (config_vars, name)))
2146 status = Mconfigured;
2147 config = MPLIST_NEXT (MPLIST_PLIST (config));
2148 if (! MPLIST_TAIL_P (config))
2151 if (MFAILP (check_variable_value (value, global ? global : plist)))
2155 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2157 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2159 if (MPLIST_TAIL_P (this_value))
2160 mplist__pop_unref (custom);
2164 if (MFAILP (check_variable_value (value, global ? global : plist)))
2166 status = Mcustomized;
2171 mplist_add (plist, Msymbol, name);
2173 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2175 mplist_add (plist, Msymbol, Mnil);
2176 mplist_add (plist, Msymbol, status);
2178 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2180 mplist_add (plist, Mt, NULL);
2181 if (valids && ! MPLIST_TAIL_P (valids))
2182 mplist__conc (plist, valids);
2186 /* Return a configured variable definition list based on
2187 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2188 get it from global_info->vars. */
2191 config_all_variables (MInputMethodInfo *im_info)
2193 MPlist *global_vars, *custom_vars, *config_vars;
2194 MInputMethodInfo *temp;
2195 MPlist *tail, *plist;
2197 M17N_OBJECT_UNREF (im_info->configured_vars);
2199 if (MPLIST_TAIL_P (im_info->vars)
2203 global_vars = im_info != global_info ? global_info->vars : NULL;
2204 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2205 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2207 im_info->configured_vars = tail = mplist ();
2208 MPLIST_DO (plist, im_info->vars)
2210 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2211 global_vars, custom_vars, config_vars);
2214 tail = mplist_add (tail, Mplist, pl);
2215 M17N_OBJECT_UNREF (pl);
2220 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2221 CONFIG contains configuration information of the input method. */
2224 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2228 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2230 load_commands (im_info, MPLIST_PLIST (pl));
2231 config_all_commands (im_info);
2232 pl = mplist_pop (pl);
2233 M17N_OBJECT_UNREF (pl);
2236 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2238 load_variables (im_info, MPLIST_PLIST (pl));
2239 config_all_variables (im_info);
2240 pl = mplist_pop (pl);
2241 M17N_OBJECT_UNREF (pl);
2244 MPLIST_DO (plist, plist)
2245 if (MPLIST_PLIST_P (plist))
2247 MPlist *elt = MPLIST_PLIST (plist);
2250 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2252 key = MPLIST_SYMBOL (elt);
2257 elt = MPLIST_NEXT (elt);
2258 if (MFAILP (MPLIST_MTEXT_P (elt)))
2260 im_info->title = MPLIST_MTEXT (elt);
2261 M17N_OBJECT_REF (im_info->title);
2263 else if (key == Mmap)
2265 pl = mplist__from_alist (MPLIST_NEXT (elt));
2268 if (! im_info->maps)
2272 mplist__conc (im_info->maps, pl);
2273 M17N_OBJECT_UNREF (pl);
2276 else if (key == Mmacro)
2278 if (! im_info->macros)
2279 im_info->macros = mplist ();
2280 MPLIST_DO (elt, MPLIST_NEXT (elt))
2282 if (MFAILP (MPLIST_PLIST_P (elt)))
2284 load_macros (im_info, MPLIST_PLIST (elt));
2287 else if (key == Mmodule)
2289 if (! im_info->externals)
2290 im_info->externals = mplist ();
2291 MPLIST_DO (elt, MPLIST_NEXT (elt))
2293 if (MFAILP (MPLIST_PLIST_P (elt)))
2295 load_external_module (im_info, MPLIST_PLIST (elt));
2298 else if (key == Mstate)
2300 MPLIST_DO (elt, MPLIST_NEXT (elt))
2304 if (MFAILP (MPLIST_PLIST_P (elt)))
2306 pl = MPLIST_PLIST (elt);
2307 if (! im_info->states)
2308 im_info->states = mplist ();
2309 state = load_state (im_info, MPLIST_PLIST (elt));
2312 mplist_put (im_info->states, state->name, state);
2315 else if (key == Minclude)
2317 /* elt ::= include (tag1 tag2 ...) key item ... */
2319 MInputMethodInfo *temp;
2321 elt = MPLIST_NEXT (elt);
2322 if (MFAILP (MPLIST_PLIST_P (elt)))
2324 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2327 elt = MPLIST_NEXT (elt);
2328 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2330 key = MPLIST_SYMBOL (elt);
2331 elt = MPLIST_NEXT (elt);
2334 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2336 if (! im_info->maps)
2337 im_info->maps = mplist ();
2338 MPLIST_DO (pl, temp->maps)
2340 p = MPLIST_VAL (pl);
2341 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2342 M17N_OBJECT_REF (p);
2345 else if (key == Mmacro)
2347 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2349 if (! im_info->macros)
2350 im_info->macros = mplist ();
2351 MPLIST_DO (pl, temp->macros)
2353 p = MPLIST_VAL (pl);
2354 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2355 M17N_OBJECT_REF (p);
2358 else if (key == Mstate)
2360 if (! temp->states || MPLIST_TAIL_P (temp->states))
2362 if (! im_info->states)
2363 im_info->states = mplist ();
2364 MPLIST_DO (pl, temp->states)
2366 MIMState *state = MPLIST_VAL (pl);
2368 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2369 M17N_OBJECT_REF (state);
2373 else if (key == Mdescription)
2375 if (im_info->description)
2377 elt = MPLIST_NEXT (elt);
2378 if (! check_description (elt))
2380 im_info->description = MPLIST_MTEXT (elt);
2381 M17N_OBJECT_REF (im_info->description);
2384 if (im_info->macros)
2386 MPLIST_DO (pl, im_info->macros)
2387 parse_action_list (MPLIST_PLIST (pl), im_info->macros);
2390 im_info->tick = time (NULL);
2395 static int take_action_list (MInputContext *ic, MPlist *action_list);
2396 static void preedit_commit (MInputContext *ic, int need_prefix);
2398 /* Shift to the state of name STATE_NAME. If STATE_NAME is `t', shift
2399 to the previous state (if any). If STATE_NAME is `nil', shift to
2400 the initial state. */
2403 shift_state (MInputContext *ic, MSymbol state_name)
2405 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2406 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2407 MIMState *orig_state = ic_info->state, *state;
2409 /* Find a state to shift to. If not found, shift to the initial
2411 if (state_name == Mt)
2413 if (! ic_info->prev_state)
2415 state = ic_info->prev_state;
2417 else if (state_name == Mnil)
2419 state = (MIMState *) MPLIST_VAL (im_info->states);
2423 state = (MIMState *) mplist_get (im_info->states, state_name);
2425 state = (MIMState *) MPLIST_VAL (im_info->states);
2431 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2432 MSYMBOL_NAME (orig_state->name),
2433 MSYMBOL_NAME (state->name));
2435 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2438 /* Enter the new state. */
2439 ic_info->state = state;
2440 ic_info->map = state->map;
2441 ic_info->state_key_head = ic_info->key_head;
2442 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2444 /* We have shifted to the initial state. */
2445 preedit_commit (ic, 0);
2446 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2447 ic_info->state_pos = ic->cursor_pos;
2448 if (state != orig_state || state_name == Mnil)
2450 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2452 /* Shifted to the initial state. */
2453 ic_info->prev_state = NULL;
2454 M17N_OBJECT_UNREF (ic_info->vars_saved);
2455 ic_info->vars_saved = mplist_copy (ic_info->vars);
2458 ic_info->prev_state = orig_state;
2461 ic->status = state->title;
2463 ic->status = im_info->title;
2464 ic->status_changed = 1;
2465 ic_info->state_hook = ic_info->map->map_actions;
2469 /* Find a candidate group that contains a candidate number INDEX from
2470 PLIST. Set START_INDEX to the first candidate number of the group,
2471 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2472 candidate group number if they are non-NULL. If INDEX is -1, find
2473 the last candidate group. */
2476 find_candidates_group (MPlist *plist, int index,
2477 int *start_index, int *end_index, int *group_index)
2479 int i = 0, gidx = 0, len;
2481 MPLIST_DO (plist, plist)
2483 if (MPLIST_MTEXT_P (plist))
2484 len = mtext_nchars (MPLIST_MTEXT (plist));
2486 len = mplist_length (MPLIST_PLIST (plist));
2487 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2493 *end_index = i + len;
2495 *group_index = gidx;
2504 /* Adjust markers for the change of preedit text.
2505 If FROM == TO, the change is insertion of INS chars.
2506 If FROM < TO and INS == 0, the change is deletion of the range.
2507 If FROM < TO and INS > 0, the change is replacement. */
2510 adjust_markers (MInputContext *ic, int from, int to, int ins)
2512 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2517 MPLIST_DO (markers, ic_info->markers)
2518 if (MPLIST_INTEGER (markers) > from)
2519 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2520 if (ic->cursor_pos >= from)
2521 ic->cursor_pos += ins;
2525 MPLIST_DO (markers, ic_info->markers)
2527 if (MPLIST_INTEGER (markers) >= to)
2528 MPLIST_VAL (markers)
2529 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2530 else if (MPLIST_INTEGER (markers) > from)
2531 MPLIST_VAL (markers) = (void *) from;
2533 if (ic->cursor_pos >= to)
2534 ic->cursor_pos += ins - (to - from);
2535 else if (ic->cursor_pos > from)
2536 ic->cursor_pos = from;
2542 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2544 int nchars = mt ? mtext_nchars (mt) : 1;
2548 mtext_ins (ic->preedit, pos, mt);
2549 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2553 mtext_ins_char (ic->preedit, pos, c, 1);
2555 MDEBUG_PRINT1 ("('%c')", c);
2557 MDEBUG_PRINT1 ("(U+%04X)", c);
2559 adjust_markers (ic, pos, pos, nchars);
2560 ic->preedit_changed = 1;
2565 preedit_delete (MInputContext *ic, int from, int to)
2567 mtext_del (ic->preedit, from, to);
2568 adjust_markers (ic, from, to, 0);
2569 ic->preedit_changed = 1;
2573 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2577 mtext_del (ic->preedit, from, to);
2580 mtext_ins (ic->preedit, from, mt);
2581 ins = mtext_nchars (mt);
2585 mtext_ins_char (ic->preedit, from, c, 1);
2588 adjust_markers (ic, from, to, ins);
2589 ic->preedit_changed = 1;
2594 preedit_commit (MInputContext *ic, int need_prefix)
2596 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2597 int preedit_len = mtext_nchars (ic->preedit);
2599 if (preedit_len > 0)
2603 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2604 Mcandidate_list, NULL, 0);
2605 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2606 Mcandidate_index, NULL, 0);
2607 mtext_cat (ic->produced, ic->preedit);
2613 MDEBUG_PRINT1 ("\n [IM] [%s]",
2614 MSYMBOL_NAME (ic_info->state->name));
2615 MDEBUG_PRINT (" (commit");
2616 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2617 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2621 mtext_reset (ic->preedit);
2622 mtext_reset (ic_info->preedit_saved);
2623 MPLIST_DO (p, ic_info->markers)
2625 ic->cursor_pos = ic_info->state_pos = 0;
2626 ic->preedit_changed = 1;
2627 ic_info->commit_key_head = ic_info->key_head;
2629 if (ic->candidate_list)
2631 M17N_OBJECT_UNREF (ic->candidate_list);
2632 ic->candidate_list = NULL;
2633 ic->candidate_index = 0;
2634 ic->candidate_from = ic->candidate_to = 0;
2635 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2636 if (ic->candidate_show)
2638 ic->candidate_show = 0;
2639 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2645 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2647 int code = marker_code (sym, 0);
2649 if (mt && (code == '[' || code == ']'))
2653 if (code == '[' && current > 0)
2655 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2659 else if (code == ']' && current < mtext_nchars (mt))
2661 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2667 return (code == '<' ? 0
2668 : code == '>' ? limit
2669 : code == '-' ? current - 1
2670 : code == '+' ? current + 1
2671 : code == '=' ? current
2672 : code - '0' > limit ? limit
2676 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2680 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2682 int from = mtext_property_start (prop);
2683 int to = mtext_property_end (prop);
2685 MPlist *candidate_list = mtext_property_value (prop);
2686 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2688 int ingroup_index = idx - start;
2691 candidate_list = mplist_copy (candidate_list);
2692 if (MPLIST_MTEXT_P (group))
2694 mt = MPLIST_MTEXT (group);
2695 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2703 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2704 i++, plist = MPLIST_NEXT (plist));
2705 mt = MPLIST_MTEXT (plist);
2706 preedit_replace (ic, from, to, mt, 0);
2707 to = from + mtext_nchars (mt);
2709 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2710 M17N_OBJECT_UNREF (candidate_list);
2711 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2712 ic->cursor_pos = to;
2716 get_select_charset (MInputContextInfo * ic_info)
2718 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2721 if (! MPLIST_VAL (plist))
2723 sym = MPLIST_SYMBOL (plist);
2726 return MCHARSET (sym);
2729 /* The returned plist must be UNREFed. */
2732 adjust_candidates (MPlist *plist, MCharset *charset)
2736 /* plist ::= MTEXT ... | PLIST ... */
2737 plist = mplist_copy (plist);
2738 if (MPLIST_MTEXT_P (plist))
2741 while (! MPLIST_TAIL_P (pl))
2743 /* pl ::= MTEXT ... */
2744 MText *mt = MPLIST_MTEXT (pl);
2748 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2750 c = mtext_ref_char (mt, i);
2751 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2755 mt = mtext_dup (mt);
2756 mplist_set (pl, Mtext, mt);
2757 M17N_OBJECT_UNREF (mt);
2760 mtext_del (mt, i, i + 1);
2763 if (mtext_len (mt) > 0)
2764 pl = MPLIST_NEXT (pl);
2768 M17N_OBJECT_UNREF (mt);
2772 else /* MPLIST_PLIST_P (plist) */
2775 while (! MPLIST_TAIL_P (pl))
2777 /* pl ::= (MTEXT ...) ... */
2778 MPlist *p = MPLIST_PLIST (pl);
2780 /* p ::= MTEXT ... */
2784 while (! MPLIST_TAIL_P (p0))
2786 MText *mt = MPLIST_MTEXT (p0);
2789 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2791 c = mtext_ref_char (mt, i);
2792 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2797 p0 = MPLIST_NEXT (p0);
2804 p = mplist_copy (p);
2805 mplist_set (pl, Mplist, p);
2806 M17N_OBJECT_UNREF (p);
2810 p0 = MPLIST_NEXT (p0);
2813 M17N_OBJECT_UNREF (mt);
2816 if (! MPLIST_TAIL_P (p))
2817 pl = MPLIST_NEXT (pl);
2821 M17N_OBJECT_UNREF (p);
2825 if (MPLIST_TAIL_P (plist))
2827 M17N_OBJECT_UNREF (plist);
2833 /* The returned Plist must be UNREFed. */
2836 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2838 MCharset *charset = get_select_charset (ic_info);
2843 plist = resolve_variable (ic_info, Mcandidates_group_size);
2844 column = MPLIST_INTEGER (plist);
2846 plist = MPLIST_PLIST (args);
2851 plist = adjust_candidates (plist, charset);
2856 M17N_OBJECT_REF (plist);
2861 if (MPLIST_MTEXT_P (plist))
2863 MText *mt = MPLIST_MTEXT (plist);
2864 MPlist *next = MPLIST_NEXT (plist);
2866 if (MPLIST_TAIL_P (next))
2867 M17N_OBJECT_REF (mt);
2870 mt = mtext_dup (mt);
2871 while (! MPLIST_TAIL_P (next))
2873 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2874 next = MPLIST_NEXT (next);
2877 M17N_OBJECT_UNREF (plist);
2879 len = mtext_nchars (mt);
2881 mplist_add (plist, Mtext, mt);
2884 for (i = 0; i < len; i += column)
2886 int to = (i + column < len ? i + column : len);
2887 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2889 mplist_add (plist, Mtext, sub);
2890 M17N_OBJECT_UNREF (sub);
2893 M17N_OBJECT_UNREF (mt);
2895 else if (MPLIST_PLIST_P (plist))
2897 MPlist *tail = plist;
2898 MPlist *new = mplist ();
2899 MPlist *this = mplist ();
2902 MPLIST_DO (tail, tail)
2904 MPlist *p = MPLIST_PLIST (tail);
2908 MText *mt = MPLIST_MTEXT (p);
2910 if (count == column)
2912 mplist_add (new, Mplist, this);
2913 M17N_OBJECT_UNREF (this);
2917 mplist_add (this, Mtext, mt);
2921 mplist_add (new, Mplist, this);
2922 M17N_OBJECT_UNREF (this);
2923 mplist_set (plist, Mnil, NULL);
2924 MPLIST_DO (tail, new)
2926 MPlist *elt = MPLIST_PLIST (tail);
2928 mplist_add (plist, Mplist, elt);
2930 M17N_OBJECT_UNREF (new);
2938 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2940 MPlist *action = NULL;
2944 if (MPLIST_SYMBOL_P (action_list))
2946 MSymbol var = MPLIST_SYMBOL (action_list);
2949 MPLIST_DO (p, ic_info->vars)
2950 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2952 if (MPLIST_TAIL_P (p))
2954 action = MPLIST_NEXT (MPLIST_PLIST (p));
2955 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2958 if (MPLIST_PLIST_P (action_list))
2960 action = MPLIST_PLIST (action_list);
2961 if (MPLIST_SYMBOL_P (action))
2963 name = MPLIST_SYMBOL (action);
2964 args = MPLIST_NEXT (action);
2966 && MPLIST_PLIST_P (args))
2967 mplist_set (action, Msymbol, M_candidates);
2969 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2972 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2973 mplist_push (action, Msymbol, M_candidates);
2974 mplist_set (action_list, Mplist, action);
2975 M17N_OBJECT_UNREF (action);
2978 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2981 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2982 mplist_push (action, Msymbol, Minsert);
2983 mplist_set (action_list, Mplist, action);
2984 M17N_OBJECT_UNREF (action);
2989 /* Perform list of actions in ACTION_LIST for the current input
2990 context IC. If unhandle action was not performed, return 0.
2991 Otherwise, return -1. */
2994 take_action_list (MInputContext *ic, MPlist *action_list)
2996 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2997 MPlist *candidate_list = ic->candidate_list;
2998 int candidate_index = ic->candidate_index;
2999 int candidate_show = ic->candidate_show;
3000 MTextProperty *prop;
3002 MPLIST_DO (action_list, action_list)
3004 MPlist *action = regularize_action (action_list, ic_info);
3010 name = MPLIST_SYMBOL (action);
3011 args = MPLIST_NEXT (action);
3013 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
3014 if (name == Minsert)
3016 if (MPLIST_SYMBOL_P (args))
3018 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3019 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3022 if (MPLIST_MTEXT_P (args))
3023 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3024 else /* MPLIST_INTEGER_P (args)) */
3025 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3027 else if (name == M_candidates)
3029 MPlist *plist = get_candidate_list (ic_info, args);
3035 if (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist))
3037 M17N_OBJECT_UNREF (plist);
3040 if (MPLIST_MTEXT_P (plist))
3042 preedit_insert (ic, ic->cursor_pos, NULL,
3043 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3048 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3050 preedit_insert (ic, ic->cursor_pos, mt, 0);
3051 len = mtext_nchars (mt);
3053 pl = mplist_copy (plist);
3054 M17N_OBJECT_UNREF (plist);
3055 mtext_put_prop (ic->preedit,
3056 ic->cursor_pos - len, ic->cursor_pos,
3057 Mcandidate_list, pl);
3058 M17N_OBJECT_UNREF (pl);
3059 mtext_put_prop (ic->preedit,
3060 ic->cursor_pos - len, ic->cursor_pos,
3061 Mcandidate_index, (void *) 0);
3063 else if (name == Mselect)
3066 int code, idx, gindex;
3067 int pos = ic->cursor_pos;
3069 int idx_decided = 0;
3072 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3075 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3076 group = find_candidates_group (mtext_property_value (prop), idx,
3077 &start, &end, &gindex);
3078 if (MPLIST_SYMBOL_P (args))
3080 code = marker_code (MPLIST_SYMBOL (args), 0);
3083 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3084 if (! MPLIST_INTEGER_P (args))
3086 idx = start + MPLIST_INTEGER (args);
3087 if (idx < start || idx >= end)
3095 if (code != '[' && code != ']')
3100 ? new_index (NULL, ic->candidate_index - start,
3101 end - start - 1, MPLIST_SYMBOL (args),
3103 : MPLIST_INTEGER (args)));
3106 find_candidates_group (mtext_property_value (prop), -1,
3111 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3116 int ingroup_index = idx - start;
3119 group = mtext_property_value (prop);
3120 len = mplist_length (group);
3133 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3134 idx += (MPLIST_MTEXT_P (group)
3135 ? mtext_nchars (MPLIST_MTEXT (group))
3136 : mplist_length (MPLIST_PLIST (group)));
3137 len = (MPLIST_MTEXT_P (group)
3138 ? mtext_nchars (MPLIST_MTEXT (group))
3139 : mplist_length (MPLIST_PLIST (group)));
3140 if (ingroup_index >= len)
3141 ingroup_index = len - 1;
3142 idx += ingroup_index;
3144 update_candidate (ic, prop, idx);
3145 MDEBUG_PRINT1 ("(%d)", idx);
3147 else if (name == Mshow)
3148 ic->candidate_show = 1;
3149 else if (name == Mhide)
3150 ic->candidate_show = 0;
3151 else if (name == Mdelete)
3153 int len = mtext_nchars (ic->preedit);
3157 if (MPLIST_SYMBOL_P (args)
3158 && surrounding_pos (MPLIST_SYMBOL (args), &pos))
3160 to = ic->cursor_pos + pos;
3163 delete_surrounding_text (ic, to);
3168 delete_surrounding_text (ic, to - len);
3174 to = (MPLIST_SYMBOL_P (args)
3175 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3177 : MPLIST_INTEGER (args));
3182 pos = to - ic->cursor_pos;
3184 MDEBUG_PRINT1 ("(%d)", pos);
3185 if (to < ic->cursor_pos)
3186 preedit_delete (ic, to, ic->cursor_pos);
3187 else if (to > ic->cursor_pos)
3188 preedit_delete (ic, ic->cursor_pos, to);
3190 else if (name == Mmove)
3192 int len = mtext_nchars (ic->preedit);
3194 = (MPLIST_SYMBOL_P (args)
3195 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3197 : MPLIST_INTEGER (args));
3203 if (pos != ic->cursor_pos)
3205 ic->cursor_pos = pos;
3206 ic->preedit_changed = 1;
3208 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3210 else if (name == Mmark)
3212 int code = marker_code (MPLIST_SYMBOL (args), 0);
3216 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3217 (void *) ic->cursor_pos);
3218 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3221 else if (name == Mpushback)
3223 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3227 if (MPLIST_SYMBOL_P (args))
3229 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3230 if (MPLIST_INTEGER_P (args))
3231 num = MPLIST_INTEGER (args);
3236 num = MPLIST_INTEGER (args);
3239 ic_info->key_head -= num;
3241 ic_info->key_head = 0;
3243 ic_info->key_head = - num;
3244 if (ic_info->key_head > ic_info->used)
3245 ic_info->key_head = ic_info->used;
3247 else if (MPLIST_MTEXT_P (args))
3249 MText *mt = MPLIST_MTEXT (args);
3250 int i, len = mtext_nchars (mt);
3253 ic_info->key_head--;
3254 for (i = 0; i < len; i++)
3256 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3257 if (ic_info->key_head + i < ic_info->used)
3258 ic_info->keys[ic_info->key_head + i] = key;
3260 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3265 MPlist *plist = MPLIST_PLIST (args), *pl;
3269 ic_info->key_head--;
3271 MPLIST_DO (pl, plist)
3273 key = MPLIST_SYMBOL (pl);
3274 if (ic_info->key_head < ic_info->used)
3275 ic_info->keys[ic_info->key_head + i] = key;
3277 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3282 else if (name == Mpop)
3284 if (ic_info->key_head < ic_info->used)
3285 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3287 else if (name == Mcall)
3289 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3290 MIMExternalFunc func = NULL;
3291 MSymbol module, func_name;
3292 MPlist *func_args, *val;
3295 module = MPLIST_SYMBOL (args);
3296 args = MPLIST_NEXT (args);
3297 func_name = MPLIST_SYMBOL (args);
3299 if (im_info->externals)
3301 MIMExternalModule *external
3302 = (MIMExternalModule *) mplist_get (im_info->externals,
3305 func = ((MIMExternalFunc)
3306 mplist_get_func (external->func_list, func_name));
3310 func_args = mplist ();
3311 mplist_add (func_args, Mt, ic);
3312 MPLIST_DO (args, MPLIST_NEXT (args))
3316 if (MPLIST_KEY (args) == Msymbol
3317 && MPLIST_KEY (args) != Mnil
3318 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3320 code = new_index (ic, ic->cursor_pos,
3321 mtext_nchars (ic->preedit),
3322 MPLIST_SYMBOL (args), ic->preedit);
3323 mplist_add (func_args, Minteger, (void *) code);
3326 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3328 val = (func) (func_args);
3329 M17N_OBJECT_UNREF (func_args);
3330 if (val && ! MPLIST_TAIL_P (val))
3331 ret = take_action_list (ic, val);
3332 M17N_OBJECT_UNREF (val);
3336 else if (name == Mshift)
3338 shift_state (ic, MPLIST_SYMBOL (args));
3340 else if (name == Mundo)
3342 int intarg = (MPLIST_TAIL_P (args)
3344 : integer_value (ic, args, 0));
3346 mtext_reset (ic->preedit);
3347 mtext_reset (ic_info->preedit_saved);
3348 mtext_reset (ic->produced);
3349 M17N_OBJECT_UNREF (ic_info->vars);
3350 ic_info->vars = mplist_copy (ic_info->vars_saved);
3351 ic->cursor_pos = ic_info->state_pos = 0;
3352 ic_info->state_key_head = ic_info->key_head
3353 = ic_info->commit_key_head = 0;
3355 shift_state (ic, Mnil);
3358 if (MPLIST_TAIL_P (args))
3363 ic_info->used += intarg;
3366 ic_info->used = intarg;
3369 else if (name == Mset || name == Madd || name == Msub
3370 || name == Mmul || name == Mdiv)
3372 MSymbol sym = MPLIST_SYMBOL (args);
3373 MPlist *value = resolve_variable (ic_info, sym);
3377 val1 = MPLIST_INTEGER (value);
3378 args = MPLIST_NEXT (args);
3379 val2 = resolve_expression (ic, args);
3381 val1 = val2, op = "=";
3382 else if (name == Madd)
3383 val1 += val2, op = "+=";
3384 else if (name == Msub)
3385 val1 -= val2, op = "-=";
3386 else if (name == Mmul)
3387 val1 *= val2, op = "*=";
3389 val1 /= val2, op = "/=";
3390 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3391 MSYMBOL_NAME (sym), op, val1, val1);
3392 mplist_set (value, Minteger, (void *) val1);
3394 else if (name == Mequal || name == Mless || name == Mgreater
3395 || name == Mless_equal || name == Mgreater_equal)
3398 MPlist *actions1, *actions2;
3401 val1 = resolve_expression (ic, args);
3402 args = MPLIST_NEXT (args);
3403 val2 = resolve_expression (ic, args);
3404 args = MPLIST_NEXT (args);
3405 actions1 = MPLIST_PLIST (args);
3406 args = MPLIST_NEXT (args);
3407 if (MPLIST_TAIL_P (args))
3410 actions2 = MPLIST_PLIST (args);
3411 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3412 if (name == Mequal ? val1 == val2
3413 : name == Mless ? val1 < val2
3414 : name == Mgreater ? val1 > val2
3415 : name == Mless_equal ? val1 <= val2
3418 MDEBUG_PRINT ("ok");
3419 ret = take_action_list (ic, actions1);
3423 MDEBUG_PRINT ("no");
3425 ret = take_action_list (ic, actions2);
3430 else if (name == Mcond)
3434 MPLIST_DO (args, args)
3439 if (! MPLIST_PLIST (args))
3441 cond = MPLIST_PLIST (args);
3442 if (resolve_expression (ic, cond) != 0)
3444 MDEBUG_PRINT1 ("(%dth)", idx);
3445 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3451 else if (name == Mcommit)
3453 preedit_commit (ic, 0);
3455 else if (name == Munhandle)
3457 preedit_commit (ic, 0);
3462 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3466 && (actions = mplist_get (im_info->macros, name)))
3468 if (take_action_list (ic, actions) < 0)
3474 if (ic->candidate_list)
3476 M17N_OBJECT_UNREF (ic->candidate_list);
3477 ic->candidate_list = NULL;
3479 if (ic->cursor_pos > 0
3480 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3483 ic->candidate_list = mtext_property_value (prop);
3484 M17N_OBJECT_REF (ic->candidate_list);
3486 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3488 ic->candidate_from = mtext_property_start (prop);
3489 ic->candidate_to = mtext_property_end (prop);
3492 if (candidate_list != ic->candidate_list)
3493 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3494 if (candidate_index != ic->candidate_index)
3495 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3496 if (candidate_show != ic->candidate_show)
3497 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3502 /* Handle the input key KEY in the current state and map specified in
3503 the input context IC. If KEY is handled correctly, return 0.
3504 Otherwise, return -1. */
3507 handle_key (MInputContext *ic)
3509 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3510 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3511 MIMMap *map = ic_info->map;
3512 MIMMap *submap = NULL;
3513 MSymbol key = ic_info->keys[ic_info->key_head];
3514 MSymbol alias = Mnil;
3517 if (ic_info->state_hook)
3519 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
3520 MSYMBOL_NAME (ic_info->state->name));
3521 take_action_list (ic, ic_info->state_hook);
3522 ic_info->state_hook = NULL;
3525 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3526 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3530 submap = mplist_get (map->submaps, key);
3533 && (alias = msymbol_get (alias, M_key_alias))
3535 submap = mplist_get (map->submaps, alias);
3540 if (! alias || alias == key)
3541 MDEBUG_PRINT (" submap-found");
3543 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3544 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3545 ic->preedit_changed = 1;
3546 ic->cursor_pos = ic_info->state_pos;
3547 ic_info->key_head++;
3548 ic_info->map = map = submap;
3549 if (map->map_actions)
3551 MDEBUG_PRINT (" map-actions:");
3552 if (take_action_list (ic, map->map_actions) < 0)
3554 MDEBUG_PRINT ("\n");
3558 else if (map->submaps)
3560 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3562 MSymbol key = ic_info->keys[i];
3563 char *name = msymbol_name (key);
3565 if (! name[0] || ! name[1])
3566 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3570 /* If this is the terminal map or we have shifted to another
3571 state, perform branch actions (if any). */
3572 if (! map->submaps || map != ic_info->map)
3574 if (map->branch_actions)
3576 MDEBUG_PRINT (" branch-actions:");
3577 if (take_action_list (ic, map->branch_actions) < 0)
3579 MDEBUG_PRINT ("\n");
3583 /* If MAP is still not the root map, shift to the current
3585 if (ic_info->map != ic_info->state->map)
3586 shift_state (ic, ic_info->state->name);
3591 /* MAP can not handle KEY. */
3593 /* Perform branch actions if any. */
3594 if (map->branch_actions)
3596 MDEBUG_PRINT (" branch-actions:");
3597 if (take_action_list (ic, map->branch_actions) < 0)
3599 MDEBUG_PRINT ("\n");
3604 if (map == ic_info->map)
3606 /* The above branch actions didn't change the state. */
3608 /* If MAP is the root map of the initial state, and there
3609 still exist an unhandled key, it means that the current
3610 input method can not handle it. */
3611 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3612 && ic_info->key_head < ic_info->used)
3614 MDEBUG_PRINT (" unhandled\n");
3615 ic_info->state_hook = map->map_actions;
3619 if (map != ic_info->state->map)
3621 /* MAP is not the root map. Shift to the root map of the
3623 shift_state (ic, ic_info->state->name);
3625 else if (! map->branch_actions)
3627 /* MAP is the root map without any default branch
3628 actions. Shift to the initial state. */
3629 shift_state (ic, Mnil);
3633 MDEBUG_PRINT ("\n");
3637 /* Initialize IC->ic_info. */
3640 init_ic_info (MInputContext *ic)
3642 MInputMethodInfo *im_info = ic->im->info;
3643 MInputContextInfo *ic_info = ic->info;
3646 MLIST_INIT1 (ic_info, keys, 8);;
3648 ic_info->markers = mplist ();
3650 ic_info->vars = mplist ();
3651 if (im_info->configured_vars)
3652 MPLIST_DO (plist, im_info->configured_vars)
3654 MPlist *pl = MPLIST_PLIST (plist);
3655 MSymbol name = MPLIST_SYMBOL (pl);
3657 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3658 if (MPLIST_KEY (pl) != Mt)
3660 MPlist *p = mplist ();
3662 mplist_push (ic_info->vars, Mplist, p);
3663 M17N_OBJECT_UNREF (p);
3664 mplist_add (p, Msymbol, name);
3665 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3668 ic_info->vars_saved = mplist_copy (ic_info->vars);
3670 if (im_info->externals)
3672 MPlist *func_args = mplist (), *plist;
3674 mplist_add (func_args, Mt, ic);
3675 MPLIST_DO (plist, im_info->externals)
3677 MIMExternalModule *external = MPLIST_VAL (plist);
3678 MIMExternalFunc func
3679 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3684 M17N_OBJECT_UNREF (func_args);
3687 ic_info->preedit_saved = mtext ();
3688 ic_info->tick = im_info->tick;
3691 /* Finalize IC->ic_info. */
3694 fini_ic_info (MInputContext *ic)
3696 MInputMethodInfo *im_info = ic->im->info;
3697 MInputContextInfo *ic_info = ic->info;
3699 if (im_info->externals)
3701 MPlist *func_args = mplist (), *plist;
3703 mplist_add (func_args, Mt, ic);
3704 MPLIST_DO (plist, im_info->externals)
3706 MIMExternalModule *external = MPLIST_VAL (plist);
3707 MIMExternalFunc func
3708 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3713 M17N_OBJECT_UNREF (func_args);
3716 MLIST_FREE1 (ic_info, keys);
3717 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3718 M17N_OBJECT_UNREF (ic_info->markers);
3719 M17N_OBJECT_UNREF (ic_info->vars);
3720 M17N_OBJECT_UNREF (ic_info->vars_saved);
3721 M17N_OBJECT_UNREF (ic_info->preceding_text);
3722 M17N_OBJECT_UNREF (ic_info->following_text);
3724 memset (ic_info, 0, sizeof (MInputContextInfo));
3728 re_init_ic (MInputContext *ic, int reload)
3730 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3731 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3732 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3734 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3735 preedit_changed = mtext_nchars (ic->preedit) > 0;
3736 cursor_pos_changed = ic->cursor_pos > 0;
3737 candidates_changed = 0;
3738 if (ic->candidate_list)
3740 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3741 M17N_OBJECT_UNREF (ic->candidate_list);
3742 ic->candidate_list = NULL;
3744 if (ic->candidate_show)
3746 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3747 ic->candidate_show = 0;
3749 if (ic->candidate_index > 0)
3751 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3752 ic->candidate_index = 0;
3753 ic->candidate_from = ic->candidate_to = 0;
3755 if (mtext_nchars (ic->produced) > 0)
3756 mtext_reset (ic->produced);
3757 if (mtext_nchars (ic->preedit) > 0)
3758 mtext_reset (ic->preedit);
3760 M17N_OBJECT_UNREF (ic->plist);
3761 ic->plist = mplist ();
3765 reload_im_info (im_info);
3766 if (! im_info->states)
3768 struct MIMState *state;
3770 M17N_OBJECT (state, free_state, MERROR_IM);
3771 state->name = msymbol ("init");
3772 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3773 MSTRUCT_CALLOC (state->map, MERROR_IM);
3774 im_info->states = mplist ();
3775 mplist_add (im_info->states, state->name, state);
3778 shift_state (ic, Mnil);
3780 ic->status_changed = status_changed;
3781 ic->preedit_changed = preedit_changed;
3782 ic->cursor_pos_changed = cursor_pos_changed;
3783 ic->candidates_changed = candidates_changed;
3787 reset_ic (MInputContext *ic, MSymbol ignore)
3789 MDEBUG_PRINT ("\n [IM] reset\n");
3794 open_im (MInputMethod *im)
3796 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3798 if (! im_info || ! im_info->states)
3799 MERROR (MERROR_IM, -1);
3806 close_im (MInputMethod *im)
3812 create_ic (MInputContext *ic)
3814 MInputContextInfo *ic_info;
3816 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3819 shift_state (ic, Mnil);
3824 destroy_ic (MInputContext *ic)
3831 check_reload (MInputContext *ic, MSymbol key)
3833 MInputMethodInfo *im_info = ic->im->info;
3834 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3838 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3842 MPLIST_DO (plist, plist)
3844 MSymbol this_key, alias;
3846 if (MPLIST_MTEXT_P (plist))
3848 MText *mt = MPLIST_MTEXT (plist);
3849 int c = mtext_ref_char (mt, 0);
3853 this_key = one_char_symbol[c];
3857 MPlist *pl = MPLIST_PLIST (plist);
3859 this_key = MPLIST_SYMBOL (pl);
3863 && (alias = msymbol_get (alias, M_key_alias))
3864 && alias != this_key);
3868 if (MPLIST_TAIL_P (plist))
3871 MDEBUG_PRINT ("\n [IM] reload");
3877 /** Handle the input key KEY in the current state and map of IC->info.
3878 If KEY is handled but no text is produced, return 0, otherwise
3884 filter (MInputContext *ic, MSymbol key, void *arg)
3886 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3887 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3890 if (check_reload (ic, key))
3893 if (! ic_info->state)
3895 ic_info->key_unhandled = 1;
3898 mtext_reset (ic->produced);
3899 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3900 M17N_OBJECT_UNREF (ic_info->preceding_text);
3901 M17N_OBJECT_UNREF (ic_info->following_text);
3902 ic_info->preceding_text = ic_info->following_text = NULL;
3903 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3904 ic_info->key_unhandled = 0;
3907 if (handle_key (ic) < 0)
3909 /* KEY was not handled. Delete it from the current key sequence. */
3910 if (ic_info->used > 0)
3912 memmove (ic_info->keys, ic_info->keys + 1,
3913 sizeof (int) * (ic_info->used - 1));
3915 if (ic_info->state_key_head > 0)
3916 ic_info->state_key_head--;
3917 if (ic_info->commit_key_head > 0)
3918 ic_info->commit_key_head--;
3920 /* This forces returning 1. */
3921 ic_info->key_unhandled = 1;
3927 reset_ic (ic, Mnil);
3928 ic_info->key_unhandled = 1;
3931 /* Break the loop if all keys were handled. */
3932 } while (ic_info->key_head < ic_info->used);
3934 /* If the current map is the root of the initial state, we should
3935 produce any preedit text in ic->produced. */
3936 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3937 preedit_commit (ic, 1);
3939 if (mtext_nchars (ic->produced) > 0)
3943 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3944 MSYMBOL_NAME (ic_info->state->name));
3945 for (i = 0; i < mtext_nchars (ic->produced); i++)
3946 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3950 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3951 Mlanguage, ic->im->language);
3953 if (ic_info->commit_key_head > 0)
3955 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3956 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3957 ic_info->used -= ic_info->commit_key_head;
3958 ic_info->key_head -= ic_info->commit_key_head;
3959 ic_info->state_key_head -= ic_info->commit_key_head;
3960 ic_info->commit_key_head = 0;
3962 if (ic_info->key_unhandled)
3965 ic_info->key_head = ic_info->state_key_head
3966 = ic_info->commit_key_head = 0;
3969 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3973 /** Return 1 if the last event or key was not handled, otherwise
3976 There is no need of looking up because ic->produced should already
3977 contain the produced text (if any).
3982 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3984 mtext_cat (mt, ic->produced);
3985 mtext_reset (ic->produced);
3986 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3990 /* Input method command handler. */
3992 /* List of all (global and local) commands.
3993 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3994 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3995 Global commands are stored as (t (t COMMAND ...)) */
3998 /* Input method variable handler. */
4001 /* Support functions for mdebug_dump_im. */
4004 dump_im_map (MPlist *map_list, int indent)
4007 MSymbol key = MPLIST_KEY (map_list);
4008 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
4010 prefix = (char *) alloca (indent + 1);
4011 memset (prefix, 32, indent);
4012 prefix[indent] = '\0';
4014 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
4015 if (map->map_actions)
4016 mdebug_dump_plist (map->map_actions, indent + 2);
4019 MPLIST_DO (map_list, map->submaps)
4021 fprintf (stderr, "\n%s ", prefix);
4022 dump_im_map (map_list, indent + 2);
4025 if (map->branch_actions)
4027 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
4028 mdebug_dump_plist (map->branch_actions, indent + 4);
4029 fprintf (stderr, ")");
4031 fprintf (stderr, ")");
4036 dump_im_state (MIMState *state, int indent)
4041 prefix = (char *) alloca (indent + 1);
4042 memset (prefix, 32, indent);
4043 prefix[indent] = '\0';
4045 fprintf (stderr, "(%s", msymbol_name (state->name));
4046 if (state->map->submaps)
4048 MPLIST_DO (map_list, state->map->submaps)
4050 fprintf (stderr, "\n%s ", prefix);
4051 dump_im_map (map_list, indent + 2);
4054 fprintf (stderr, ")");
4062 Minput_driver = msymbol ("input-driver");
4064 Minput_preedit_start = msymbol ("input-preedit-start");
4065 Minput_preedit_done = msymbol ("input-preedit-done");
4066 Minput_preedit_draw = msymbol ("input-preedit-draw");
4067 Minput_status_start = msymbol ("input-status-start");
4068 Minput_status_done = msymbol ("input-status-done");
4069 Minput_status_draw = msymbol ("input-status-draw");
4070 Minput_candidates_start = msymbol ("input-candidates-start");
4071 Minput_candidates_done = msymbol ("input-candidates-done");
4072 Minput_candidates_draw = msymbol ("input-candidates-draw");
4073 Minput_set_spot = msymbol ("input-set-spot");
4074 Minput_focus_move = msymbol ("input-focus-move");
4075 Minput_focus_in = msymbol ("input-focus-in");
4076 Minput_focus_out = msymbol ("input-focus-out");
4077 Minput_toggle = msymbol ("input-toggle");
4078 Minput_reset = msymbol ("input-reset");
4079 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4080 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4081 Mcustomized = msymbol ("customized");
4082 Mconfigured = msymbol ("configured");
4083 Minherited = msymbol ("inherited");
4085 minput_default_driver.open_im = open_im;
4086 minput_default_driver.close_im = close_im;
4087 minput_default_driver.create_ic = create_ic;
4088 minput_default_driver.destroy_ic = destroy_ic;
4089 minput_default_driver.filter = filter;
4090 minput_default_driver.lookup = lookup;
4091 minput_default_driver.callback_list = mplist ();
4092 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4093 M17N_FUNC (reset_ic));
4094 minput_driver = &minput_default_driver;
4096 fully_initialized = 0;
4103 if (fully_initialized)
4105 free_im_list (im_info_list);
4107 free_im_list (im_custom_list);
4109 free_im_list (im_config_list);
4110 M17N_OBJECT_UNREF (load_im_info_keys);
4113 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4114 M17N_OBJECT_UNREF (minput_driver->callback_list);
4119 minput__char_to_key (int c)
4121 if (c < 0 || c >= 0x100)
4124 return one_char_symbol[c];
4128 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4133 /*** @addtogroup m17nInputMethod */
4138 @brief Symbol whose name is "input-method".
4141 @brief "input-method" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
4143 MSymbol Minput_method;
4146 @name Variables: Predefined symbols for callback commands. */
4148 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4151 These are the predefined symbols that are used as the @c COMMAND
4152 argument of callback functions of an input method driver (see
4153 #MInputDriver::callback_list).
4155 Most of them do not require extra argument nor return any value;
4156 exceptions are these:
4158 @b Minput_get_surrounding_text: When a callback function assigned for
4159 this command is called, the first element of #MInputContext::plist
4160 has key #Minteger and the value specifies which portion of the
4161 surrounding text should be retrieved. If the value is positive,
4162 it specifies the number of characters following the current cursor
4163 position. If the value is negative, the absolute value specifies
4164 the number of characters preceding the current cursor position.
4165 If the value is zero, it means that the caller just wants to know
4166 if the surrounding text is currently supported or not.
4168 If the surrounding text is currently supported, the callback
4169 function must set the key of this element to #Mtext and the value
4170 to the retrieved M-text. The length of the M-text may be shorter
4171 than the requested number of characters, if the available text is
4172 not that long. The length can be zero in the worst case. Or, the
4173 length may be longer if an application thinks it is more efficient
4174 to return that length.
4176 If the surrounding text is not currently supported, the callback
4177 function should return without changing the first element of
4178 #MInputContext::plist.
4180 @b Minput_delete_surrounding_text: When a callback function assigned
4181 for this command is called, the first element of
4182 #MInputContext::plist has key #Minteger and the value specifies
4183 which portion of the surrounding text should be deleted in the
4184 same way as the case of Minput_get_surrounding_text. The callback
4185 function must delete the specified text. It should not alter
4186 #MInputContext::plist. */
4188 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4189 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4191 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4193 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4194 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4195 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4196 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4197 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4198 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4199 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4201 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4202 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4203 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4204 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4205 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4207 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4208 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4210 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4211 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4212 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4213 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4214 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4215 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4216 MSymbol Minput_preedit_start;
4217 MSymbol Minput_preedit_done;
4218 MSymbol Minput_preedit_draw;
4219 MSymbol Minput_status_start;
4220 MSymbol Minput_status_done;
4221 MSymbol Minput_status_draw;
4222 MSymbol Minput_candidates_start;
4223 MSymbol Minput_candidates_done;
4224 MSymbol Minput_candidates_draw;
4225 MSymbol Minput_set_spot;
4226 MSymbol Minput_toggle;
4227 MSymbol Minput_reset;
4228 MSymbol Minput_get_surrounding_text;
4229 MSymbol Minput_delete_surrounding_text;
4235 @name Variables: Predefined symbols for special input events.
4237 These are the predefined symbols that are used as the @c KEY
4238 argument of minput_filter (). */
4240 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4242 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4247 MSymbol Minput_focus_out;
4248 MSymbol Minput_focus_in;
4249 MSymbol Minput_focus_move;
4255 @name Variables: Predefined symbols used in input method information. */
4257 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4261 These are the predefined symbols describing status of input method
4262 command and variable, and are used in a return value of
4263 minput_get_command () and minput_get_variable (). */
4265 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4266 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4268 MSymbol Mcustomized;
4269 MSymbol Mconfigured;
4275 @brief The default driver for internal input methods.
4277 The variable #minput_default_driver is the default driver for
4278 internal input methods.
4280 The member MInputDriver::open_im () searches the m17n database for
4281 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4282 $NAME\> and loads it.
4284 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4285 programmers responsibility to set it to a plist of proper callback
4286 functions. Otherwise, no feedback information (e.g. preedit text)
4287 can be shown to users.
4289 The macro M17N_INIT () sets the variable #minput_driver to the
4290 pointer to this driver so that all internal input methods use it.
4292 Therefore, unless @c minput_driver is set differently, the driver
4293 dependent arguments $ARG of the functions whose name begins with
4294 "minput_" are all ignored. */
4296 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4298 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4300 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4301 \< #Minput_method, $LANGUAGE, $NAME\>
4302 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4304 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4305 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4306 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4307 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4309 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4310 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4312 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4313 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4315 MInputDriver minput_default_driver;
4319 @brief The driver for internal input methods.
4321 The variable #minput_driver is a pointer to the input method
4322 driver that is used by internal input methods. The macro
4323 M17N_INIT () initializes it to a pointer to #minput_default_driver
4324 if <m17n<EM></EM>.h> is included. */
4326 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4328 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4329 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4330 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4331 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4333 MInputDriver *minput_driver;
4337 The variable #Minput_driver is a symbol for a foreign input method.
4338 See @ref foreign-input-method "foreign input method" for the detail. */
4339 MSymbol Minput_driver;
4354 @brief Open an input method.
4356 The minput_open_im () function opens an input method whose
4357 language and name match $LANGUAGE and $NAME, and returns a pointer
4358 to the input method object newly allocated.
4360 This function at first decides a driver for the input method as
4363 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4364 #minput_driver is used.
4366 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4367 driver pointed to by the property value is used to open the input
4368 method. If $NAME has no such a property, @c NULL is returned.
4370 Then, the member MInputDriver::open_im () of the driver is
4373 $ARG is set in the member @c arg of the structure MInputMethod so
4374 that the driver can refer to it. */
4376 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4378 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4379 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4381 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4383 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4384 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4386 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4387 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4388 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4390 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4392 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4394 @latexonly \IPAlabel{minput_open} @endlatexonly
4399 minput_open_im (MSymbol language, MSymbol name, void *arg)
4402 MInputDriver *driver;
4406 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4407 msymbol_name (language), msymbol_name (name));
4411 MERROR (MERROR_IM, NULL);
4412 driver = minput_driver;
4416 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4418 MERROR (MERROR_IM, NULL);
4421 MSTRUCT_CALLOC (im, MERROR_IM);
4422 im->language = language;
4425 im->driver = *driver;
4426 if ((*im->driver.open_im) (im) < 0)
4428 MDEBUG_PRINT (" failed\n");
4432 MDEBUG_PRINT (" ok\n");
4439 @brief Close an input method.
4441 The minput_close_im () function closes the input method $IM, which
4442 must have been created by minput_open_im (). */
4445 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4447 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4448 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4451 minput_close_im (MInputMethod *im)
4453 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4454 msymbol_name (im->name), msymbol_name (im->language));
4455 (*im->driver.close_im) (im);
4457 MDEBUG_PRINT (" done\n");
4463 @brief Create an input context.
4465 The minput_create_ic () function creates an input context object
4466 associated with input method $IM, and calls callback functions
4467 corresponding to @b Minput_preedit_start, @b Minput_status_start, and
4468 @b Minput_status_draw in this order.
4471 If an input context is successfully created, minput_create_ic ()
4472 returns a pointer to it. Otherwise it returns @c NULL. */
4475 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4477 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4478 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4479 @b Minput_preedit_start, @b Minput_status_start, @b Minput_status_draw
4480 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4483 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4484 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4488 minput_create_ic (MInputMethod *im, void *arg)
4492 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4493 msymbol_name (im->name), msymbol_name (im->language));
4494 MSTRUCT_CALLOC (ic, MERROR_IM);
4497 ic->preedit = mtext ();
4498 ic->candidate_list = NULL;
4499 ic->produced = mtext ();
4500 ic->spot.x = ic->spot.y = 0;
4502 ic->plist = mplist ();
4503 if ((*im->driver.create_ic) (ic) < 0)
4505 MDEBUG_PRINT (" failed\n");
4506 M17N_OBJECT_UNREF (ic->preedit);
4507 M17N_OBJECT_UNREF (ic->produced);
4508 M17N_OBJECT_UNREF (ic->plist);
4513 if (im->driver.callback_list)
4515 minput_callback (ic, Minput_preedit_start);
4516 minput_callback (ic, Minput_status_start);
4517 minput_callback (ic, Minput_status_draw);
4520 MDEBUG_PRINT (" ok\n");
4527 @brief Destroy an input context.
4529 The minput_destroy_ic () function destroys the input context $IC,
4530 which must have been created by minput_create_ic (). It calls
4531 callback functions corresponding to @b Minput_preedit_done,
4532 @b Minput_status_done, and @b Minput_candidates_done in this order. */
4535 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4537 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4538 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4539 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4540 @b Minput_preedit_done, @b Minput_status_done, @b Minput_candidates_done
4541 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4545 minput_destroy_ic (MInputContext *ic)
4547 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4548 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4549 if (ic->im->driver.callback_list)
4551 minput_callback (ic, Minput_preedit_done);
4552 minput_callback (ic, Minput_status_done);
4553 minput_callback (ic, Minput_candidates_done);
4555 (*ic->im->driver.destroy_ic) (ic);
4556 M17N_OBJECT_UNREF (ic->preedit);
4557 M17N_OBJECT_UNREF (ic->produced);
4558 M17N_OBJECT_UNREF (ic->plist);
4559 MDEBUG_PRINT (" done\n");
4566 @brief Filter an input key.
4568 The minput_filter () function filters input key $KEY according to
4569 input context $IC, and calls callback functions corresponding to
4570 @b Minput_preedit_draw, @b Minput_status_draw, and
4571 @b Minput_candidates_draw if the preedit text, the status, and the
4572 current candidate are changed respectively.
4574 To make the input method commit the current preedit text (if any)
4575 and shift to the initial state, call this function with #Mnil as
4578 To inform the input method about the focus-out event, call this
4579 function with @b Minput_focus_out as $KEY.
4581 To inform the input method about the focus-in event, call this
4582 function with @b Minput_focus_in as $KEY.
4584 To inform the input method about the focus-move event (i.e. input
4585 spot change within the same input context), call this function
4586 with @b Minput_focus_move as $KEY.
4589 If $KEY is filtered out, this function returns 1. In that case,
4590 the caller should discard the key. Otherwise, it returns 0, and
4591 the caller should handle the key, for instance, by calling the
4592 function minput_lookup () with the same key. */
4595 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4597 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4598 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4599 @b Minput_preedit_draw, @b Minput_status_draw,
4600 @b Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4603 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4604 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4605 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4606 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4608 @latexonly \IPAlabel{minput_filter} @endlatexonly
4612 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4619 if (ic->im->driver.callback_list
4620 && mtext_nchars (ic->preedit) > 0)
4621 minput_callback (ic, Minput_preedit_draw);
4623 ret = (*ic->im->driver.filter) (ic, key, arg);
4625 if (ic->im->driver.callback_list)
4627 if (ic->preedit_changed)
4628 minput_callback (ic, Minput_preedit_draw);
4629 if (ic->status_changed)
4630 minput_callback (ic, Minput_status_draw);
4631 if (ic->candidates_changed)
4632 minput_callback (ic, Minput_candidates_draw);
4641 @brief Look up a text produced in the input context.
4643 The minput_lookup () function looks up a text in the input context
4644 $IC. $KEY must be identical to the one that was used in the previous call of
4647 If a text was produced by the input method, it is concatenated
4650 This function calls #MInputDriver::lookup .
4653 If $KEY was correctly handled by the input method, this function
4654 returns 0. Otherwise, it returns -1, even though some text
4655 might be produced in $MT. */
4658 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4660 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4661 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4663 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4666 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4669 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4670 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4671 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4673 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4676 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4678 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4683 @brief Set the spot of the input context.
4685 The minput_set_spot () function sets the spot of input context $IC
4686 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4687 The semantics of these values depends on the input method driver.
4689 For instance, a driver designed to work in a CUI environment may
4690 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4691 $DESCENT . A driver designed to work in a window system may
4692 interpret $X and $Y as the pixel offsets relative to the origin of the
4693 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4694 descent pixels of the line at ($X . $Y ).
4696 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4698 $MT and $POS are the M-text and the character position at the spot.
4699 $MT may be @c NULL, in which case, the input method cannot get
4700 information about the text around the spot. */
4703 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4705 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4706 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4707 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4709 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4710 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4711 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4712 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4713 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4714 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4716 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4718 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4719 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4723 minput_set_spot (MInputContext *ic, int x, int y,
4724 int ascent, int descent, int fontsize,
4729 ic->spot.ascent = ascent;
4730 ic->spot.descent = descent;
4731 ic->spot.fontsize = fontsize;
4734 if (ic->im->driver.callback_list)
4735 minput_callback (ic, Minput_set_spot);
4740 @brief Toggle input method.
4742 The minput_toggle () function toggles the input method associated
4743 with input context $IC. */
4745 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4747 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4748 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4752 minput_toggle (MInputContext *ic)
4754 if (ic->im->driver.callback_list)
4755 minput_callback (ic, Minput_toggle);
4756 ic->active = ! ic->active;
4762 @brief Reset an input context.
4764 The minput_reset_ic () function resets input context $IC by
4765 calling a callback function corresponding to @b Minput_reset. It
4766 resets the status of $IC to its initial one. As the
4767 current preedit text is deleted without commitment, if necessary,
4768 call minput_filter () with the arg @b key #Mnil to force the input
4769 method to commit the preedit in advance. */
4772 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4774 ´Ø¿ô minput_reset_ic () ¤Ï @b Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4775 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4776 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4777 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4778 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @b key #Mnil ¤Ç¸Æ¤ó¤Ç
4779 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4782 minput_reset_ic (MInputContext *ic)
4784 if (ic->im->driver.callback_list)
4785 minput_callback (ic, Minput_reset);
4791 @brief Get title and icon filename of an input method.
4793 The minput_get_title_icon () function returns a plist containing a
4794 title and icon filename (if any) of an input method specified by
4795 $LANGUAGE and $NAME.
4797 The first element of the plist has key #Mtext and the value is an
4798 M-text of the title for identifying the input method. The second
4799 element (if any) has key #Mtext and the value is an M-text of the
4800 icon image (absolute) filename for the same purpose.
4803 If there exists a specified input method and it defines an title,
4804 a plist is returned. Otherwise, NULL is returned. The caller
4805 must free the plist by m17n_object_unref (). */
4807 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4809 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4810 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4813 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4814 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4815 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4818 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4819 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4820 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4823 minput_get_title_icon (MSymbol language, MSymbol name)
4825 MInputMethodInfo *im_info;
4832 im_info = get_im_info (language, name, Mnil, Mtitle);
4833 if (! im_info || !im_info->title)
4835 mt = mtext_get_prop (im_info->title, 0, Mtext);
4837 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4840 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4843 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4844 (char *) MSYMBOL_NAME (name));
4845 file = mdatabase__find_file (buf);
4846 if (! file && language == Mt)
4848 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4849 file = mdatabase__find_file (buf);
4854 mplist_add (plist, Mtext, im_info->title);
4857 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4859 mplist_add (plist, Mtext, mt);
4860 M17N_OBJECT_UNREF (mt);
4868 @brief Get description text of an input method.
4870 The minput_get_description () function returns an M-text that
4871 describes the input method specified by $LANGUAGE and $NAME.
4874 If the specified input method has a description text, a pointer to
4875 #MText is returned. The caller has to free it by m17n_object_unref ().
4876 If the input method does not have a description text, @c NULL is
4879 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4881 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4882 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4885 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4886 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4887 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4888 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4891 minput_get_description (MSymbol language, MSymbol name)
4893 MInputMethodInfo *im_info;
4901 extra = language, language = Mt;
4903 im_info = get_im_info (language, name, extra, Mdescription);
4904 if (! im_info || ! im_info->description)
4906 M17N_OBJECT_REF (im_info->description);
4907 return im_info->description;
4913 @brief Get information about input method command(s).
4915 The minput_get_command () function returns information about
4916 the command $COMMAND of the input method specified by $LANGUAGE and
4917 $NAME. An input method command is a pseudo key event to which one
4918 or more actual input key sequences are assigned.
4920 There are two kinds of commands, global and local. A global
4921 command has a global definition, and the description and the key
4922 assignment may be inherited by a local command. Each input method
4923 defines a local command which has a local key assignment. It may
4924 also declare a local command that inherits the definition of a
4925 global command of the same name.
4927 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4928 information about a global command. Otherwise information about a
4929 local command is returned.
4931 If $COMMAND is #Mnil, information about all commands is returned.
4933 The return value is a @e well-formed plist (@ref m17nPlist) of this
4936 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4938 @c NAME is a symbol representing the command name.
4940 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4941 command has no description.
4943 @c STATUS is a symbol representing how the key assignment is decided.
4944 The value is #Mnil (the default key assignment), @b Mcustomized (the
4945 key assignment is customized by per-user customization file), or
4946 @b Mconfigured (the key assignment is set by the call of
4947 minput_config_command ()). For a local command only, it may also
4948 be @b Minherited (the key assignment is inherited from the
4949 corresponding global command).
4951 @c KEYSEQ is a plist of one or more symbols representing a key
4952 sequence assigned to the command. If there's no KEYSEQ, the
4953 command is currently disabled (i.e. no key sequence can trigger
4954 actions of the command).
4956 If $COMMAND is not #Mnil, the first element of the returned plist
4957 contains the information about $COMMAND.
4961 If the requested information was found, a pointer to a non-empty
4962 plist is returned. As the plist is kept in the library, the
4963 caller must not modify nor free it.
4965 Otherwise (the specified input method or the specified command
4966 does not exist), @c NULL is returned. */
4968 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4970 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4971 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4972 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4973 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4975 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4976 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4977 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4978 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4979 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4981 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4982 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4985 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4987 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4990 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4992 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4994 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4997 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4998 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, @b Mcustomized ¡Ê¥æ¡¼
4999 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
5000 @b Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
5001 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
5002 @b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
5005 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
5006 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
5007 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
5008 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
5010 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
5011 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5015 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5016 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5019 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5024 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
5026 /* Return a description of the command COMMAND of the input method
5027 specified by LANGUAGE and NAME. */
5028 MPlist *cmd = minput_get_command (langauge, name, command);
5033 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
5034 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
5035 return (mplist_key (plist) == Mtext
5036 ? (MText *) mplist_value (plist)
5042 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5044 MInputMethodInfo *im_info;
5048 im_info = get_im_info (language, name, Mnil, Mcommand);
5050 || ! im_info->configured_cmds
5051 || MPLIST_TAIL_P (im_info->configured_cmds))
5053 if (command == Mnil)
5054 return im_info->configured_cmds;
5055 return mplist__assq (im_info->configured_cmds, command);
5061 @brief Configure the key sequence of an input method command.
5063 The minput_config_command () function assigns a list of key
5064 sequences $KEYSEQLIST to the command $COMMAND of the input method
5065 specified by $LANGUAGE and $NAME.
5067 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5068 sequences, and each key sequence must be a plist of symbols.
5070 If $KEYSEQLIST is an empty plist, any configuration and
5071 customization of the command are cancelled, and default key
5072 sequences become effective.
5074 If $KEYSEQLIST is NULL, the configuration of the command is
5075 canceled, and the original key sequences (what saved in per-user
5076 customization file, or the default one) become effective.
5078 In the latter two cases, $COMMAND can be #Mnil to make all the
5079 commands of the input method the target of the operation.
5081 If $NAME is #Mnil, this function configures the key assignment of a
5082 global command, not that of a specific input method.
5084 The configuration takes effect for input methods opened or
5085 re-opened later in the current session. In order to make the
5086 configuration take effect for the future session, it must be saved
5087 in a per-user customization file by the function
5088 minput_save_config ().
5091 If the operation was successful, this function returns 0,
5092 otherwise returns -1. The operation fails in these cases:
5094 <li>$KEYSEQLIST is not in a valid form.
5095 <li>$COMMAND is not available for the input method.
5096 <li>$LANGUAGE and $NAME do not specify an existing input method.
5100 minput_get_commands (), minput_save_config ().
5103 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5105 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5106 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5107 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5109 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5110 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5112 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5113 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5115 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5116 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5117 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5119 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5120 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5122 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5123 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5125 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5126 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5127 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5128 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5132 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5134 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5135 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5136 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5140 minput_get_commands (), minput_save_config ().
5144 /* Add "C-x u" to the "start" command of Unicode input method. */
5146 MSymbol start_command = msymbol ("start");
5147 MSymbol unicode = msymbol ("unicode");
5148 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5150 /* At first get the current key-sequence assignment. */
5151 cmd = minput_get_command (Mt, unicode, start_command);
5154 /* The input method does not have the command "start". Here
5155 should come some error handling code. */
5157 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5158 Extract the part (KEY-SEQUENCE ...). */
5159 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5160 /* Copy it because we should not modify it directly. */
5161 key_seq_list = mplist_copy (plist);
5163 key_seq = mplist ();
5164 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5165 mplist_add (key_seq, Msymbol, msymbol ("u"));
5166 mplist_add (key_seq_list, Mplist, key_seq);
5167 m17n_object_unref (key_seq);
5169 minput_config_command (Mt, unicode, start_command, key_seq_list);
5170 m17n_object_unref (key_seq_list);
5175 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5178 MInputMethodInfo *im_info, *config;
5183 im_info = get_im_info (language, name, Mnil, Mcommand);
5185 MERROR (MERROR_IM, -1);
5186 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5188 || ! mplist__assq (im_info->configured_cmds, command)))
5189 MERROR (MERROR_IM, -1);
5190 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5192 MPLIST_DO (plist, keyseqlist)
5193 if (! check_command_keyseq (plist))
5194 MERROR (MERROR_IM, -1);
5197 config = get_config_info (im_info);
5200 if (! im_config_list)
5201 im_config_list = mplist ();
5202 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5203 config->cmds = mplist ();
5204 config->vars = mplist ();
5207 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5208 /* Nothing to do. */
5211 if (command == Mnil)
5215 /* Cancal the configuration. */
5216 if (MPLIST_TAIL_P (config->cmds))
5218 mplist_set (config->cmds, Mnil, NULL);
5222 /* Cancal the customization. */
5223 MInputMethodInfo *custom = get_custom_info (im_info);
5225 if (MPLIST_TAIL_P (config->cmds)
5226 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5227 /* Nothing to do. */
5229 mplist_set (config->cmds, Mnil, NULL);
5230 MPLIST_DO (plist, custom->cmds)
5232 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5234 mplist_add (plist, Msymbol, command);
5235 mplist_push (config->cmds, Mplist, plist);
5236 M17N_OBJECT_UNREF (plist);
5242 plist = mplist__assq (config->cmds, command);
5245 /* Cancel the configuration. */
5248 mplist__pop_unref (plist);
5250 else if (MPLIST_TAIL_P (keyseqlist))
5252 /* Cancel the customization. */
5253 MInputMethodInfo *custom = get_custom_info (im_info);
5254 int no_custom = (! custom || ! custom->cmds
5255 || ! mplist__assq (custom->cmds, command));
5261 mplist_add (config->cmds, Mplist, plist);
5262 M17N_OBJECT_UNREF (plist);
5263 plist = mplist_add (plist, Msymbol, command);
5268 mplist__pop_unref (plist);
5271 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5272 plist = MPLIST_NEXT (plist);
5273 mplist_set (plist, Mnil, NULL);
5283 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5284 if (! MPLIST_TAIL_P (plist))
5285 mplist_set (plist, Mnil, NULL);
5290 mplist_add (config->cmds, Mplist, plist);
5291 M17N_OBJECT_UNREF (plist);
5292 plist = mplist_add (plist, Msymbol, command);
5293 plist = MPLIST_NEXT (plist);
5295 MPLIST_DO (keyseqlist, keyseqlist)
5297 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5298 plist = mplist_add (plist, Mplist, pl);
5299 M17N_OBJECT_UNREF (pl);
5303 config_all_commands (im_info);
5304 im_info->tick = time (NULL);
5311 @brief Get information about input method variable(s).
5313 The minput_get_variable () function returns information about
5314 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5315 An input method variable controls behavior of an input method.
5317 There are two kinds of variables, global and local. A global
5318 variable has a global definition, and the description and the value
5319 may be inherited by a local variable. Each input method defines a
5320 local variable which has local value. It may also declare a
5321 local variable that inherits definition of a global variable of
5324 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5325 variable is returned. Otherwise information about a local variable
5328 If $VARIABLE is #Mnil, information about all variables is
5331 The return value is a @e well-formed plist (@ref m17nPlist) of this
5334 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5336 @c NAME is a symbol representing the variable name.
5338 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5339 variable has no description.
5341 @c STATUS is a symbol representing how the value is decided. The
5342 value is #Mnil (the default value), @b Mcustomized (the value is
5343 customized by per-user customization file), or @b Mconfigured (the
5344 value is set by the call of minput_config_variable ()). For a
5345 local variable only, it may also be @b Minherited (the value is
5346 inherited from the corresponding global variable).
5348 @c VALUE is the initial value of the variable. If the key of this
5349 element is #Mt, the variable has no initial value. Otherwise, the
5350 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5353 @c VALID-VALUEs (if any) specify which values the variable can have.
5354 They have the same type (i.e. having the same key) as @c VALUE except
5355 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5356 may be a plist of two integers specifying the range of possible
5359 If there no @c VALID-VALUE, the variable can have any value as long
5360 as the type is the same as @c VALUE.
5362 If $VARIABLE is not #Mnil, the first element of the returned plist
5363 contains the information about $VARIABLE.
5367 If the requested information was found, a pointer to a non-empty
5368 plist is returned. As the plist is kept in the library, the
5369 caller must not modify nor free it.
5371 Otherwise (the specified input method or the specified variable
5372 does not exist), @c NULL is returned. */
5374 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5376 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5377 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5378 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5380 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5381 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5382 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5383 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5386 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5387 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5389 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5391 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5393 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5396 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5398 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5401 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5402 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, @b Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5403 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, @b Mconfigured
5404 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5405 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢@b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5406 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5408 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5409 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5410 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5412 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5413 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5414 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5415 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5417 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5420 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5421 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5425 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5426 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5429 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5433 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5435 MInputMethodInfo *im_info;
5439 im_info = get_im_info (language, name, Mnil, Mvariable);
5440 if (! im_info || ! im_info->configured_vars)
5442 if (variable == Mnil)
5443 return im_info->configured_vars;
5444 return mplist__assq (im_info->configured_vars, variable);
5450 @brief Configure the value of an input method variable.
5452 The minput_config_variable () function assigns $VALUE to the
5453 variable $VARIABLE of the input method specified by $LANGUAGE and
5456 If $VALUE is a non-empty plist, it must be a plist of one element
5457 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5458 the corresponding type. That value is assigned to the variable.
5460 If $VALUE is an empty plist, any configuration and customization
5461 of the variable are canceled, and the default value is assigned to
5464 If $VALUE is NULL, the configuration of the variable is canceled,
5465 and the original value (what saved in per-user customization file,
5466 or the default value) is assigned to the variable.
5468 In the latter two cases, $VARIABLE can be #Mnil to make all the
5469 variables of the input method the target of the operation.
5471 If $NAME is #Mnil, this function configures the value of global
5472 variable, not that of a specific input method.
5474 The configuration takes effect for input methods opened or
5475 re-opened later in the current session. To make the configuration
5476 take effect for the future session, it must be saved in a per-user
5477 customization file by the function minput_save_config ().
5481 If the operation was successful, this function returns 0,
5482 otherwise returns -1. The operation fails in these cases:
5484 <li>$VALUE is not in a valid form, the type does not match the
5485 definition, or the value is our of range.
5486 <li>$VARIABLE is not available for the input method.
5487 <li>$LANGUAGE and $NAME do not specify an existing input method.
5491 minput_get_variable (), minput_save_config (). */
5493 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5495 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5496 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5498 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5499 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5500 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5502 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5503 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5505 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5506 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5508 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5509 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5511 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5512 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5514 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5515 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5516 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5517 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5521 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5523 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5524 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5525 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5529 minput_get_commands (), minput_save_config ().
5532 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5535 MInputMethodInfo *im_info, *config;
5540 im_info = get_im_info (language, name, Mnil, Mvariable);
5542 MERROR (MERROR_IM, -1);
5543 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5545 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5546 MERROR (MERROR_IM, -1);
5548 if (value && ! MPLIST_TAIL_P (value))
5550 plist = MPLIST_PLIST (plist);
5551 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5552 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5553 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5554 if (MPLIST_KEY (plist) != Mt
5555 && ! check_variable_value (value, plist))
5556 MERROR (MERROR_IM, -1);
5559 config = get_config_info (im_info);
5562 if (! im_config_list)
5563 im_config_list = mplist ();
5564 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5565 config->cmds = mplist ();
5566 config->vars = mplist ();
5569 if (! value && MPLIST_TAIL_P (config->vars))
5570 /* Nothing to do. */
5573 if (variable == Mnil)
5577 /* Cancel the configuration. */
5578 if (MPLIST_TAIL_P (config->vars))
5580 mplist_set (config->vars, Mnil, NULL);
5584 /* Cancel the customization. */
5585 MInputMethodInfo *custom = get_custom_info (im_info);
5587 if (MPLIST_TAIL_P (config->vars)
5588 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5589 /* Nothing to do. */
5591 mplist_set (config->vars, Mnil, NULL);
5592 MPLIST_DO (plist, custom->vars)
5594 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5596 mplist_add (plist, Msymbol, variable);
5597 mplist_push (config->vars, Mplist, plist);
5598 M17N_OBJECT_UNREF (plist);
5604 plist = mplist__assq (config->vars, variable);
5607 /* Cancel the configuration. */
5610 mplist__pop_unref (plist);
5612 else if (MPLIST_TAIL_P (value))
5614 /* Cancel the customization. */
5615 MInputMethodInfo *custom = get_custom_info (im_info);
5616 int no_custom = (! custom || ! custom->vars
5617 || ! mplist__assq (custom->vars, variable));
5623 mplist_add (config->vars, Mplist, plist);
5624 M17N_OBJECT_UNREF (plist);
5625 plist = mplist_add (plist, Msymbol, variable);
5630 mplist__pop_unref (plist);
5633 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5634 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5635 mplist_set (plist, Mnil ,NULL);
5643 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5644 if (! MPLIST_TAIL_P (plist))
5645 mplist_set (plist, Mnil, NULL);
5650 mplist_add (config->vars, Mplist, plist);
5651 M17N_OBJECT_UNREF (plist);
5652 plist = mplist_add (plist, Msymbol, variable);
5653 plist = MPLIST_NEXT (plist);
5655 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5658 config_all_variables (im_info);
5659 im_info->tick = time (NULL);
5666 @brief Get the name of per-user customization file.
5668 The minput_config_file () function returns the absolute path name
5669 of per-user customization file into which minput_save_config ()
5670 save configurations. It is usually @c config.mic under the
5671 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5672 directory). It is not assured that the file of the returned name
5673 exists nor is readable/writable. If minput_save_config () fails
5674 and returns -1, an application program might check the file, make
5675 it writable (if possible), and try minput_save_config () again.
5679 This function returns a string. As the string is kept in the
5680 library, the caller must not modify nor free it.
5683 minput_save_config ()
5686 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5688 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5689 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5690 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5691 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5692 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5693 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5694 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5699 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5700 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5703 minput_save_config ()
5707 minput_config_file ()
5711 return mdatabase__file (im_custom_mdb);
5717 @brief Save configurations in per-user customization file.
5719 The minput_save_config () function saves the configurations done
5720 so far in the current session into the per-user customization
5725 If the operation was successful, 1 is returned. If the per-user
5726 customization file is currently locked, 0 is returned. In that
5727 case, the caller may wait for a while and try again. If the
5728 configuration file is not writable, -1 is returned. In that case,
5729 the caller may check the name of the file by calling
5730 minput_config_file (), make it writable if possible, and try
5734 minput_config_file () */
5736 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5738 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5739 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5743 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5744 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5745 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5746 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5750 minput_config_file () */
5753 minput_save_config (void)
5755 MPlist *data, *tail, *plist, *p, *elt;
5759 ret = mdatabase__lock (im_custom_mdb);
5762 if (! im_config_list)
5764 update_custom_info ();
5765 if (! im_custom_list)
5766 im_custom_list = mplist ();
5768 /* At first, reflect configuration in customization. */
5769 MPLIST_DO (plist, im_config_list)
5771 MPlist *pl = MPLIST_PLIST (plist);
5772 MSymbol language, name, extra, command, variable;
5773 MInputMethodInfo *custom, *config;
5775 language = MPLIST_SYMBOL (pl);
5776 pl = MPLIST_NEXT (pl);
5777 name = MPLIST_SYMBOL (pl);
5778 pl = MPLIST_NEXT (pl);
5779 extra = MPLIST_SYMBOL (pl);
5780 pl = MPLIST_NEXT (pl);
5781 config = MPLIST_VAL (pl);
5782 custom = get_custom_info (config);
5784 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5786 MPLIST_DO (pl, config->cmds)
5788 elt = MPLIST_PLIST (pl);
5789 command = MPLIST_SYMBOL (elt);
5791 p = mplist__assq (custom->cmds, command);
5793 custom->cmds = mplist (), p = NULL;
5794 elt = MPLIST_NEXT (elt);
5797 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5798 mplist_set (p, Mnil, NULL);
5803 mplist_add (custom->cmds, Mplist, p);
5804 M17N_OBJECT_UNREF (p);
5805 mplist_add (p, Msymbol, command);
5806 p = mplist_add (p, Msymbol, Mnil);
5807 p = MPLIST_NEXT (p);
5809 mplist__conc (p, elt);
5812 MPLIST_DO (pl, config->vars)
5814 elt = MPLIST_PLIST (pl);
5815 variable = MPLIST_SYMBOL (elt);
5817 p = mplist__assq (custom->vars, variable);
5819 custom->vars = mplist (), p = NULL;
5820 elt = MPLIST_NEXT (elt);
5823 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5824 mplist_set (p, Mnil, NULL);
5829 mplist_add (custom->vars, Mplist, p);
5830 M17N_OBJECT_UNREF (p);
5831 mplist_add (p, Msymbol, variable);
5832 p = mplist_add (p, Msymbol, Mnil);
5833 p = MPLIST_NEXT (p);
5835 mplist__conc (p, elt);
5838 free_im_list (im_config_list);
5839 im_config_list = NULL;
5841 /* Next, reflect customization to the actual plist to be written. */
5842 data = tail = mplist ();
5843 MPLIST_DO (plist, im_custom_list)
5845 MPlist *pl = MPLIST_PLIST (plist);
5846 MSymbol language, name, extra;
5847 MInputMethodInfo *custom, *im_info;
5849 language = MPLIST_SYMBOL (pl);
5850 pl = MPLIST_NEXT (pl);
5851 name = MPLIST_SYMBOL (pl);
5852 pl = MPLIST_NEXT (pl);
5853 extra = MPLIST_SYMBOL (pl);
5854 pl = MPLIST_NEXT (pl);
5855 custom = MPLIST_VAL (pl);
5856 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5857 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5859 im_info = lookup_im_info (im_info_list, language, name, extra);
5863 config_all_commands (im_info);
5865 config_all_variables (im_info);
5869 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5871 MPLIST_DO (p, custom->cmds)
5872 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5874 if (! MPLIST_TAIL_P (p))
5878 mplist_add (elt, Mplist, pl);
5879 M17N_OBJECT_UNREF (pl);
5880 pl = mplist_add (pl, Msymbol, Mcommand);
5881 MPLIST_DO (p, custom->cmds)
5882 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5883 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5886 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5888 MPLIST_DO (p, custom->vars)
5889 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5891 if (! MPLIST_TAIL_P (p))
5896 mplist_add (elt, Mplist, pl);
5897 M17N_OBJECT_UNREF (pl);
5898 pl = mplist_add (pl, Msymbol, Mvariable);
5899 MPLIST_DO (p, custom->vars)
5900 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5901 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5907 mplist_push (elt, Mplist, pl);
5908 M17N_OBJECT_UNREF (pl);
5909 pl = mplist_add (pl, Msymbol, Minput_method);
5910 pl = mplist_add (pl, Msymbol, language);
5911 pl = mplist_add (pl, Msymbol, name);
5913 pl = mplist_add (pl, Msymbol, extra);
5914 tail = mplist_add (tail, Mplist, elt);
5915 M17N_OBJECT_UNREF (elt);
5919 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5920 ret = mdatabase__save (im_custom_mdb, data);
5921 mdatabase__unlock (im_custom_mdb);
5922 M17N_OBJECT_UNREF (data);
5923 return (ret < 0 ? -1 : 1);
5930 @name Obsolete functions
5933 @name Obsolete ¤Ê´Ø¿ô
5939 @brief Get a list of variables of an input method (obsolete).
5941 This function is obsolete. Use minput_get_variable () instead.
5943 The minput_get_variables () function returns a plist (#MPlist) of
5944 variables used to control the behavior of the input method
5945 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5946 (@ref m17nPlist) of the following format:
5949 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5950 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5954 @c VARNAME is a symbol representing the variable name.
5956 @c DOC-MTEXT is an M-text describing the variable.
5958 @c DEFAULT-VALUE is the default value of the variable. It is a
5959 symbol, integer, or M-text.
5961 @c VALUEs (if any) specifies the possible values of the variable.
5962 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5963 @c TO), where @c FROM and @c TO specifies a range of possible
5966 For instance, suppose an input method has the variables:
5968 @li name:intvar, description:"value is an integer",
5969 initial value:0, value-range:0..3,10,20
5971 @li name:symvar, description:"value is a symbol",
5972 initial value:nil, value-range:a, b, c, nil
5974 @li name:txtvar, description:"value is an M-text",
5975 initial value:empty text, no value-range (i.e. any text)
5977 Then, the returned plist is as follows.
5980 (intvar ("value is an integer" 0 (0 3) 10 20)
5981 symvar ("value is a symbol" nil a b c nil)
5982 txtvar ("value is an M-text" ""))
5986 If the input method uses any variables, a pointer to #MPlist is
5987 returned. As the plist is kept in the library, the caller must not
5988 modify nor free it. If the input method does not use any
5989 variable, @c NULL is returned. */
5991 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5993 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5994 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5995 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5999 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6000 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
6004 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6006 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
6008 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
6011 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
6012 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
6013 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
6015 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
6017 @li name:intvar, ÀâÌÀ:"value is an integer",
6018 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
6020 @li name:symvar, ÀâÌÀ:"value is a symbol",
6021 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
6023 @li name:txtvar, ÀâÌÀ:"value is an M-text",
6024 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
6026 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
6029 (intvar ("value is an integer" 0 (0 3) 10 20)
6030 symvar ("value is a symbol" nil a b c nil)
6031 txtvar ("value is an M-text" ""))
6035 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
6036 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6037 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
6040 minput_get_variables (MSymbol language, MSymbol name)
6042 MInputMethodInfo *im_info;
6047 im_info = get_im_info (language, name, Mnil, Mvariable);
6048 if (! im_info || ! im_info->configured_vars)
6051 M17N_OBJECT_UNREF (im_info->bc_vars);
6052 im_info->bc_vars = mplist ();
6053 MPLIST_DO (vars, im_info->configured_vars)
6055 MPlist *plist = MPLIST_PLIST (vars);
6056 MPlist *elt = mplist ();
6058 mplist_push (im_info->bc_vars, Mplist, elt);
6059 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6060 elt = MPLIST_NEXT (elt);
6061 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6062 M17N_OBJECT_UNREF (elt);
6064 return im_info->bc_vars;
6070 @brief Set the initial value of an input method variable.
6072 The minput_set_variable () function sets the initial value of
6073 input method variable $VARIABLE to $VALUE for the input method
6074 specified by $LANGUAGE and $NAME.
6076 By default, the initial value is 0.
6078 This setting gets effective in a newly opened input method.
6081 If the operation was successful, 0 is returned. Otherwise -1 is
6082 returned, and #merror_code is set to @c MERROR_IM. */
6084 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6086 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6087 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6088 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6090 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6092 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6095 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6096 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6099 minput_set_variable (MSymbol language, MSymbol name,
6100 MSymbol variable, void *value)
6103 MInputMethodInfo *im_info;
6108 if (variable == Mnil)
6109 MERROR (MERROR_IM, -1);
6110 plist = minput_get_variable (language, name, variable);
6111 plist = MPLIST_PLIST (plist);
6112 plist = MPLIST_NEXT (plist);
6114 mplist_add (pl, MPLIST_KEY (plist), value);
6115 ret = minput_config_variable (language, name, variable, pl);
6116 M17N_OBJECT_UNREF (pl);
6119 im_info = get_im_info (language, name, Mnil, Mvariable);
6128 @brief Get information about input method commands.
6130 The minput_get_commands () function returns information about
6131 input method commands of the input method specified by $LANGUAGE
6132 and $NAME. An input method command is a pseudo key event to which
6133 one or more actual input key sequences are assigned.
6135 There are two kinds of commands, global and local. Global
6136 commands are used by multiple input methods for the same purpose,
6137 and have global key assignments. Local commands are used only by
6138 a specific input method, and have only local key assignments.
6140 Each input method may locally change key assignments for global
6141 commands. The global key assignment for a global command is
6142 effective only when the current input method does not have local
6143 key assignments for that command.
6145 If $NAME is #Mnil, information about global commands is returned.
6146 In this case $LANGUAGE is ignored.
6148 If $NAME is not #Mnil, information about those commands that have
6149 local key assignments in the input method specified by $LANGUAGE
6150 and $NAME is returned.
6153 If no input method commands are found, this function returns @c NULL.
6155 Otherwise, a pointer to a plist is returned. The key of each
6156 element in the plist is a symbol representing a command, and the
6157 value is a plist of the form COMMAND-INFO described below.
6159 The first element of COMMAND-INFO has the key #Mtext, and the
6160 value is an M-text describing the command.
6162 If there are no more elements, that means no key sequences are
6163 assigned to the command. Otherwise, each of the remaining
6164 elements has the key #Mplist, and the value is a plist whose keys are
6165 #Msymbol and values are symbols representing input keys, which are
6166 currently assigned to the command.
6168 As the returned plist is kept in the library, the caller must not
6169 modify nor free it. */
6171 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6173 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6174 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6175 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6176 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6178 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6179 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6180 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6181 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6183 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6184 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6185 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6188 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6189 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6191 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6192 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6196 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6198 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6199 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6200 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6202 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6203 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6204 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6207 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6208 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6209 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6210 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6211 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6213 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6214 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6217 minput_get_commands (MSymbol language, MSymbol name)
6219 MInputMethodInfo *im_info;
6224 im_info = get_im_info (language, name, Mnil, Mcommand);
6225 if (! im_info || ! im_info->configured_vars)
6227 M17N_OBJECT_UNREF (im_info->bc_cmds);
6228 im_info->bc_cmds = mplist ();
6229 MPLIST_DO (cmds, im_info->configured_cmds)
6231 MPlist *plist = MPLIST_PLIST (cmds);
6232 MPlist *elt = mplist ();
6234 mplist_push (im_info->bc_cmds, Mplist, elt);
6235 mplist_add (elt, MPLIST_SYMBOL (plist),
6236 mplist_copy (MPLIST_NEXT (plist)));
6237 M17N_OBJECT_UNREF (elt);
6239 return im_info->bc_cmds;
6245 @brief Assign a key sequence to an input method command (obsolete).
6247 This function is obsolete. Use minput_config_command () instead.
6249 The minput_assign_command_keys () function assigns input key
6250 sequence $KEYSEQ to input method command $COMMAND for the input
6251 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6252 key sequence is assigned globally no matter what $LANGUAGE is.
6253 Otherwise the key sequence is assigned locally.
6255 Each element of $KEYSEQ must have the key $Msymbol and the value
6256 must be a symbol representing an input key.
6258 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6259 globally or locally.
6261 This assignment gets effective in a newly opened input method.
6264 If the operation was successful, 0 is returned. Otherwise -1 is
6265 returned, and #merror_code is set to @c MERROR_IM. */
6267 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6269 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6270 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6271 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6272 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6273 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6275 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6276 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6278 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6279 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6281 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6285 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6286 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6289 minput_assign_command_keys (MSymbol language, MSymbol name,
6290 MSymbol command, MPlist *keyseq)
6296 if (command == Mnil)
6297 MERROR (MERROR_IM, -1);
6302 if (! check_command_keyseq (keyseq))
6303 MERROR (MERROR_IM, -1);
6305 mplist_add (plist, Mplist, keyseq);
6310 ret = minput_config_command (language, name, command, keyseq);
6311 M17N_OBJECT_UNREF (keyseq);
6318 @brief Call a callback function
6320 The minput_callback () functions calls a callback function
6321 $COMMAND assigned for the input context $IC. The caller must set
6322 specific elements in $IC->plist if the callback function requires.
6325 If there exists a specified callback function, 0 is returned.
6326 Otherwise -1 is returned. By side effects, $IC->plist may be
6330 minput_callback (MInputContext *ic, MSymbol command)
6332 MInputCallbackFunc func;
6334 if (! ic->im->driver.callback_list)
6336 func = ((MInputCallbackFunc)
6337 mplist_get_func (ic->im->driver.callback_list, command));
6340 (func) (ic, command);
6347 /*** @addtogroup m17nDebug */
6353 @brief Dump an input method.
6355 The mdebug_dump_im () function prints the input method $IM in a
6356 human readable way to the stderr. $INDENT specifies how many
6357 columns to indent the lines but the first one.
6360 This function returns $IM. */
6362 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6364 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6365 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6368 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6371 mdebug_dump_im (MInputMethod *im, int indent)
6373 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6376 prefix = (char *) alloca (indent + 1);
6377 memset (prefix, 32, indent);
6378 prefix[indent] = '\0';
6380 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6381 msymbol_name (im->name));
6382 mdebug_dump_mtext (im_info->title, 0, 0);
6383 if (im->name != Mnil)
6387 MPLIST_DO (state, im_info->states)
6389 fprintf (stderr, "\n%s ", prefix);
6390 dump_im_state (MPLIST_VAL (state), indent + 2);
6393 fprintf (stderr, ")");