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]);
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);
2399 shift_state (MInputContext *ic, MSymbol state_name)
2401 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2402 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2403 MIMState *orig_state = ic_info->state, *state;
2405 /* Find a state to shift to. If not found, shift to the initial
2407 if (state_name == Mt)
2409 if (! ic_info->prev_state)
2411 state = ic_info->prev_state;
2413 else if (state_name == Mnil)
2415 state = (MIMState *) MPLIST_VAL (im_info->states);
2419 state = (MIMState *) mplist_get (im_info->states, state_name);
2421 state = (MIMState *) MPLIST_VAL (im_info->states);
2427 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2428 MSYMBOL_NAME (orig_state->name),
2429 MSYMBOL_NAME (state->name));
2431 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2434 /* Enter the new state. */
2435 ic_info->state = state;
2436 ic_info->map = state->map;
2437 ic_info->state_key_head = ic_info->key_head;
2438 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2440 /* We have shifted to the initial state. */
2441 preedit_commit (ic, 0);
2442 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2443 ic_info->state_pos = ic->cursor_pos;
2444 if (state != orig_state)
2446 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2448 /* Shifted to the initial state. */
2449 ic_info->prev_state = NULL;
2450 M17N_OBJECT_UNREF (ic_info->vars_saved);
2451 ic_info->vars_saved = mplist_copy (ic_info->vars);
2454 ic_info->prev_state = orig_state;
2457 ic->status = state->title;
2459 ic->status = im_info->title;
2460 ic->status_changed = 1;
2461 if (ic_info->map == ic_info->state->map
2462 && ic_info->map->map_actions)
2464 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2465 MSYMBOL_NAME (state->name));
2466 take_action_list (ic, ic_info->map->map_actions);
2471 /* Find a candidate group that contains a candidate number INDEX from
2472 PLIST. Set START_INDEX to the first candidate number of the group,
2473 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2474 candidate group number if they are non-NULL. If INDEX is -1, find
2475 the last candidate group. */
2478 find_candidates_group (MPlist *plist, int index,
2479 int *start_index, int *end_index, int *group_index)
2481 int i = 0, gidx = 0, len;
2483 MPLIST_DO (plist, plist)
2485 if (MPLIST_MTEXT_P (plist))
2486 len = mtext_nchars (MPLIST_MTEXT (plist));
2488 len = mplist_length (MPLIST_PLIST (plist));
2489 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2495 *end_index = i + len;
2497 *group_index = gidx;
2506 /* Adjust markers for the change of preedit text.
2507 If FROM == TO, the change is insertion of INS chars.
2508 If FROM < TO and INS == 0, the change is deletion of the range.
2509 If FROM < TO and INS > 0, the change is replacement. */
2512 adjust_markers (MInputContext *ic, int from, int to, int ins)
2514 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2519 MPLIST_DO (markers, ic_info->markers)
2520 if (MPLIST_INTEGER (markers) > from)
2521 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2522 if (ic->cursor_pos >= from)
2523 ic->cursor_pos += ins;
2527 MPLIST_DO (markers, ic_info->markers)
2529 if (MPLIST_INTEGER (markers) >= to)
2530 MPLIST_VAL (markers)
2531 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2532 else if (MPLIST_INTEGER (markers) > from)
2533 MPLIST_VAL (markers) = (void *) from;
2535 if (ic->cursor_pos >= to)
2536 ic->cursor_pos += ins - (to - from);
2537 else if (ic->cursor_pos > from)
2538 ic->cursor_pos = from;
2544 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2546 int nchars = mt ? mtext_nchars (mt) : 1;
2550 mtext_ins (ic->preedit, pos, mt);
2551 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2555 mtext_ins_char (ic->preedit, pos, c, 1);
2557 MDEBUG_PRINT1 ("('%c')", c);
2559 MDEBUG_PRINT1 ("(U+%04X)", c);
2561 adjust_markers (ic, pos, pos, nchars);
2562 ic->preedit_changed = 1;
2567 preedit_delete (MInputContext *ic, int from, int to)
2569 mtext_del (ic->preedit, from, to);
2570 adjust_markers (ic, from, to, 0);
2571 ic->preedit_changed = 1;
2575 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2579 mtext_del (ic->preedit, from, to);
2582 mtext_ins (ic->preedit, from, mt);
2583 ins = mtext_nchars (mt);
2587 mtext_ins_char (ic->preedit, from, c, 1);
2590 adjust_markers (ic, from, to, ins);
2591 ic->preedit_changed = 1;
2596 preedit_commit (MInputContext *ic, int need_prefix)
2598 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2599 int preedit_len = mtext_nchars (ic->preedit);
2601 if (preedit_len > 0)
2605 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2606 Mcandidate_list, NULL, 0);
2607 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2608 Mcandidate_index, NULL, 0);
2609 mtext_cat (ic->produced, ic->preedit);
2615 MDEBUG_PRINT1 ("\n [IM] [%s]",
2616 MSYMBOL_NAME (ic_info->state->name));
2617 MDEBUG_PRINT (" (commit");
2618 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2619 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2623 mtext_reset (ic->preedit);
2624 mtext_reset (ic_info->preedit_saved);
2625 MPLIST_DO (p, ic_info->markers)
2627 ic->cursor_pos = ic_info->state_pos = 0;
2628 ic->preedit_changed = 1;
2629 ic_info->commit_key_head = ic_info->key_head;
2631 if (ic->candidate_list)
2633 M17N_OBJECT_UNREF (ic->candidate_list);
2634 ic->candidate_list = NULL;
2635 ic->candidate_index = 0;
2636 ic->candidate_from = ic->candidate_to = 0;
2637 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2638 if (ic->candidate_show)
2640 ic->candidate_show = 0;
2641 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2647 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2649 int code = marker_code (sym, 0);
2651 if (mt && (code == '[' || code == ']'))
2655 if (code == '[' && current > 0)
2657 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2661 else if (code == ']' && current < mtext_nchars (mt))
2663 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2669 return (code == '<' ? 0
2670 : code == '>' ? limit
2671 : code == '-' ? current - 1
2672 : code == '+' ? current + 1
2673 : code == '=' ? current
2674 : code - '0' > limit ? limit
2678 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2682 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2684 int from = mtext_property_start (prop);
2685 int to = mtext_property_end (prop);
2687 MPlist *candidate_list = mtext_property_value (prop);
2688 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2690 int ingroup_index = idx - start;
2693 candidate_list = mplist_copy (candidate_list);
2694 if (MPLIST_MTEXT_P (group))
2696 mt = MPLIST_MTEXT (group);
2697 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2705 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2706 i++, plist = MPLIST_NEXT (plist));
2707 mt = MPLIST_MTEXT (plist);
2708 preedit_replace (ic, from, to, mt, 0);
2709 to = from + mtext_nchars (mt);
2711 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2712 M17N_OBJECT_UNREF (candidate_list);
2713 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2714 ic->cursor_pos = to;
2718 get_select_charset (MInputContextInfo * ic_info)
2720 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2723 if (! MPLIST_VAL (plist))
2725 sym = MPLIST_SYMBOL (plist);
2728 return MCHARSET (sym);
2731 /* The returned plist must be UNREFed. */
2734 adjust_candidates (MPlist *plist, MCharset *charset)
2738 /* plist ::= MTEXT ... | PLIST ... */
2739 plist = mplist_copy (plist);
2740 if (MPLIST_MTEXT_P (plist))
2743 while (! MPLIST_TAIL_P (pl))
2745 /* pl ::= MTEXT ... */
2746 MText *mt = MPLIST_MTEXT (pl);
2750 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2752 c = mtext_ref_char (mt, i);
2753 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2757 mt = mtext_dup (mt);
2758 mplist_set (pl, Mtext, mt);
2759 M17N_OBJECT_UNREF (mt);
2762 mtext_del (mt, i, i + 1);
2765 if (mtext_len (mt) > 0)
2766 pl = MPLIST_NEXT (pl);
2770 M17N_OBJECT_UNREF (mt);
2774 else /* MPLIST_PLIST_P (plist) */
2777 while (! MPLIST_TAIL_P (pl))
2779 /* pl ::= (MTEXT ...) ... */
2780 MPlist *p = MPLIST_PLIST (pl);
2782 /* p ::= MTEXT ... */
2786 while (! MPLIST_TAIL_P (p0))
2788 MText *mt = MPLIST_MTEXT (p0);
2791 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2793 c = mtext_ref_char (mt, i);
2794 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2799 p0 = MPLIST_NEXT (p0);
2806 p = mplist_copy (p);
2807 mplist_set (pl, Mplist, p);
2808 M17N_OBJECT_UNREF (p);
2812 p0 = MPLIST_NEXT (p0);
2815 M17N_OBJECT_UNREF (mt);
2818 if (! MPLIST_TAIL_P (p))
2819 pl = MPLIST_NEXT (pl);
2823 M17N_OBJECT_UNREF (p);
2827 if (MPLIST_TAIL_P (plist))
2829 M17N_OBJECT_UNREF (plist);
2835 /* The returned Plist must be UNREFed. */
2838 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2840 MCharset *charset = get_select_charset (ic_info);
2845 plist = resolve_variable (ic_info, Mcandidates_group_size);
2846 column = MPLIST_INTEGER (plist);
2848 plist = MPLIST_PLIST (args);
2853 plist = adjust_candidates (plist, charset);
2858 M17N_OBJECT_REF (plist);
2863 if (MPLIST_MTEXT_P (plist))
2865 MText *mt = MPLIST_MTEXT (plist);
2866 MPlist *next = MPLIST_NEXT (plist);
2868 if (MPLIST_TAIL_P (next))
2869 M17N_OBJECT_REF (mt);
2872 mt = mtext_dup (mt);
2873 while (! MPLIST_TAIL_P (next))
2875 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2876 next = MPLIST_NEXT (next);
2879 M17N_OBJECT_UNREF (plist);
2881 len = mtext_nchars (mt);
2883 mplist_add (plist, Mtext, mt);
2886 for (i = 0; i < len; i += column)
2888 int to = (i + column < len ? i + column : len);
2889 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2891 mplist_add (plist, Mtext, sub);
2892 M17N_OBJECT_UNREF (sub);
2895 M17N_OBJECT_UNREF (mt);
2897 else if (MPLIST_PLIST_P (plist))
2899 MPlist *tail = plist;
2900 MPlist *new = mplist ();
2901 MPlist *this = mplist ();
2904 MPLIST_DO (tail, tail)
2906 MPlist *p = MPLIST_PLIST (tail);
2910 MText *mt = MPLIST_MTEXT (p);
2912 if (count == column)
2914 mplist_add (new, Mplist, this);
2915 M17N_OBJECT_UNREF (this);
2919 mplist_add (this, Mtext, mt);
2923 mplist_add (new, Mplist, this);
2924 M17N_OBJECT_UNREF (this);
2925 mplist_set (plist, Mnil, NULL);
2926 MPLIST_DO (tail, new)
2928 MPlist *elt = MPLIST_PLIST (tail);
2930 mplist_add (plist, Mplist, elt);
2932 M17N_OBJECT_UNREF (new);
2940 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2942 MPlist *action = NULL;
2946 if (MPLIST_SYMBOL_P (action_list))
2948 MSymbol var = MPLIST_SYMBOL (action_list);
2951 MPLIST_DO (p, ic_info->vars)
2952 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2954 if (MPLIST_TAIL_P (p))
2956 action = MPLIST_NEXT (MPLIST_PLIST (p));
2957 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2960 if (MPLIST_PLIST_P (action_list))
2962 action = MPLIST_PLIST (action_list);
2963 if (MPLIST_SYMBOL_P (action))
2965 name = MPLIST_SYMBOL (action);
2966 args = MPLIST_NEXT (action);
2968 && MPLIST_PLIST_P (args))
2969 mplist_set (action, Msymbol, M_candidates);
2971 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2974 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2975 mplist_push (action, Msymbol, M_candidates);
2976 mplist_set (action_list, Mplist, action);
2977 M17N_OBJECT_UNREF (action);
2980 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2983 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2984 mplist_push (action, Msymbol, Minsert);
2985 mplist_set (action_list, Mplist, action);
2986 M17N_OBJECT_UNREF (action);
2991 /* Perform list of actions in ACTION_LIST for the current input
2992 context IC. If unhandle action was not performed, return 0.
2993 Otherwise, return -1. */
2996 take_action_list (MInputContext *ic, MPlist *action_list)
2998 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2999 MPlist *candidate_list = ic->candidate_list;
3000 int candidate_index = ic->candidate_index;
3001 int candidate_show = ic->candidate_show;
3002 MTextProperty *prop;
3004 MPLIST_DO (action_list, action_list)
3006 MPlist *action = regularize_action (action_list, ic_info);
3012 name = MPLIST_SYMBOL (action);
3013 args = MPLIST_NEXT (action);
3015 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
3016 if (name == Minsert)
3018 if (MPLIST_SYMBOL_P (args))
3020 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3021 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3024 if (MPLIST_MTEXT_P (args))
3025 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3026 else /* MPLIST_INTEGER_P (args)) */
3027 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3029 else if (name == M_candidates)
3031 MPlist *plist = get_candidate_list (ic_info, args);
3037 if (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist))
3039 M17N_OBJECT_UNREF (plist);
3042 if (MPLIST_MTEXT_P (plist))
3044 preedit_insert (ic, ic->cursor_pos, NULL,
3045 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3050 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3052 preedit_insert (ic, ic->cursor_pos, mt, 0);
3053 len = mtext_nchars (mt);
3055 pl = mplist_copy (plist);
3056 M17N_OBJECT_UNREF (plist);
3057 mtext_put_prop (ic->preedit,
3058 ic->cursor_pos - len, ic->cursor_pos,
3059 Mcandidate_list, pl);
3060 M17N_OBJECT_UNREF (pl);
3061 mtext_put_prop (ic->preedit,
3062 ic->cursor_pos - len, ic->cursor_pos,
3063 Mcandidate_index, (void *) 0);
3065 else if (name == Mselect)
3068 int code, idx, gindex;
3069 int pos = ic->cursor_pos;
3071 int idx_decided = 0;
3074 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3077 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3078 group = find_candidates_group (mtext_property_value (prop), idx,
3079 &start, &end, &gindex);
3080 if (MPLIST_SYMBOL_P (args))
3082 code = marker_code (MPLIST_SYMBOL (args), 0);
3085 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3086 if (! MPLIST_INTEGER_P (args))
3088 idx = start + MPLIST_INTEGER (args);
3089 if (idx < start || idx >= end)
3097 if (code != '[' && code != ']')
3102 ? new_index (NULL, ic->candidate_index - start,
3103 end - start - 1, MPLIST_SYMBOL (args),
3105 : MPLIST_INTEGER (args)));
3108 find_candidates_group (mtext_property_value (prop), -1,
3113 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3118 int ingroup_index = idx - start;
3121 group = mtext_property_value (prop);
3122 len = mplist_length (group);
3135 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3136 idx += (MPLIST_MTEXT_P (group)
3137 ? mtext_nchars (MPLIST_MTEXT (group))
3138 : mplist_length (MPLIST_PLIST (group)));
3139 len = (MPLIST_MTEXT_P (group)
3140 ? mtext_nchars (MPLIST_MTEXT (group))
3141 : mplist_length (MPLIST_PLIST (group)));
3142 if (ingroup_index >= len)
3143 ingroup_index = len - 1;
3144 idx += ingroup_index;
3146 update_candidate (ic, prop, idx);
3147 MDEBUG_PRINT1 ("(%d)", idx);
3149 else if (name == Mshow)
3150 ic->candidate_show = 1;
3151 else if (name == Mhide)
3152 ic->candidate_show = 0;
3153 else if (name == Mdelete)
3155 int len = mtext_nchars (ic->preedit);
3159 if (MPLIST_SYMBOL_P (args)
3160 && surrounding_pos (MPLIST_SYMBOL (args), &pos))
3162 to = ic->cursor_pos + pos;
3165 delete_surrounding_text (ic, to);
3170 delete_surrounding_text (ic, to - len);
3176 to = (MPLIST_SYMBOL_P (args)
3177 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3179 : MPLIST_INTEGER (args));
3184 pos = to - ic->cursor_pos;
3186 MDEBUG_PRINT1 ("(%d)", pos);
3187 if (to < ic->cursor_pos)
3188 preedit_delete (ic, to, ic->cursor_pos);
3189 else if (to > ic->cursor_pos)
3190 preedit_delete (ic, ic->cursor_pos, to);
3192 else if (name == Mmove)
3194 int len = mtext_nchars (ic->preedit);
3196 = (MPLIST_SYMBOL_P (args)
3197 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3199 : MPLIST_INTEGER (args));
3205 if (pos != ic->cursor_pos)
3207 ic->cursor_pos = pos;
3208 ic->preedit_changed = 1;
3210 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3212 else if (name == Mmark)
3214 int code = marker_code (MPLIST_SYMBOL (args), 0);
3218 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3219 (void *) ic->cursor_pos);
3220 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3223 else if (name == Mpushback)
3225 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3229 if (MPLIST_SYMBOL_P (args))
3231 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3232 if (MPLIST_INTEGER_P (args))
3233 num = MPLIST_INTEGER (args);
3238 num = MPLIST_INTEGER (args);
3241 ic_info->key_head -= num;
3243 ic_info->key_head = 0;
3245 ic_info->key_head = - num;
3246 if (ic_info->key_head > ic_info->used)
3247 ic_info->key_head = ic_info->used;
3249 else if (MPLIST_MTEXT_P (args))
3251 MText *mt = MPLIST_MTEXT (args);
3252 int i, len = mtext_nchars (mt);
3255 ic_info->key_head--;
3256 for (i = 0; i < len; i++)
3258 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3259 if (ic_info->key_head + i < ic_info->used)
3260 ic_info->keys[ic_info->key_head + i] = key;
3262 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3267 MPlist *plist = MPLIST_PLIST (args), *pl;
3271 ic_info->key_head--;
3273 MPLIST_DO (pl, plist)
3275 key = MPLIST_SYMBOL (pl);
3276 if (ic_info->key_head < ic_info->used)
3277 ic_info->keys[ic_info->key_head + i] = key;
3279 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3284 else if (name == Mpop)
3286 if (ic_info->key_head < ic_info->used)
3287 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3289 else if (name == Mcall)
3291 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3292 MIMExternalFunc func = NULL;
3293 MSymbol module, func_name;
3294 MPlist *func_args, *val;
3297 module = MPLIST_SYMBOL (args);
3298 args = MPLIST_NEXT (args);
3299 func_name = MPLIST_SYMBOL (args);
3301 if (im_info->externals)
3303 MIMExternalModule *external
3304 = (MIMExternalModule *) mplist_get (im_info->externals,
3307 func = ((MIMExternalFunc)
3308 mplist_get_func (external->func_list, func_name));
3312 func_args = mplist ();
3313 mplist_add (func_args, Mt, ic);
3314 MPLIST_DO (args, MPLIST_NEXT (args))
3318 if (MPLIST_KEY (args) == Msymbol
3319 && MPLIST_KEY (args) != Mnil
3320 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3322 code = new_index (ic, ic->cursor_pos,
3323 mtext_nchars (ic->preedit),
3324 MPLIST_SYMBOL (args), ic->preedit);
3325 mplist_add (func_args, Minteger, (void *) code);
3328 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3330 val = (func) (func_args);
3331 M17N_OBJECT_UNREF (func_args);
3332 if (val && ! MPLIST_TAIL_P (val))
3333 ret = take_action_list (ic, val);
3334 M17N_OBJECT_UNREF (val);
3338 else if (name == Mshift)
3340 shift_state (ic, MPLIST_SYMBOL (args));
3342 else if (name == Mundo)
3344 int intarg = (MPLIST_TAIL_P (args)
3346 : integer_value (ic, args, 0));
3348 mtext_reset (ic->preedit);
3349 mtext_reset (ic_info->preedit_saved);
3350 mtext_reset (ic->produced);
3351 M17N_OBJECT_UNREF (ic_info->vars);
3352 ic_info->vars = mplist_copy (ic_info->vars_saved);
3353 ic->cursor_pos = ic_info->state_pos = 0;
3354 ic_info->state_key_head = ic_info->key_head
3355 = ic_info->commit_key_head = 0;
3357 shift_state (ic, Mnil);
3360 if (MPLIST_TAIL_P (args))
3365 ic_info->used += intarg;
3368 ic_info->used = intarg;
3371 else if (name == Mset || name == Madd || name == Msub
3372 || name == Mmul || name == Mdiv)
3374 MSymbol sym = MPLIST_SYMBOL (args);
3375 MPlist *value = resolve_variable (ic_info, sym);
3379 val1 = MPLIST_INTEGER (value);
3380 args = MPLIST_NEXT (args);
3381 val2 = resolve_expression (ic, args);
3383 val1 = val2, op = "=";
3384 else if (name == Madd)
3385 val1 += val2, op = "+=";
3386 else if (name == Msub)
3387 val1 -= val2, op = "-=";
3388 else if (name == Mmul)
3389 val1 *= val2, op = "*=";
3391 val1 /= val2, op = "/=";
3392 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3393 MSYMBOL_NAME (sym), op, val1, val1);
3394 mplist_set (value, Minteger, (void *) val1);
3396 else if (name == Mequal || name == Mless || name == Mgreater
3397 || name == Mless_equal || name == Mgreater_equal)
3400 MPlist *actions1, *actions2;
3403 val1 = resolve_expression (ic, args);
3404 args = MPLIST_NEXT (args);
3405 val2 = resolve_expression (ic, args);
3406 args = MPLIST_NEXT (args);
3407 actions1 = MPLIST_PLIST (args);
3408 args = MPLIST_NEXT (args);
3409 if (MPLIST_TAIL_P (args))
3412 actions2 = MPLIST_PLIST (args);
3413 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3414 if (name == Mequal ? val1 == val2
3415 : name == Mless ? val1 < val2
3416 : name == Mgreater ? val1 > val2
3417 : name == Mless_equal ? val1 <= val2
3420 MDEBUG_PRINT ("ok");
3421 ret = take_action_list (ic, actions1);
3425 MDEBUG_PRINT ("no");
3427 ret = take_action_list (ic, actions2);
3432 else if (name == Mcond)
3436 MPLIST_DO (args, args)
3441 if (! MPLIST_PLIST (args))
3443 cond = MPLIST_PLIST (args);
3444 if (resolve_expression (ic, cond) != 0)
3446 MDEBUG_PRINT1 ("(%dth)", idx);
3447 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3453 else if (name == Mcommit)
3455 preedit_commit (ic, 0);
3457 else if (name == Munhandle)
3459 preedit_commit (ic, 0);
3464 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3468 && (actions = mplist_get (im_info->macros, name)))
3470 if (take_action_list (ic, actions) < 0)
3476 if (ic->candidate_list)
3478 M17N_OBJECT_UNREF (ic->candidate_list);
3479 ic->candidate_list = NULL;
3481 if (ic->cursor_pos > 0
3482 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3485 ic->candidate_list = mtext_property_value (prop);
3486 M17N_OBJECT_REF (ic->candidate_list);
3488 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3490 ic->candidate_from = mtext_property_start (prop);
3491 ic->candidate_to = mtext_property_end (prop);
3494 if (candidate_list != ic->candidate_list)
3495 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3496 if (candidate_index != ic->candidate_index)
3497 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3498 if (candidate_show != ic->candidate_show)
3499 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3504 /* Handle the input key KEY in the current state and map specified in
3505 the input context IC. If KEY is handled correctly, return 0.
3506 Otherwise, return -1. */
3509 handle_key (MInputContext *ic)
3511 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3512 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3513 MIMMap *map = ic_info->map;
3514 MIMMap *submap = NULL;
3515 MSymbol key = ic_info->keys[ic_info->key_head];
3516 MSymbol alias = Mnil;
3519 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3520 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3524 submap = mplist_get (map->submaps, key);
3527 && (alias = msymbol_get (alias, M_key_alias))
3529 submap = mplist_get (map->submaps, alias);
3534 if (! alias || alias == key)
3535 MDEBUG_PRINT (" submap-found");
3537 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3538 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3539 ic->preedit_changed = 1;
3540 ic->cursor_pos = ic_info->state_pos;
3541 ic_info->key_head++;
3542 ic_info->map = map = submap;
3543 if (map->map_actions)
3545 MDEBUG_PRINT (" map-actions:");
3546 if (take_action_list (ic, map->map_actions) < 0)
3548 MDEBUG_PRINT ("\n");
3552 else if (map->submaps)
3554 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3556 MSymbol key = ic_info->keys[i];
3557 char *name = msymbol_name (key);
3559 if (! name[0] || ! name[1])
3560 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3564 /* If this is the terminal map or we have shifted to another
3565 state, perform branch actions (if any). */
3566 if (! map->submaps || map != ic_info->map)
3568 if (map->branch_actions)
3570 MDEBUG_PRINT (" branch-actions:");
3571 if (take_action_list (ic, map->branch_actions) < 0)
3573 MDEBUG_PRINT ("\n");
3577 /* If MAP is still not the root map, shift to the current
3579 if (ic_info->map != ic_info->state->map)
3580 shift_state (ic, ic_info->state->name);
3585 /* MAP can not handle KEY. */
3587 /* Perform branch actions if any. */
3588 if (map->branch_actions)
3590 MDEBUG_PRINT (" branch-actions:");
3591 if (take_action_list (ic, map->branch_actions) < 0)
3593 MDEBUG_PRINT ("\n");
3598 if (map == ic_info->map)
3600 /* The above branch actions didn't change the state. */
3602 /* If MAP is the root map of the initial state, and there
3603 still exist an unhandled key, it means that the current
3604 input method can not handle it. */
3605 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3606 && ic_info->key_head < ic_info->used)
3608 MDEBUG_PRINT (" unhandled\n");
3612 if (map != ic_info->state->map)
3614 /* MAP is not the root map. Shift to the root map of the
3616 shift_state (ic, ic_info->state->name);
3618 else if (! map->branch_actions)
3620 /* MAP is the root map without any default branch
3621 actions. Shift to the initial state. */
3622 shift_state (ic, Mnil);
3626 MDEBUG_PRINT ("\n");
3630 /* Initialize IC->ic_info. */
3633 init_ic_info (MInputContext *ic)
3635 MInputMethodInfo *im_info = ic->im->info;
3636 MInputContextInfo *ic_info = ic->info;
3639 MLIST_INIT1 (ic_info, keys, 8);;
3641 ic_info->markers = mplist ();
3643 ic_info->vars = mplist ();
3644 if (im_info->configured_vars)
3645 MPLIST_DO (plist, im_info->configured_vars)
3647 MPlist *pl = MPLIST_PLIST (plist);
3648 MSymbol name = MPLIST_SYMBOL (pl);
3650 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3651 if (MPLIST_KEY (pl) != Mt)
3653 MPlist *p = mplist ();
3655 mplist_push (ic_info->vars, Mplist, p);
3656 M17N_OBJECT_UNREF (p);
3657 mplist_add (p, Msymbol, name);
3658 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3661 ic_info->vars_saved = mplist_copy (ic_info->vars);
3663 if (im_info->externals)
3665 MPlist *func_args = mplist (), *plist;
3667 mplist_add (func_args, Mt, ic);
3668 MPLIST_DO (plist, im_info->externals)
3670 MIMExternalModule *external = MPLIST_VAL (plist);
3671 MIMExternalFunc func
3672 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3677 M17N_OBJECT_UNREF (func_args);
3680 ic_info->preedit_saved = mtext ();
3681 ic_info->tick = im_info->tick;
3684 /* Finalize IC->ic_info. */
3687 fini_ic_info (MInputContext *ic)
3689 MInputMethodInfo *im_info = ic->im->info;
3690 MInputContextInfo *ic_info = ic->info;
3692 if (im_info->externals)
3694 MPlist *func_args = mplist (), *plist;
3696 mplist_add (func_args, Mt, ic);
3697 MPLIST_DO (plist, im_info->externals)
3699 MIMExternalModule *external = MPLIST_VAL (plist);
3700 MIMExternalFunc func
3701 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3706 M17N_OBJECT_UNREF (func_args);
3709 MLIST_FREE1 (ic_info, keys);
3710 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3711 M17N_OBJECT_UNREF (ic_info->markers);
3712 M17N_OBJECT_UNREF (ic_info->vars);
3713 M17N_OBJECT_UNREF (ic_info->vars_saved);
3714 M17N_OBJECT_UNREF (ic_info->preceding_text);
3715 M17N_OBJECT_UNREF (ic_info->following_text);
3717 memset (ic_info, 0, sizeof (MInputContextInfo));
3721 re_init_ic (MInputContext *ic, int reload)
3723 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3724 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3725 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3727 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3728 preedit_changed = mtext_nchars (ic->preedit) > 0;
3729 cursor_pos_changed = ic->cursor_pos > 0;
3730 candidates_changed = 0;
3731 if (ic->candidate_list)
3733 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3734 M17N_OBJECT_UNREF (ic->candidate_list);
3735 ic->candidate_list = NULL;
3737 if (ic->candidate_show)
3739 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3740 ic->candidate_show = 0;
3742 if (ic->candidate_index > 0)
3744 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3745 ic->candidate_index = 0;
3746 ic->candidate_from = ic->candidate_to = 0;
3748 if (mtext_nchars (ic->produced) > 0)
3749 mtext_reset (ic->produced);
3750 if (mtext_nchars (ic->preedit) > 0)
3751 mtext_reset (ic->preedit);
3753 M17N_OBJECT_UNREF (ic->plist);
3754 ic->plist = mplist ();
3758 reload_im_info (im_info);
3759 if (! im_info->states)
3761 struct MIMState *state;
3763 M17N_OBJECT (state, free_state, MERROR_IM);
3764 state->name = msymbol ("init");
3765 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3766 MSTRUCT_CALLOC (state->map, MERROR_IM);
3767 im_info->states = mplist ();
3768 mplist_add (im_info->states, state->name, state);
3771 shift_state (ic, Mnil);
3773 ic->status_changed = status_changed;
3774 ic->preedit_changed = preedit_changed;
3775 ic->cursor_pos_changed = cursor_pos_changed;
3776 ic->candidates_changed = candidates_changed;
3780 reset_ic (MInputContext *ic, MSymbol ignore)
3782 MDEBUG_PRINT ("\n [IM] reset\n");
3787 open_im (MInputMethod *im)
3789 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3791 if (! im_info || ! im_info->states)
3792 MERROR (MERROR_IM, -1);
3799 close_im (MInputMethod *im)
3805 create_ic (MInputContext *ic)
3807 MInputContextInfo *ic_info;
3809 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3812 shift_state (ic, Mnil);
3817 destroy_ic (MInputContext *ic)
3824 check_reload (MInputContext *ic, MSymbol key)
3826 MInputMethodInfo *im_info = ic->im->info;
3827 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3831 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3835 MPLIST_DO (plist, plist)
3837 MSymbol this_key, alias;
3839 if (MPLIST_MTEXT_P (plist))
3841 MText *mt = MPLIST_MTEXT (plist);
3842 int c = mtext_ref_char (mt, 0);
3846 this_key = one_char_symbol[c];
3850 MPlist *pl = MPLIST_PLIST (plist);
3852 this_key = MPLIST_SYMBOL (pl);
3856 && (alias = msymbol_get (alias, M_key_alias))
3857 && alias != this_key);
3861 if (MPLIST_TAIL_P (plist))
3864 MDEBUG_PRINT ("\n [IM] reload");
3870 /** Handle the input key KEY in the current state and map of IC->info.
3871 If KEY is handled but no text is produced, return 0, otherwise
3877 filter (MInputContext *ic, MSymbol key, void *arg)
3879 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3880 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3883 if (check_reload (ic, key))
3886 if (! ic_info->state)
3888 ic_info->key_unhandled = 1;
3891 mtext_reset (ic->produced);
3892 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3893 M17N_OBJECT_UNREF (ic_info->preceding_text);
3894 M17N_OBJECT_UNREF (ic_info->following_text);
3895 ic_info->preceding_text = ic_info->following_text = NULL;
3896 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3897 ic_info->key_unhandled = 0;
3900 if (handle_key (ic) < 0)
3902 /* KEY was not handled. Delete it from the current key sequence. */
3903 if (ic_info->used > 0)
3905 memmove (ic_info->keys, ic_info->keys + 1,
3906 sizeof (int) * (ic_info->used - 1));
3908 if (ic_info->state_key_head > 0)
3909 ic_info->state_key_head--;
3910 if (ic_info->commit_key_head > 0)
3911 ic_info->commit_key_head--;
3913 /* This forces returning 1. */
3914 ic_info->key_unhandled = 1;
3920 reset_ic (ic, Mnil);
3921 ic_info->key_unhandled = 1;
3924 /* Break the loop if all keys were handled. */
3925 } while (ic_info->key_head < ic_info->used);
3927 /* If the current map is the root of the initial state, we should
3928 produce any preedit text in ic->produced. */
3929 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3930 preedit_commit (ic, 1);
3932 if (mtext_nchars (ic->produced) > 0)
3936 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3937 MSYMBOL_NAME (ic_info->state->name));
3938 for (i = 0; i < mtext_nchars (ic->produced); i++)
3939 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3943 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3944 Mlanguage, ic->im->language);
3946 if (ic_info->commit_key_head > 0)
3948 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3949 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3950 ic_info->used -= ic_info->commit_key_head;
3951 ic_info->key_head -= ic_info->commit_key_head;
3952 ic_info->state_key_head -= ic_info->commit_key_head;
3953 ic_info->commit_key_head = 0;
3955 if (ic_info->key_unhandled)
3958 ic_info->key_head = ic_info->state_key_head
3959 = ic_info->commit_key_head = 0;
3962 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3966 /** Return 1 if the last event or key was not handled, otherwise
3969 There is no need of looking up because ic->produced should already
3970 contain the produced text (if any).
3975 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3977 mtext_cat (mt, ic->produced);
3978 mtext_reset (ic->produced);
3979 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3983 /* Input method command handler. */
3985 /* List of all (global and local) commands.
3986 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3987 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3988 Global commands are stored as (t (t COMMAND ...)) */
3991 /* Input method variable handler. */
3994 /* Support functions for mdebug_dump_im. */
3997 dump_im_map (MPlist *map_list, int indent)
4000 MSymbol key = MPLIST_KEY (map_list);
4001 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
4003 prefix = (char *) alloca (indent + 1);
4004 memset (prefix, 32, indent);
4005 prefix[indent] = '\0';
4007 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
4008 if (map->map_actions)
4009 mdebug_dump_plist (map->map_actions, indent + 2);
4012 MPLIST_DO (map_list, map->submaps)
4014 fprintf (stderr, "\n%s ", prefix);
4015 dump_im_map (map_list, indent + 2);
4018 if (map->branch_actions)
4020 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
4021 mdebug_dump_plist (map->branch_actions, indent + 4);
4022 fprintf (stderr, ")");
4024 fprintf (stderr, ")");
4029 dump_im_state (MIMState *state, int indent)
4034 prefix = (char *) alloca (indent + 1);
4035 memset (prefix, 32, indent);
4036 prefix[indent] = '\0';
4038 fprintf (stderr, "(%s", msymbol_name (state->name));
4039 if (state->map->submaps)
4041 MPLIST_DO (map_list, state->map->submaps)
4043 fprintf (stderr, "\n%s ", prefix);
4044 dump_im_map (map_list, indent + 2);
4047 fprintf (stderr, ")");
4055 Minput_driver = msymbol ("input-driver");
4057 Minput_preedit_start = msymbol ("input-preedit-start");
4058 Minput_preedit_done = msymbol ("input-preedit-done");
4059 Minput_preedit_draw = msymbol ("input-preedit-draw");
4060 Minput_status_start = msymbol ("input-status-start");
4061 Minput_status_done = msymbol ("input-status-done");
4062 Minput_status_draw = msymbol ("input-status-draw");
4063 Minput_candidates_start = msymbol ("input-candidates-start");
4064 Minput_candidates_done = msymbol ("input-candidates-done");
4065 Minput_candidates_draw = msymbol ("input-candidates-draw");
4066 Minput_set_spot = msymbol ("input-set-spot");
4067 Minput_focus_move = msymbol ("input-focus-move");
4068 Minput_focus_in = msymbol ("input-focus-in");
4069 Minput_focus_out = msymbol ("input-focus-out");
4070 Minput_toggle = msymbol ("input-toggle");
4071 Minput_reset = msymbol ("input-reset");
4072 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4073 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4074 Mcustomized = msymbol ("customized");
4075 Mconfigured = msymbol ("configured");
4076 Minherited = msymbol ("inherited");
4078 minput_default_driver.open_im = open_im;
4079 minput_default_driver.close_im = close_im;
4080 minput_default_driver.create_ic = create_ic;
4081 minput_default_driver.destroy_ic = destroy_ic;
4082 minput_default_driver.filter = filter;
4083 minput_default_driver.lookup = lookup;
4084 minput_default_driver.callback_list = mplist ();
4085 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4086 M17N_FUNC (reset_ic));
4087 minput_driver = &minput_default_driver;
4089 fully_initialized = 0;
4096 if (fully_initialized)
4098 free_im_list (im_info_list);
4100 free_im_list (im_custom_list);
4102 free_im_list (im_config_list);
4103 M17N_OBJECT_UNREF (load_im_info_keys);
4106 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4107 M17N_OBJECT_UNREF (minput_driver->callback_list);
4112 minput__char_to_key (int c)
4114 if (c < 0 || c >= 0x100)
4117 return one_char_symbol[c];
4121 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4126 /*** @addtogroup m17nInputMethod */
4131 @brief Symbol whose name is "input-method".
4134 @brief "input-method" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
4136 MSymbol Minput_method;
4139 @name Variables: Predefined symbols for callback commands. */
4141 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4144 These are the predefined symbols that are used as the @c COMMAND
4145 argument of callback functions of an input method driver (see
4146 #MInputDriver::callback_list).
4148 Most of them do not require extra argument nor return any value;
4149 exceptions are these:
4151 @b Minput_get_surrounding_text: When a callback function assigned for
4152 this command is called, the first element of #MInputContext::plist
4153 has key #Minteger and the value specifies which portion of the
4154 surrounding text should be retrieved. If the value is positive,
4155 it specifies the number of characters following the current cursor
4156 position. If the value is negative, the absolute value specifies
4157 the number of characters preceding the current cursor position.
4158 If the value is zero, it means that the caller just wants to know
4159 if the surrounding text is currently supported or not.
4161 If the surrounding text is currently supported, the callback
4162 function must set the key of this element to #Mtext and the value
4163 to the retrieved M-text. The length of the M-text may be shorter
4164 than the requested number of characters, if the available text is
4165 not that long. The length can be zero in the worst case. Or, the
4166 length may be longer if an application thinks it is more efficient
4167 to return that length.
4169 If the surrounding text is not currently supported, the callback
4170 function should return without changing the first element of
4171 #MInputContext::plist.
4173 @b Minput_delete_surrounding_text: When a callback function assigned
4174 for this command is called, the first element of
4175 #MInputContext::plist has key #Minteger and the value specifies
4176 which portion of the surrounding text should be deleted in the
4177 same way as the case of Minput_get_surrounding_text. The callback
4178 function must delete the specified text. It should not alter
4179 #MInputContext::plist. */
4181 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4182 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4184 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4186 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4187 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4188 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4189 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4190 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4191 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4192 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4194 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4195 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4196 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4197 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4198 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4200 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4201 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4203 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4204 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4205 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4206 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4207 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4208 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4209 MSymbol Minput_preedit_start;
4210 MSymbol Minput_preedit_done;
4211 MSymbol Minput_preedit_draw;
4212 MSymbol Minput_status_start;
4213 MSymbol Minput_status_done;
4214 MSymbol Minput_status_draw;
4215 MSymbol Minput_candidates_start;
4216 MSymbol Minput_candidates_done;
4217 MSymbol Minput_candidates_draw;
4218 MSymbol Minput_set_spot;
4219 MSymbol Minput_toggle;
4220 MSymbol Minput_reset;
4221 MSymbol Minput_get_surrounding_text;
4222 MSymbol Minput_delete_surrounding_text;
4228 @name Variables: Predefined symbols for special input events.
4230 These are the predefined symbols that are used as the @c KEY
4231 argument of minput_filter (). */
4233 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4235 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4240 MSymbol Minput_focus_out;
4241 MSymbol Minput_focus_in;
4242 MSymbol Minput_focus_move;
4248 @name Variables: Predefined symbols used in input method information. */
4250 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4254 These are the predefined symbols describing status of input method
4255 command and variable, and are used in a return value of
4256 minput_get_command () and minput_get_variable (). */
4258 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4259 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4261 MSymbol Mcustomized;
4262 MSymbol Mconfigured;
4268 @brief The default driver for internal input methods.
4270 The variable #minput_default_driver is the default driver for
4271 internal input methods.
4273 The member MInputDriver::open_im () searches the m17n database for
4274 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4275 $NAME\> and loads it.
4277 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4278 programmers responsibility to set it to a plist of proper callback
4279 functions. Otherwise, no feedback information (e.g. preedit text)
4280 can be shown to users.
4282 The macro M17N_INIT () sets the variable #minput_driver to the
4283 pointer to this driver so that all internal input methods use it.
4285 Therefore, unless @c minput_driver is set differently, the driver
4286 dependent arguments $ARG of the functions whose name begins with
4287 "minput_" are all ignored. */
4289 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4291 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4293 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4294 \< #Minput_method, $LANGUAGE, $NAME\>
4295 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4297 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4298 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4299 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4300 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4302 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4303 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4305 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4306 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4308 MInputDriver minput_default_driver;
4312 @brief The driver for internal input methods.
4314 The variable #minput_driver is a pointer to the input method
4315 driver that is used by internal input methods. The macro
4316 M17N_INIT () initializes it to a pointer to #minput_default_driver
4317 if <m17n<EM></EM>.h> is included. */
4319 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4321 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4322 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4323 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4324 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4326 MInputDriver *minput_driver;
4330 The variable #Minput_driver is a symbol for a foreign input method.
4331 See @ref foreign-input-method "foreign input method" for the detail. */
4332 MSymbol Minput_driver;
4347 @brief Open an input method.
4349 The minput_open_im () function opens an input method whose
4350 language and name match $LANGUAGE and $NAME, and returns a pointer
4351 to the input method object newly allocated.
4353 This function at first decides a driver for the input method as
4356 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4357 #minput_driver is used.
4359 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4360 driver pointed to by the property value is used to open the input
4361 method. If $NAME has no such a property, @c NULL is returned.
4363 Then, the member MInputDriver::open_im () of the driver is
4366 $ARG is set in the member @c arg of the structure MInputMethod so
4367 that the driver can refer to it. */
4369 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4371 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4372 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4374 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4376 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4377 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4379 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4380 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4381 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4383 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4385 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4387 @latexonly \IPAlabel{minput_open} @endlatexonly
4392 minput_open_im (MSymbol language, MSymbol name, void *arg)
4395 MInputDriver *driver;
4399 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4400 msymbol_name (language), msymbol_name (name));
4404 MERROR (MERROR_IM, NULL);
4405 driver = minput_driver;
4409 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4411 MERROR (MERROR_IM, NULL);
4414 MSTRUCT_CALLOC (im, MERROR_IM);
4415 im->language = language;
4418 im->driver = *driver;
4419 if ((*im->driver.open_im) (im) < 0)
4421 MDEBUG_PRINT (" failed\n");
4425 MDEBUG_PRINT (" ok\n");
4432 @brief Close an input method.
4434 The minput_close_im () function closes the input method $IM, which
4435 must have been created by minput_open_im (). */
4438 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4440 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4441 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4444 minput_close_im (MInputMethod *im)
4446 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4447 msymbol_name (im->name), msymbol_name (im->language));
4448 (*im->driver.close_im) (im);
4450 MDEBUG_PRINT (" done\n");
4456 @brief Create an input context.
4458 The minput_create_ic () function creates an input context object
4459 associated with input method $IM, and calls callback functions
4460 corresponding to @b Minput_preedit_start, @b Minput_status_start, and
4461 @b Minput_status_draw in this order.
4464 If an input context is successfully created, minput_create_ic ()
4465 returns a pointer to it. Otherwise it returns @c NULL. */
4468 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4470 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4471 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4472 @b Minput_preedit_start, @b Minput_status_start, @b Minput_status_draw
4473 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4476 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4477 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4481 minput_create_ic (MInputMethod *im, void *arg)
4485 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4486 msymbol_name (im->name), msymbol_name (im->language));
4487 MSTRUCT_CALLOC (ic, MERROR_IM);
4490 ic->preedit = mtext ();
4491 ic->candidate_list = NULL;
4492 ic->produced = mtext ();
4493 ic->spot.x = ic->spot.y = 0;
4495 ic->plist = mplist ();
4496 if ((*im->driver.create_ic) (ic) < 0)
4498 MDEBUG_PRINT (" failed\n");
4499 M17N_OBJECT_UNREF (ic->preedit);
4500 M17N_OBJECT_UNREF (ic->produced);
4501 M17N_OBJECT_UNREF (ic->plist);
4506 if (im->driver.callback_list)
4508 minput_callback (ic, Minput_preedit_start);
4509 minput_callback (ic, Minput_status_start);
4510 minput_callback (ic, Minput_status_draw);
4513 MDEBUG_PRINT (" ok\n");
4520 @brief Destroy an input context.
4522 The minput_destroy_ic () function destroys the input context $IC,
4523 which must have been created by minput_create_ic (). It calls
4524 callback functions corresponding to @b Minput_preedit_done,
4525 @b Minput_status_done, and @b Minput_candidates_done in this order. */
4528 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4530 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4531 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4532 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4533 @b Minput_preedit_done, @b Minput_status_done, @b Minput_candidates_done
4534 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4538 minput_destroy_ic (MInputContext *ic)
4540 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4541 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4542 if (ic->im->driver.callback_list)
4544 minput_callback (ic, Minput_preedit_done);
4545 minput_callback (ic, Minput_status_done);
4546 minput_callback (ic, Minput_candidates_done);
4548 (*ic->im->driver.destroy_ic) (ic);
4549 M17N_OBJECT_UNREF (ic->preedit);
4550 M17N_OBJECT_UNREF (ic->produced);
4551 M17N_OBJECT_UNREF (ic->plist);
4552 MDEBUG_PRINT (" done\n");
4559 @brief Filter an input key.
4561 The minput_filter () function filters input key $KEY according to
4562 input context $IC, and calls callback functions corresponding to
4563 @b Minput_preedit_draw, @b Minput_status_draw, and
4564 @b Minput_candidates_draw if the preedit text, the status, and the
4565 current candidate are changed respectively.
4567 To make the input method commit the current preedit text (if any)
4568 and shift to the initial state, call this function with #Mnil as
4571 To inform the input method about the focus-out event, call this
4572 function with @b Minput_focus_out as $KEY.
4574 To inform the input method about the focus-in event, call this
4575 function with @b Minput_focus_in as $KEY.
4577 To inform the input method about the focus-move event (i.e. input
4578 spot change within the same input context), call this function
4579 with @b Minput_focus_move as $KEY.
4582 If $KEY is filtered out, this function returns 1. In that case,
4583 the caller should discard the key. Otherwise, it returns 0, and
4584 the caller should handle the key, for instance, by calling the
4585 function minput_lookup () with the same key. */
4588 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4590 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4591 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4592 @b Minput_preedit_draw, @b Minput_status_draw,
4593 @b Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4596 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4597 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4598 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4599 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4601 @latexonly \IPAlabel{minput_filter} @endlatexonly
4605 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4612 if (ic->im->driver.callback_list
4613 && mtext_nchars (ic->preedit) > 0)
4614 minput_callback (ic, Minput_preedit_draw);
4616 ret = (*ic->im->driver.filter) (ic, key, arg);
4618 if (ic->im->driver.callback_list)
4620 if (ic->preedit_changed)
4621 minput_callback (ic, Minput_preedit_draw);
4622 if (ic->status_changed)
4623 minput_callback (ic, Minput_status_draw);
4624 if (ic->candidates_changed)
4625 minput_callback (ic, Minput_candidates_draw);
4634 @brief Look up a text produced in the input context.
4636 The minput_lookup () function looks up a text in the input context
4637 $IC. $KEY must be identical to the one that was used in the previous call of
4640 If a text was produced by the input method, it is concatenated
4643 This function calls #MInputDriver::lookup .
4646 If $KEY was correctly handled by the input method, this function
4647 returns 0. Otherwise, it returns -1, even though some text
4648 might be produced in $MT. */
4651 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4653 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4654 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4656 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4659 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4662 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4663 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4664 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4666 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4669 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4671 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4676 @brief Set the spot of the input context.
4678 The minput_set_spot () function sets the spot of input context $IC
4679 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4680 The semantics of these values depends on the input method driver.
4682 For instance, a driver designed to work in a CUI environment may
4683 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4684 $DESCENT . A driver designed to work in a window system may
4685 interpret $X and $Y as the pixel offsets relative to the origin of the
4686 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4687 descent pixels of the line at ($X . $Y ).
4689 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4691 $MT and $POS are the M-text and the character position at the spot.
4692 $MT may be @c NULL, in which case, the input method cannot get
4693 information about the text around the spot. */
4696 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4698 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4699 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4700 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4702 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4703 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4704 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4705 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4706 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4707 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4709 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4711 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4712 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4716 minput_set_spot (MInputContext *ic, int x, int y,
4717 int ascent, int descent, int fontsize,
4722 ic->spot.ascent = ascent;
4723 ic->spot.descent = descent;
4724 ic->spot.fontsize = fontsize;
4727 if (ic->im->driver.callback_list)
4728 minput_callback (ic, Minput_set_spot);
4733 @brief Toggle input method.
4735 The minput_toggle () function toggles the input method associated
4736 with input context $IC. */
4738 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4740 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4741 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4745 minput_toggle (MInputContext *ic)
4747 if (ic->im->driver.callback_list)
4748 minput_callback (ic, Minput_toggle);
4749 ic->active = ! ic->active;
4755 @brief Reset an input context.
4757 The minput_reset_ic () function resets input context $IC by
4758 calling a callback function corresponding to @b Minput_reset. It
4759 resets the status of $IC to its initial one. As the
4760 current preedit text is deleted without commitment, if necessary,
4761 call minput_filter () with the arg @b key #Mnil to force the input
4762 method to commit the preedit in advance. */
4765 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4767 ´Ø¿ô minput_reset_ic () ¤Ï @b Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4768 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4769 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4770 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4771 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @b key #Mnil ¤Ç¸Æ¤ó¤Ç
4772 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4775 minput_reset_ic (MInputContext *ic)
4777 if (ic->im->driver.callback_list)
4778 minput_callback (ic, Minput_reset);
4784 @brief Get title and icon filename of an input method.
4786 The minput_get_title_icon () function returns a plist containing a
4787 title and icon filename (if any) of an input method specified by
4788 $LANGUAGE and $NAME.
4790 The first element of the plist has key #Mtext and the value is an
4791 M-text of the title for identifying the input method. The second
4792 element (if any) has key #Mtext and the value is an M-text of the
4793 icon image (absolute) filename for the same purpose.
4796 If there exists a specified input method and it defines an title,
4797 a plist is returned. Otherwise, NULL is returned. The caller
4798 must free the plist by m17n_object_unref (). */
4800 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4802 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4803 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4806 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4807 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4808 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4811 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4812 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4813 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4816 minput_get_title_icon (MSymbol language, MSymbol name)
4818 MInputMethodInfo *im_info;
4825 im_info = get_im_info (language, name, Mnil, Mtitle);
4826 if (! im_info || !im_info->title)
4828 mt = mtext_get_prop (im_info->title, 0, Mtext);
4830 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4833 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4836 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4837 (char *) MSYMBOL_NAME (name));
4838 file = mdatabase__find_file (buf);
4839 if (! file && language == Mt)
4841 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4842 file = mdatabase__find_file (buf);
4847 mplist_add (plist, Mtext, im_info->title);
4850 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4852 mplist_add (plist, Mtext, mt);
4853 M17N_OBJECT_UNREF (mt);
4861 @brief Get description text of an input method.
4863 The minput_get_description () function returns an M-text that
4864 describes the input method specified by $LANGUAGE and $NAME.
4867 If the specified input method has a description text, a pointer to
4868 #MText is returned. The caller has to free it by m17n_object_unref ().
4869 If the input method does not have a description text, @c NULL is
4872 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4874 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4875 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4878 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4879 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4880 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4881 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4884 minput_get_description (MSymbol language, MSymbol name)
4886 MInputMethodInfo *im_info;
4894 extra = language, language = Mt;
4896 im_info = get_im_info (language, name, extra, Mdescription);
4897 if (! im_info || ! im_info->description)
4899 M17N_OBJECT_REF (im_info->description);
4900 return im_info->description;
4906 @brief Get information about input method command(s).
4908 The minput_get_command () function returns information about
4909 the command $COMMAND of the input method specified by $LANGUAGE and
4910 $NAME. An input method command is a pseudo key event to which one
4911 or more actual input key sequences are assigned.
4913 There are two kinds of commands, global and local. A global
4914 command has a global definition, and the description and the key
4915 assignment may be inherited by a local command. Each input method
4916 defines a local command which has a local key assignment. It may
4917 also declare a local command that inherits the definition of a
4918 global command of the same name.
4920 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4921 information about a global command. Otherwise information about a
4922 local command is returned.
4924 If $COMMAND is #Mnil, information about all commands is returned.
4926 The return value is a @e well-formed plist (@ref m17nPlist) of this
4929 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4931 @c NAME is a symbol representing the command name.
4933 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4934 command has no description.
4936 @c STATUS is a symbol representing how the key assignment is decided.
4937 The value is #Mnil (the default key assignment), @b Mcustomized (the
4938 key assignment is customized by per-user customization file), or
4939 @b Mconfigured (the key assignment is set by the call of
4940 minput_config_command ()). For a local command only, it may also
4941 be @b Minherited (the key assignment is inherited from the
4942 corresponding global command).
4944 @c KEYSEQ is a plist of one or more symbols representing a key
4945 sequence assigned to the command. If there's no KEYSEQ, the
4946 command is currently disabled (i.e. no key sequence can trigger
4947 actions of the command).
4949 If $COMMAND is not #Mnil, the first element of the returned plist
4950 contains the information about $COMMAND.
4954 If the requested information was found, a pointer to a non-empty
4955 plist is returned. As the plist is kept in the library, the
4956 caller must not modify nor free it.
4958 Otherwise (the specified input method or the specified command
4959 does not exist), @c NULL is returned. */
4961 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4963 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4964 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4965 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4966 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4968 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4969 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4970 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4971 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4972 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4974 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4975 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4978 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4980 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4983 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4985 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4987 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4990 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4991 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, @b Mcustomized ¡Ê¥æ¡¼
4992 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4993 @b Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4994 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4995 @b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4998 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4999 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
5000 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
5001 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
5003 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
5004 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5008 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5009 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5012 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5017 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
5019 /* Return a description of the command COMMAND of the input method
5020 specified by LANGUAGE and NAME. */
5021 MPlist *cmd = minput_get_command (langauge, name, command);
5026 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
5027 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
5028 return (mplist_key (plist) == Mtext
5029 ? (MText *) mplist_value (plist)
5035 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5037 MInputMethodInfo *im_info;
5041 im_info = get_im_info (language, name, Mnil, Mcommand);
5043 || ! im_info->configured_cmds
5044 || MPLIST_TAIL_P (im_info->configured_cmds))
5046 if (command == Mnil)
5047 return im_info->configured_cmds;
5048 return mplist__assq (im_info->configured_cmds, command);
5054 @brief Configure the key sequence of an input method command.
5056 The minput_config_command () function assigns a list of key
5057 sequences $KEYSEQLIST to the command $COMMAND of the input method
5058 specified by $LANGUAGE and $NAME.
5060 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5061 sequences, and each key sequence must be a plist of symbols.
5063 If $KEYSEQLIST is an empty plist, any configuration and
5064 customization of the command are cancelled, and default key
5065 sequences become effective.
5067 If $KEYSEQLIST is NULL, the configuration of the command is
5068 canceled, and the original key sequences (what saved in per-user
5069 customization file, or the default one) become effective.
5071 In the latter two cases, $COMMAND can be #Mnil to make all the
5072 commands of the input method the target of the operation.
5074 If $NAME is #Mnil, this function configures the key assignment of a
5075 global command, not that of a specific input method.
5077 The configuration takes effect for input methods opened or
5078 re-opened later in the current session. In order to make the
5079 configuration take effect for the future session, it must be saved
5080 in a per-user customization file by the function
5081 minput_save_config ().
5084 If the operation was successful, this function returns 0,
5085 otherwise returns -1. The operation fails in these cases:
5087 <li>$KEYSEQLIST is not in a valid form.
5088 <li>$COMMAND is not available for the input method.
5089 <li>$LANGUAGE and $NAME do not specify an existing input method.
5093 minput_get_commands (), minput_save_config ().
5096 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5098 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5099 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5100 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5102 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5103 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5105 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5106 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5108 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5109 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5110 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5112 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5113 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5115 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5116 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5118 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5119 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5120 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5121 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5125 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5127 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5128 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5129 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5133 minput_get_commands (), minput_save_config ().
5137 /* Add "C-x u" to the "start" command of Unicode input method. */
5139 MSymbol start_command = msymbol ("start");
5140 MSymbol unicode = msymbol ("unicode");
5141 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5143 /* At first get the current key-sequence assignment. */
5144 cmd = minput_get_command (Mt, unicode, start_command);
5147 /* The input method does not have the command "start". Here
5148 should come some error handling code. */
5150 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5151 Extract the part (KEY-SEQUENCE ...). */
5152 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5153 /* Copy it because we should not modify it directly. */
5154 key_seq_list = mplist_copy (plist);
5156 key_seq = mplist ();
5157 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5158 mplist_add (key_seq, Msymbol, msymbol ("u"));
5159 mplist_add (key_seq_list, Mplist, key_seq);
5160 m17n_object_unref (key_seq);
5162 minput_config_command (Mt, unicode, start_command, key_seq_list);
5163 m17n_object_unref (key_seq_list);
5168 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5171 MInputMethodInfo *im_info, *config;
5176 im_info = get_im_info (language, name, Mnil, Mcommand);
5178 MERROR (MERROR_IM, -1);
5179 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5181 || ! mplist__assq (im_info->configured_cmds, command)))
5182 MERROR (MERROR_IM, -1);
5183 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5185 MPLIST_DO (plist, keyseqlist)
5186 if (! check_command_keyseq (plist))
5187 MERROR (MERROR_IM, -1);
5190 config = get_config_info (im_info);
5193 if (! im_config_list)
5194 im_config_list = mplist ();
5195 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5196 config->cmds = mplist ();
5197 config->vars = mplist ();
5200 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5201 /* Nothing to do. */
5204 if (command == Mnil)
5208 /* Cancal the configuration. */
5209 if (MPLIST_TAIL_P (config->cmds))
5211 mplist_set (config->cmds, Mnil, NULL);
5215 /* Cancal the customization. */
5216 MInputMethodInfo *custom = get_custom_info (im_info);
5218 if (MPLIST_TAIL_P (config->cmds)
5219 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5220 /* Nothing to do. */
5222 mplist_set (config->cmds, Mnil, NULL);
5223 MPLIST_DO (plist, custom->cmds)
5225 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5227 mplist_add (plist, Msymbol, command);
5228 mplist_push (config->cmds, Mplist, plist);
5229 M17N_OBJECT_UNREF (plist);
5235 plist = mplist__assq (config->cmds, command);
5238 /* Cancel the configuration. */
5241 mplist__pop_unref (plist);
5243 else if (MPLIST_TAIL_P (keyseqlist))
5245 /* Cancel the customization. */
5246 MInputMethodInfo *custom = get_custom_info (im_info);
5247 int no_custom = (! custom || ! custom->cmds
5248 || ! mplist__assq (custom->cmds, command));
5254 mplist_add (config->cmds, Mplist, plist);
5255 M17N_OBJECT_UNREF (plist);
5256 plist = mplist_add (plist, Msymbol, command);
5261 mplist__pop_unref (plist);
5264 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5265 plist = MPLIST_NEXT (plist);
5266 mplist_set (plist, Mnil, NULL);
5276 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5277 if (! MPLIST_TAIL_P (plist))
5278 mplist_set (plist, Mnil, NULL);
5283 mplist_add (config->cmds, Mplist, plist);
5284 M17N_OBJECT_UNREF (plist);
5285 plist = mplist_add (plist, Msymbol, command);
5286 plist = MPLIST_NEXT (plist);
5288 MPLIST_DO (keyseqlist, keyseqlist)
5290 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5291 plist = mplist_add (plist, Mplist, pl);
5292 M17N_OBJECT_UNREF (pl);
5296 config_all_commands (im_info);
5297 im_info->tick = time (NULL);
5304 @brief Get information about input method variable(s).
5306 The minput_get_variable () function returns information about
5307 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5308 An input method variable controls behavior of an input method.
5310 There are two kinds of variables, global and local. A global
5311 variable has a global definition, and the description and the value
5312 may be inherited by a local variable. Each input method defines a
5313 local variable which has local value. It may also declare a
5314 local variable that inherits definition of a global variable of
5317 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5318 variable is returned. Otherwise information about a local variable
5321 If $VARIABLE is #Mnil, information about all variables is
5324 The return value is a @e well-formed plist (@ref m17nPlist) of this
5327 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5329 @c NAME is a symbol representing the variable name.
5331 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5332 variable has no description.
5334 @c STATUS is a symbol representing how the value is decided. The
5335 value is #Mnil (the default value), @b Mcustomized (the value is
5336 customized by per-user customization file), or @b Mconfigured (the
5337 value is set by the call of minput_config_variable ()). For a
5338 local variable only, it may also be @b Minherited (the value is
5339 inherited from the corresponding global variable).
5341 @c VALUE is the initial value of the variable. If the key of this
5342 element is #Mt, the variable has no initial value. Otherwise, the
5343 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5346 @c VALID-VALUEs (if any) specify which values the variable can have.
5347 They have the same type (i.e. having the same key) as @c VALUE except
5348 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5349 may be a plist of two integers specifying the range of possible
5352 If there no @c VALID-VALUE, the variable can have any value as long
5353 as the type is the same as @c VALUE.
5355 If $VARIABLE is not #Mnil, the first element of the returned plist
5356 contains the information about $VARIABLE.
5360 If the requested information was found, a pointer to a non-empty
5361 plist is returned. As the plist is kept in the library, the
5362 caller must not modify nor free it.
5364 Otherwise (the specified input method or the specified variable
5365 does not exist), @c NULL is returned. */
5367 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5369 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5370 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5371 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5373 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5374 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5375 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5376 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5379 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5380 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5382 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5384 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5386 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5389 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5391 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5394 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5395 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, @b Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5396 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, @b Mconfigured
5397 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5398 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢@b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5399 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5401 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5402 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5403 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5405 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5406 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5407 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5408 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5410 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5413 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5414 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5418 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5419 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5422 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5426 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5428 MInputMethodInfo *im_info;
5432 im_info = get_im_info (language, name, Mnil, Mvariable);
5433 if (! im_info || ! im_info->configured_vars)
5435 if (variable == Mnil)
5436 return im_info->configured_vars;
5437 return mplist__assq (im_info->configured_vars, variable);
5443 @brief Configure the value of an input method variable.
5445 The minput_config_variable () function assigns $VALUE to the
5446 variable $VARIABLE of the input method specified by $LANGUAGE and
5449 If $VALUE is a non-empty plist, it must be a plist of one element
5450 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5451 the corresponding type. That value is assigned to the variable.
5453 If $VALUE is an empty plist, any configuration and customization
5454 of the variable are canceled, and the default value is assigned to
5457 If $VALUE is NULL, the configuration of the variable is canceled,
5458 and the original value (what saved in per-user customization file,
5459 or the default value) is assigned to the variable.
5461 In the latter two cases, $VARIABLE can be #Mnil to make all the
5462 variables of the input method the target of the operation.
5464 If $NAME is #Mnil, this function configures the value of global
5465 variable, not that of a specific input method.
5467 The configuration takes effect for input methods opened or
5468 re-opened later in the current session. To make the configuration
5469 take effect for the future session, it must be saved in a per-user
5470 customization file by the function minput_save_config ().
5474 If the operation was successful, this function returns 0,
5475 otherwise returns -1. The operation fails in these cases:
5477 <li>$VALUE is not in a valid form, the type does not match the
5478 definition, or the value is our of range.
5479 <li>$VARIABLE is not available for the input method.
5480 <li>$LANGUAGE and $NAME do not specify an existing input method.
5484 minput_get_variable (), minput_save_config (). */
5486 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5488 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5489 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5491 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5492 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5493 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5495 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5496 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5498 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5499 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5501 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5502 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5504 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5505 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5507 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5508 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5509 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5510 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5514 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5516 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5517 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5518 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5522 minput_get_commands (), minput_save_config ().
5525 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5528 MInputMethodInfo *im_info, *config;
5533 im_info = get_im_info (language, name, Mnil, Mvariable);
5535 MERROR (MERROR_IM, -1);
5536 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5538 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5539 MERROR (MERROR_IM, -1);
5541 if (value && ! MPLIST_TAIL_P (value))
5543 plist = MPLIST_PLIST (plist);
5544 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5545 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5546 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5547 if (MPLIST_KEY (plist) != Mt
5548 && ! check_variable_value (value, plist))
5549 MERROR (MERROR_IM, -1);
5552 config = get_config_info (im_info);
5555 if (! im_config_list)
5556 im_config_list = mplist ();
5557 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5558 config->cmds = mplist ();
5559 config->vars = mplist ();
5562 if (! value && MPLIST_TAIL_P (config->vars))
5563 /* Nothing to do. */
5566 if (variable == Mnil)
5570 /* Cancel the configuration. */
5571 if (MPLIST_TAIL_P (config->vars))
5573 mplist_set (config->vars, Mnil, NULL);
5577 /* Cancel the customization. */
5578 MInputMethodInfo *custom = get_custom_info (im_info);
5580 if (MPLIST_TAIL_P (config->vars)
5581 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5582 /* Nothing to do. */
5584 mplist_set (config->vars, Mnil, NULL);
5585 MPLIST_DO (plist, custom->vars)
5587 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5589 mplist_add (plist, Msymbol, variable);
5590 mplist_push (config->vars, Mplist, plist);
5591 M17N_OBJECT_UNREF (plist);
5597 plist = mplist__assq (config->vars, variable);
5600 /* Cancel the configuration. */
5603 mplist__pop_unref (plist);
5605 else if (MPLIST_TAIL_P (value))
5607 /* Cancel the customization. */
5608 MInputMethodInfo *custom = get_custom_info (im_info);
5609 int no_custom = (! custom || ! custom->vars
5610 || ! mplist__assq (custom->vars, variable));
5616 mplist_add (config->vars, Mplist, plist);
5617 M17N_OBJECT_UNREF (plist);
5618 plist = mplist_add (plist, Msymbol, variable);
5623 mplist__pop_unref (plist);
5626 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5627 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5628 mplist_set (plist, Mnil ,NULL);
5636 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5637 if (! MPLIST_TAIL_P (plist))
5638 mplist_set (plist, Mnil, NULL);
5643 mplist_add (config->vars, Mplist, plist);
5644 M17N_OBJECT_UNREF (plist);
5645 plist = mplist_add (plist, Msymbol, variable);
5646 plist = MPLIST_NEXT (plist);
5648 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5651 config_all_variables (im_info);
5652 im_info->tick = time (NULL);
5659 @brief Get the name of per-user customization file.
5661 The minput_config_file () function returns the absolute path name
5662 of per-user customization file into which minput_save_config ()
5663 save configurations. It is usually @c config.mic under the
5664 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5665 directory). It is not assured that the file of the returned name
5666 exists nor is readable/writable. If minput_save_config () fails
5667 and returns -1, an application program might check the file, make
5668 it writable (if possible), and try minput_save_config () again.
5672 This function returns a string. As the string is kept in the
5673 library, the caller must not modify nor free it.
5676 minput_save_config ()
5679 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5681 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5682 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5683 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5684 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5685 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5686 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5687 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5692 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5693 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5696 minput_save_config ()
5700 minput_config_file ()
5704 return mdatabase__file (im_custom_mdb);
5710 @brief Save configurations in per-user customization file.
5712 The minput_save_config () function saves the configurations done
5713 so far in the current session into the per-user customization
5718 If the operation was successful, 1 is returned. If the per-user
5719 customization file is currently locked, 0 is returned. In that
5720 case, the caller may wait for a while and try again. If the
5721 configuration file is not writable, -1 is returned. In that case,
5722 the caller may check the name of the file by calling
5723 minput_config_file (), make it writable if possible, and try
5727 minput_config_file () */
5729 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5731 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5732 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5736 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5737 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5738 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5739 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5743 minput_config_file () */
5746 minput_save_config (void)
5748 MPlist *data, *tail, *plist, *p, *elt;
5752 ret = mdatabase__lock (im_custom_mdb);
5755 if (! im_config_list)
5757 update_custom_info ();
5758 if (! im_custom_list)
5759 im_custom_list = mplist ();
5761 /* At first, reflect configuration in customization. */
5762 MPLIST_DO (plist, im_config_list)
5764 MPlist *pl = MPLIST_PLIST (plist);
5765 MSymbol language, name, extra, command, variable;
5766 MInputMethodInfo *custom, *config;
5768 language = MPLIST_SYMBOL (pl);
5769 pl = MPLIST_NEXT (pl);
5770 name = MPLIST_SYMBOL (pl);
5771 pl = MPLIST_NEXT (pl);
5772 extra = MPLIST_SYMBOL (pl);
5773 pl = MPLIST_NEXT (pl);
5774 config = MPLIST_VAL (pl);
5775 custom = get_custom_info (config);
5777 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5779 MPLIST_DO (pl, config->cmds)
5781 elt = MPLIST_PLIST (pl);
5782 command = MPLIST_SYMBOL (elt);
5784 p = mplist__assq (custom->cmds, command);
5786 custom->cmds = mplist (), p = NULL;
5787 elt = MPLIST_NEXT (elt);
5790 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5791 mplist_set (p, Mnil, NULL);
5796 mplist_add (custom->cmds, Mplist, p);
5797 M17N_OBJECT_UNREF (p);
5798 mplist_add (p, Msymbol, command);
5799 p = mplist_add (p, Msymbol, Mnil);
5800 p = MPLIST_NEXT (p);
5802 mplist__conc (p, elt);
5805 MPLIST_DO (pl, config->vars)
5807 elt = MPLIST_PLIST (pl);
5808 variable = MPLIST_SYMBOL (elt);
5810 p = mplist__assq (custom->vars, variable);
5812 custom->vars = mplist (), p = NULL;
5813 elt = MPLIST_NEXT (elt);
5816 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5817 mplist_set (p, Mnil, NULL);
5822 mplist_add (custom->vars, Mplist, p);
5823 M17N_OBJECT_UNREF (p);
5824 mplist_add (p, Msymbol, variable);
5825 p = mplist_add (p, Msymbol, Mnil);
5826 p = MPLIST_NEXT (p);
5828 mplist__conc (p, elt);
5831 free_im_list (im_config_list);
5832 im_config_list = NULL;
5834 /* Next, reflect customization to the actual plist to be written. */
5835 data = tail = mplist ();
5836 MPLIST_DO (plist, im_custom_list)
5838 MPlist *pl = MPLIST_PLIST (plist);
5839 MSymbol language, name, extra;
5840 MInputMethodInfo *custom, *im_info;
5842 language = MPLIST_SYMBOL (pl);
5843 pl = MPLIST_NEXT (pl);
5844 name = MPLIST_SYMBOL (pl);
5845 pl = MPLIST_NEXT (pl);
5846 extra = MPLIST_SYMBOL (pl);
5847 pl = MPLIST_NEXT (pl);
5848 custom = MPLIST_VAL (pl);
5849 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5850 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5852 im_info = lookup_im_info (im_info_list, language, name, extra);
5856 config_all_commands (im_info);
5858 config_all_variables (im_info);
5862 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5864 MPLIST_DO (p, custom->cmds)
5865 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5867 if (! MPLIST_TAIL_P (p))
5871 mplist_add (elt, Mplist, pl);
5872 M17N_OBJECT_UNREF (pl);
5873 pl = mplist_add (pl, Msymbol, Mcommand);
5874 MPLIST_DO (p, custom->cmds)
5875 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5876 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5879 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5881 MPLIST_DO (p, custom->vars)
5882 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5884 if (! MPLIST_TAIL_P (p))
5889 mplist_add (elt, Mplist, pl);
5890 M17N_OBJECT_UNREF (pl);
5891 pl = mplist_add (pl, Msymbol, Mvariable);
5892 MPLIST_DO (p, custom->vars)
5893 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5894 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5900 mplist_push (elt, Mplist, pl);
5901 M17N_OBJECT_UNREF (pl);
5902 pl = mplist_add (pl, Msymbol, Minput_method);
5903 pl = mplist_add (pl, Msymbol, language);
5904 pl = mplist_add (pl, Msymbol, name);
5906 pl = mplist_add (pl, Msymbol, extra);
5907 tail = mplist_add (tail, Mplist, elt);
5908 M17N_OBJECT_UNREF (elt);
5912 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5913 ret = mdatabase__save (im_custom_mdb, data);
5914 mdatabase__unlock (im_custom_mdb);
5915 M17N_OBJECT_UNREF (data);
5916 return (ret < 0 ? -1 : 1);
5923 @name Obsolete functions
5926 @name Obsolete ¤Ê´Ø¿ô
5932 @brief Get a list of variables of an input method (obsolete).
5934 This function is obsolete. Use minput_get_variable () instead.
5936 The minput_get_variables () function returns a plist (#MPlist) of
5937 variables used to control the behavior of the input method
5938 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5939 (@ref m17nPlist) of the following format:
5942 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5943 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5947 @c VARNAME is a symbol representing the variable name.
5949 @c DOC-MTEXT is an M-text describing the variable.
5951 @c DEFAULT-VALUE is the default value of the variable. It is a
5952 symbol, integer, or M-text.
5954 @c VALUEs (if any) specifies the possible values of the variable.
5955 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5956 @c TO), where @c FROM and @c TO specifies a range of possible
5959 For instance, suppose an input method has the variables:
5961 @li name:intvar, description:"value is an integer",
5962 initial value:0, value-range:0..3,10,20
5964 @li name:symvar, description:"value is a symbol",
5965 initial value:nil, value-range:a, b, c, nil
5967 @li name:txtvar, description:"value is an M-text",
5968 initial value:empty text, no value-range (i.e. any text)
5970 Then, the returned plist is as follows.
5973 (intvar ("value is an integer" 0 (0 3) 10 20)
5974 symvar ("value is a symbol" nil a b c nil)
5975 txtvar ("value is an M-text" ""))
5979 If the input method uses any variables, a pointer to #MPlist is
5980 returned. As the plist is kept in the library, the caller must not
5981 modify nor free it. If the input method does not use any
5982 variable, @c NULL is returned. */
5984 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5986 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5987 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5988 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5992 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5993 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5997 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5999 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
6001 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
6004 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
6005 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
6006 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
6008 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
6010 @li name:intvar, ÀâÌÀ:"value is an integer",
6011 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
6013 @li name:symvar, ÀâÌÀ:"value is a symbol",
6014 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
6016 @li name:txtvar, ÀâÌÀ:"value is an M-text",
6017 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
6019 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
6022 (intvar ("value is an integer" 0 (0 3) 10 20)
6023 symvar ("value is a symbol" nil a b c nil)
6024 txtvar ("value is an M-text" ""))
6028 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
6029 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6030 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
6033 minput_get_variables (MSymbol language, MSymbol name)
6035 MInputMethodInfo *im_info;
6040 im_info = get_im_info (language, name, Mnil, Mvariable);
6041 if (! im_info || ! im_info->configured_vars)
6044 M17N_OBJECT_UNREF (im_info->bc_vars);
6045 im_info->bc_vars = mplist ();
6046 MPLIST_DO (vars, im_info->configured_vars)
6048 MPlist *plist = MPLIST_PLIST (vars);
6049 MPlist *elt = mplist ();
6051 mplist_push (im_info->bc_vars, Mplist, elt);
6052 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6053 elt = MPLIST_NEXT (elt);
6054 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6055 M17N_OBJECT_UNREF (elt);
6057 return im_info->bc_vars;
6063 @brief Set the initial value of an input method variable.
6065 The minput_set_variable () function sets the initial value of
6066 input method variable $VARIABLE to $VALUE for the input method
6067 specified by $LANGUAGE and $NAME.
6069 By default, the initial value is 0.
6071 This setting gets effective in a newly opened input method.
6074 If the operation was successful, 0 is returned. Otherwise -1 is
6075 returned, and #merror_code is set to @c MERROR_IM. */
6077 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6079 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6080 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6081 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6083 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6085 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6088 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6089 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6092 minput_set_variable (MSymbol language, MSymbol name,
6093 MSymbol variable, void *value)
6096 MInputMethodInfo *im_info;
6101 if (variable == Mnil)
6102 MERROR (MERROR_IM, -1);
6103 plist = minput_get_variable (language, name, variable);
6104 plist = MPLIST_PLIST (plist);
6105 plist = MPLIST_NEXT (plist);
6107 mplist_add (pl, MPLIST_KEY (plist), value);
6108 ret = minput_config_variable (language, name, variable, pl);
6109 M17N_OBJECT_UNREF (pl);
6112 im_info = get_im_info (language, name, Mnil, Mvariable);
6121 @brief Get information about input method commands.
6123 The minput_get_commands () function returns information about
6124 input method commands of the input method specified by $LANGUAGE
6125 and $NAME. An input method command is a pseudo key event to which
6126 one or more actual input key sequences are assigned.
6128 There are two kinds of commands, global and local. Global
6129 commands are used by multiple input methods for the same purpose,
6130 and have global key assignments. Local commands are used only by
6131 a specific input method, and have only local key assignments.
6133 Each input method may locally change key assignments for global
6134 commands. The global key assignment for a global command is
6135 effective only when the current input method does not have local
6136 key assignments for that command.
6138 If $NAME is #Mnil, information about global commands is returned.
6139 In this case $LANGUAGE is ignored.
6141 If $NAME is not #Mnil, information about those commands that have
6142 local key assignments in the input method specified by $LANGUAGE
6143 and $NAME is returned.
6146 If no input method commands are found, this function returns @c NULL.
6148 Otherwise, a pointer to a plist is returned. The key of each
6149 element in the plist is a symbol representing a command, and the
6150 value is a plist of the form COMMAND-INFO described below.
6152 The first element of COMMAND-INFO has the key #Mtext, and the
6153 value is an M-text describing the command.
6155 If there are no more elements, that means no key sequences are
6156 assigned to the command. Otherwise, each of the remaining
6157 elements has the key #Mplist, and the value is a plist whose keys are
6158 #Msymbol and values are symbols representing input keys, which are
6159 currently assigned to the command.
6161 As the returned plist is kept in the library, the caller must not
6162 modify nor free it. */
6164 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6166 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6167 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6168 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6169 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6171 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6172 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6173 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6174 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6176 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6177 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6178 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6181 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6182 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6184 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6185 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6189 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6191 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6192 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6193 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6195 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6196 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6197 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6200 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6201 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6202 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6203 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6204 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6206 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6207 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6210 minput_get_commands (MSymbol language, MSymbol name)
6212 MInputMethodInfo *im_info;
6217 im_info = get_im_info (language, name, Mnil, Mcommand);
6218 if (! im_info || ! im_info->configured_vars)
6220 M17N_OBJECT_UNREF (im_info->bc_cmds);
6221 im_info->bc_cmds = mplist ();
6222 MPLIST_DO (cmds, im_info->configured_cmds)
6224 MPlist *plist = MPLIST_PLIST (cmds);
6225 MPlist *elt = mplist ();
6227 mplist_push (im_info->bc_cmds, Mplist, elt);
6228 mplist_add (elt, MPLIST_SYMBOL (plist),
6229 mplist_copy (MPLIST_NEXT (plist)));
6230 M17N_OBJECT_UNREF (elt);
6232 return im_info->bc_cmds;
6238 @brief Assign a key sequence to an input method command (obsolete).
6240 This function is obsolete. Use minput_config_command () instead.
6242 The minput_assign_command_keys () function assigns input key
6243 sequence $KEYSEQ to input method command $COMMAND for the input
6244 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6245 key sequence is assigned globally no matter what $LANGUAGE is.
6246 Otherwise the key sequence is assigned locally.
6248 Each element of $KEYSEQ must have the key $Msymbol and the value
6249 must be a symbol representing an input key.
6251 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6252 globally or locally.
6254 This assignment gets effective in a newly opened input method.
6257 If the operation was successful, 0 is returned. Otherwise -1 is
6258 returned, and #merror_code is set to @c MERROR_IM. */
6260 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6262 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6263 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6264 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6265 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6266 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6268 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6269 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6271 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6272 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6274 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6278 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6279 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6282 minput_assign_command_keys (MSymbol language, MSymbol name,
6283 MSymbol command, MPlist *keyseq)
6289 if (command == Mnil)
6290 MERROR (MERROR_IM, -1);
6295 if (! check_command_keyseq (keyseq))
6296 MERROR (MERROR_IM, -1);
6298 mplist_add (plist, Mplist, keyseq);
6303 ret = minput_config_command (language, name, command, keyseq);
6304 M17N_OBJECT_UNREF (keyseq);
6311 @brief Call a callback function
6313 The minput_callback () functions calls a callback function
6314 $COMMAND assigned for the input context $IC. The caller must set
6315 specific elements in $IC->plist if the callback function requires.
6318 If there exists a specified callback function, 0 is returned.
6319 Otherwise -1 is returned. By side effects, $IC->plist may be
6323 minput_callback (MInputContext *ic, MSymbol command)
6325 MInputCallbackFunc func;
6327 if (! ic->im->driver.callback_list)
6329 func = ((MInputCallbackFunc)
6330 mplist_get_func (ic->im->driver.callback_list, command));
6333 (func) (ic, command);
6340 /*** @addtogroup m17nDebug */
6346 @brief Dump an input method.
6348 The mdebug_dump_im () function prints the input method $IM in a
6349 human readable way to the stderr. $INDENT specifies how many
6350 columns to indent the lines but the first one.
6353 This function returns $IM. */
6355 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6357 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6358 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6361 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6364 mdebug_dump_im (MInputMethod *im, int indent)
6366 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6369 prefix = (char *) alloca (indent + 1);
6370 memset (prefix, 32, indent);
6371 prefix[indent] = '\0';
6373 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6374 msymbol_name (im->name));
6375 mdebug_dump_mtext (im_info->title, 0, 0);
6376 if (im->name != Mnil)
6380 MPLIST_DO (state, im_info->states)
6382 fprintf (stderr, "\n%s ", prefix);
6383 dump_im_state (MPLIST_VAL (state), indent + 2);
6386 fprintf (stderr, ")");