1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
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> ³°ÉôÆþÎϥ᥽¥Ã¥É
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)
665 name = MSYMBOL_NAME (sym);
667 && (name[1] == '-' || name[1] == '+')
668 && name[2] >= '1' && name[2] <= '9')
669 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
674 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
676 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
678 MText *preedit = ic->preedit;
679 int len = mtext_nchars (preedit);
681 if (MPLIST_INTEGER_P (arg))
682 return MPLIST_INTEGER (arg);
684 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
687 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
689 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
692 return ic_info->key_head;
693 if ((code == '-' || code == '+'))
695 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
699 pos = atoi (name + 1);
701 return get_preceding_char (ic, 0);
703 pos = ic->cursor_pos + pos;
705 pos = ic->cursor_pos + pos - 1;
708 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
709 return mtext_ref_char (ic->produced,
710 mtext_len (ic->produced) + pos);
711 return get_preceding_char (ic, - pos);
714 return get_following_char (ic, pos - len);
717 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
719 else if (code >= '0' && code <= '9')
721 else if (code == '=')
722 pos = ic->cursor_pos;
723 else if (code == '[')
724 pos = ic->cursor_pos - 1;
725 else if (code == ']')
726 pos = ic->cursor_pos + 1;
727 else if (code == '<')
729 else if (code == '>')
731 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
735 parse_expression (MPlist *plist)
739 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
741 if (! MPLIST_PLIST_P (plist))
743 plist = MPLIST_PLIST (plist);
744 op = MPLIST_SYMBOL (plist);
745 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
746 && op != Mand && op != Mor && op != Mnot
747 && op != Mless && op != Mgreater && op != Mequal
748 && op != Mless_equal && op != Mgreater_equal)
749 MERROR (MERROR_IM, -1);
750 MPLIST_DO (plist, MPLIST_NEXT (plist))
751 if (parse_expression (plist) < 0)
757 resolve_expression (MInputContext *ic, MPlist *plist)
762 if (MPLIST_INTEGER_P (plist))
763 return MPLIST_INTEGER (plist);
764 if (MPLIST_SYMBOL_P (plist))
765 return integer_value (ic, plist, 1);
766 if (! MPLIST_PLIST_P (plist))
768 plist = MPLIST_PLIST (plist);
769 if (! MPLIST_SYMBOL_P (plist))
771 op = MPLIST_SYMBOL (plist);
772 plist = MPLIST_NEXT (plist);
773 val = resolve_expression (ic, plist);
775 MPLIST_DO (plist, MPLIST_NEXT (plist))
776 val += resolve_expression (ic, plist);
777 else if (op == Mminus)
778 MPLIST_DO (plist, MPLIST_NEXT (plist))
779 val -= resolve_expression (ic, plist);
780 else if (op == Mstar)
781 MPLIST_DO (plist, MPLIST_NEXT (plist))
782 val *= resolve_expression (ic, plist);
783 else if (op == Mslash)
784 MPLIST_DO (plist, MPLIST_NEXT (plist))
785 val /= resolve_expression (ic, plist);
787 MPLIST_DO (plist, MPLIST_NEXT (plist))
788 val &= resolve_expression (ic, plist);
790 MPLIST_DO (plist, MPLIST_NEXT (plist))
791 val |= resolve_expression (ic, plist);
794 else if (op == Mless)
795 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
796 else if (op == Mequal)
797 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
798 else if (op == Mgreater)
799 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
800 else if (op == Mless_equal)
801 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
802 else if (op == Mgreater_equal)
803 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
807 /* Parse PLIST as an action list. PLIST should have this form:
808 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
809 Return 0 if successfully parsed, otherwise return -1. */
812 parse_action_list (MPlist *plist, MPlist *macros)
814 MPLIST_DO (plist, plist)
816 if (MPLIST_MTEXT_P (plist))
818 /* This is a short form of (insert MTEXT). */
819 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
820 MERROR (MERROR_IM, -1); */
822 else if (MPLIST_PLIST_P (plist)
823 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
824 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
828 /* This is a short form of (insert (GROUPS *)). */
829 MPLIST_DO (pl, MPLIST_PLIST (plist))
831 if (MPLIST_PLIST_P (pl))
835 MPLIST_DO (elt, MPLIST_PLIST (pl))
836 if (! MPLIST_MTEXT_P (elt)
837 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
838 MERROR (MERROR_IM, -1);
842 if (! MPLIST_MTEXT_P (pl)
843 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
844 MERROR (MERROR_IM, -1);
848 else if (MPLIST_INTEGER_P (plist))
850 int c = MPLIST_INTEGER (plist);
852 if (c < 0 || c > MCHAR_MAX)
853 MERROR (MERROR_IM, -1);
855 else if (MPLIST_PLIST_P (plist)
856 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
858 MPlist *pl = MPLIST_PLIST (plist);
859 MSymbol action_name = MPLIST_SYMBOL (pl);
861 pl = MPLIST_NEXT (pl);
863 if (action_name == M_candidates)
865 /* This is an already regularised action. */
868 if (action_name == Minsert)
870 if (MPLIST_MTEXT_P (pl))
872 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
873 MERROR (MERROR_IM, -1);
875 else if (MPLIST_INTEGER_P (pl))
877 int c = MPLIST_INTEGER (pl);
879 if (c < 0 || c > MCHAR_MAX)
880 MERROR (MERROR_IM, -1);
882 else if (MPLIST_PLIST_P (pl))
884 MPLIST_DO (pl, MPLIST_PLIST (pl))
886 if (MPLIST_PLIST_P (pl))
890 MPLIST_DO (elt, MPLIST_PLIST (pl))
891 if (! MPLIST_MTEXT_P (elt)
892 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
893 MERROR (MERROR_IM, -1);
897 if (! MPLIST_MTEXT_P (pl)
898 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
899 MERROR (MERROR_IM, -1);
903 else if (! MPLIST_SYMBOL_P (pl))
904 MERROR (MERROR_IM, -1);
906 else if (action_name == Mselect
907 || action_name == Mdelete
908 || action_name == Mmove)
910 if (parse_expression (pl) < 0)
913 else if (action_name == Mmark
914 || action_name == Mcall
915 || action_name == Mshift)
917 if (! MPLIST_SYMBOL_P (pl))
918 MERROR (MERROR_IM, -1);
920 else if (action_name == Mundo)
922 if (! MPLIST_TAIL_P (pl))
924 if (! MPLIST_SYMBOL_P (pl)
925 && ! MPLIST_INTEGER_P (pl))
926 MERROR (MERROR_IM, -1);
929 else if (action_name == Mpushback)
931 if (MPLIST_MTEXT_P (pl))
933 MText *mt = MPLIST_MTEXT (pl);
935 if (mtext_nchars (mt) != mtext_nbytes (mt))
936 MERROR (MERROR_IM, -1);
938 else if (MPLIST_PLIST_P (pl))
942 MPLIST_DO (p, MPLIST_PLIST (pl))
943 if (! MPLIST_SYMBOL_P (p))
944 MERROR (MERROR_IM, -1);
946 else if (! MPLIST_INTEGER_P (pl))
947 MERROR (MERROR_IM, -1);
949 else if (action_name == Mset || action_name == Madd
950 || action_name == Msub || action_name == Mmul
951 || action_name == Mdiv)
953 if (! MPLIST_SYMBOL_P (pl))
954 MERROR (MERROR_IM, -1);
955 if (parse_expression (MPLIST_NEXT (pl)) < 0)
958 else if (action_name == Mequal || action_name == Mless
959 || action_name == Mgreater || action_name == Mless_equal
960 || action_name == Mgreater_equal)
962 if (parse_expression (pl) < 0
963 || parse_expression (MPLIST_NEXT (pl)) < 0)
965 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
966 if (! MPLIST_PLIST_P (pl))
967 MERROR (MERROR_IM, -1);
968 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
969 MERROR (MERROR_IM, -1);
970 pl = MPLIST_NEXT (pl);
971 if (MPLIST_PLIST_P (pl)
972 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
973 MERROR (MERROR_IM, -1);
975 else if (action_name == Mshow || action_name == Mhide
976 || action_name == Mcommit || action_name == Munhandle
977 || action_name == Mpop)
979 else if (action_name == Mcond)
982 if (! MPLIST_PLIST_P (pl))
983 MERROR (MERROR_IM, -1);
985 else if (! macros || ! mplist_get (macros, action_name))
986 MERROR (MERROR_IM, -1);
988 else if (! MPLIST_SYMBOL_P (plist))
989 MERROR (MERROR_IM, -1);
996 resolve_command (MPlist *cmds, MSymbol command)
1000 if (! cmds || ! (plist = mplist__assq (cmds, command)))
1002 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
1003 plist = MPLIST_NEXT (plist);
1004 plist = MPLIST_NEXT (plist);
1005 plist = MPLIST_NEXT (plist);
1009 /* Load a translation into MAP from PLIST.
1010 PLIST has this form:
1011 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
1014 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
1015 MPlist *branch_actions, MPlist *macros)
1020 if (MPLIST_MTEXT_P (keylist))
1022 MText *mt = MPLIST_MTEXT (keylist);
1024 len = mtext_nchars (mt);
1025 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
1027 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1028 for (i = 0; i < len; i++)
1029 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1035 if (MFAILP (MPLIST_PLIST_P (keylist)))
1037 elt = MPLIST_PLIST (keylist);
1038 len = MPLIST_LENGTH (elt);
1039 if (MFAILP (len > 0))
1041 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1042 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1044 if (MPLIST_INTEGER_P (elt))
1046 int c = MPLIST_INTEGER (elt);
1048 if (MFAILP (c >= 0 && c < 0x100))
1050 keyseq[i] = one_char_symbol[c];
1054 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1056 keyseq[i] = MPLIST_SYMBOL (elt);
1061 for (i = 0; i < len; i++)
1063 MIMMap *deeper = NULL;
1066 deeper = mplist_get (map->submaps, keyseq[i]);
1068 map->submaps = mplist ();
1071 /* Fixme: It is better to make all deeper maps at once. */
1072 MSTRUCT_CALLOC (deeper, MERROR_IM);
1073 mplist_put (map->submaps, keyseq[i], deeper);
1078 /* We reach a terminal map. */
1079 if (map->map_actions
1080 || map->branch_actions)
1081 /* This map is already defined. We avoid overriding it. */
1084 if (! MPLIST_TAIL_P (map_actions))
1086 if (parse_action_list (map_actions, macros) < 0)
1087 MERROR (MERROR_IM, -1);
1088 map->map_actions = map_actions;
1092 map->branch_actions = branch_actions;
1093 M17N_OBJECT_REF (branch_actions);
1099 /* Load a branch from PLIST into MAP. PLIST has this form:
1100 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1103 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1106 MPlist *branch_actions;
1108 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1110 map_name = MPLIST_SYMBOL (plist);
1111 plist = MPLIST_NEXT (plist);
1112 if (MPLIST_TAIL_P (plist))
1113 branch_actions = NULL;
1114 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1117 branch_actions = plist;
1118 if (map_name == Mnil)
1120 map->branch_actions = branch_actions;
1122 M17N_OBJECT_REF (branch_actions);
1124 else if (map_name == Mt)
1126 map->map_actions = branch_actions;
1128 M17N_OBJECT_REF (branch_actions);
1130 else if (im_info->maps)
1132 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1133 if (! plist && im_info->configured_vars)
1135 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1137 if (p && MPLIST_PLIST_P (p))
1139 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1140 if (MPLIST_SYMBOL_P (p))
1141 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1146 MPLIST_DO (plist, plist)
1148 MPlist *keylist, *map_actions;
1150 if (! MPLIST_PLIST_P (plist))
1151 MERROR (MERROR_IM, -1);
1152 keylist = MPLIST_PLIST (plist);
1153 map_actions = MPLIST_NEXT (keylist);
1154 if (MPLIST_SYMBOL_P (keylist))
1156 MSymbol command = MPLIST_SYMBOL (keylist);
1159 if (MFAILP (command != Mat_reload))
1161 pl = resolve_command (im_info->configured_cmds, command);
1165 load_translation (map, pl, map_actions, branch_actions,
1169 load_translation (map, keylist, map_actions, branch_actions,
1178 /* Load a macro from PLIST into IM_INFO->macros.
1179 PLIST has this form:
1180 PLIST ::= ( MACRO-NAME ACTION * )
1181 IM_INFO->macros is a plist of macro names vs action list. */
1184 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1189 if (! MPLIST_SYMBOL_P (plist))
1190 MERROR (MERROR_IM, -1);
1191 name = MPLIST_SYMBOL (plist);
1192 plist = MPLIST_NEXT (plist);
1193 if (MFAILP (! MPLIST_TAIL_P (plist)))
1194 MERROR (MERROR_IM, -1);
1195 pl = mplist_get (im_info->macros, name);
1196 M17N_OBJECT_UNREF (pl);
1197 mplist_put (im_info->macros, name, plist);
1198 M17N_OBJECT_REF (plist);
1202 /* Load an external module from PLIST into IM_INFO->externals.
1203 PLIST has this form:
1204 PLIST ::= ( MODULE-NAME FUNCTION * )
1205 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1208 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1213 MIMExternalModule *external;
1217 if (MPLIST_MTEXT_P (plist))
1218 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1219 else if (MPLIST_SYMBOL_P (plist))
1220 module = MPLIST_SYMBOL (plist);
1221 module_file = alloca (strlen (MSYMBOL_NAME (module))
1222 + strlen (DLOPEN_SHLIB_EXT) + 1);
1223 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1225 handle = dlopen (module_file, RTLD_NOW);
1226 if (MFAILP (handle))
1228 fprintf (stderr, "%s\n", dlerror ());
1231 func_list = mplist ();
1232 MPLIST_DO (plist, MPLIST_NEXT (plist))
1234 if (! MPLIST_SYMBOL_P (plist))
1235 MERROR_GOTO (MERROR_IM, err_label);
1236 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1239 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1242 MSTRUCT_MALLOC (external, MERROR_IM);
1243 external->handle = handle;
1244 external->func_list = func_list;
1245 mplist_add (im_info->externals, module, external);
1250 M17N_OBJECT_UNREF (func_list);
1255 free_map (MIMMap *map, int top)
1260 M17N_OBJECT_UNREF (map->map_actions);
1263 MPLIST_DO (plist, map->submaps)
1264 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1265 M17N_OBJECT_UNREF (map->submaps);
1267 M17N_OBJECT_UNREF (map->branch_actions);
1272 free_state (void *object)
1274 MIMState *state = object;
1276 M17N_OBJECT_UNREF (state->title);
1278 free_map (state->map, 1);
1282 /** Load a state from PLIST into a newly allocated state object.
1283 PLIST has this form:
1284 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1285 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1286 Return the state object. */
1289 load_state (MInputMethodInfo *im_info, MPlist *plist)
1293 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1295 M17N_OBJECT (state, free_state, MERROR_IM);
1296 state->name = MPLIST_SYMBOL (plist);
1297 plist = MPLIST_NEXT (plist);
1298 if (MPLIST_MTEXT_P (plist))
1300 state->title = MPLIST_MTEXT (plist);
1301 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1302 Mlanguage, im_info->language);
1303 M17N_OBJECT_REF (state->title);
1304 plist = MPLIST_NEXT (plist);
1306 MSTRUCT_CALLOC (state->map, MERROR_IM);
1307 MPLIST_DO (plist, plist)
1309 if (MFAILP (MPLIST_PLIST_P (plist)))
1311 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1316 /* Return a newly created IM_INFO for an input method specified by
1317 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1319 static MInputMethodInfo *
1320 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1323 MInputMethodInfo *im_info;
1326 if (name == Mnil && extra == Mnil)
1327 language = Mt, extra = Mglobal;
1328 MSTRUCT_CALLOC (im_info, MERROR_IM);
1330 im_info->language = language;
1331 im_info->name = name;
1332 im_info->extra = extra;
1335 mplist_add (plist, Mplist, elt);
1336 M17N_OBJECT_UNREF (elt);
1337 elt = mplist_add (elt, Msymbol, language);
1338 elt = mplist_add (elt, Msymbol, name);
1339 elt = mplist_add (elt, Msymbol, extra);
1340 mplist_add (elt, Mt, im_info);
1346 fini_im_info (MInputMethodInfo *im_info)
1350 M17N_OBJECT_UNREF (im_info->cmds);
1351 M17N_OBJECT_UNREF (im_info->configured_cmds);
1352 M17N_OBJECT_UNREF (im_info->bc_cmds);
1353 M17N_OBJECT_UNREF (im_info->vars);
1354 M17N_OBJECT_UNREF (im_info->configured_vars);
1355 M17N_OBJECT_UNREF (im_info->bc_vars);
1356 M17N_OBJECT_UNREF (im_info->description);
1357 M17N_OBJECT_UNREF (im_info->title);
1358 if (im_info->states)
1360 MPLIST_DO (plist, im_info->states)
1362 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1364 M17N_OBJECT_UNREF (state);
1366 M17N_OBJECT_UNREF (im_info->states);
1369 if (im_info->macros)
1371 MPLIST_DO (plist, im_info->macros)
1372 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1373 M17N_OBJECT_UNREF (im_info->macros);
1376 if (im_info->externals)
1378 MPLIST_DO (plist, im_info->externals)
1380 MIMExternalModule *external = MPLIST_VAL (plist);
1382 dlclose (external->handle);
1383 M17N_OBJECT_UNREF (external->func_list);
1385 MPLIST_KEY (plist) = Mt;
1387 M17N_OBJECT_UNREF (im_info->externals);
1391 MPLIST_DO (plist, im_info->maps)
1393 MPlist *p = MPLIST_PLIST (plist);
1395 M17N_OBJECT_UNREF (p);
1397 M17N_OBJECT_UNREF (im_info->maps);
1404 free_im_info (MInputMethodInfo *im_info)
1406 fini_im_info (im_info);
1411 free_im_list (MPlist *plist)
1415 MPLIST_DO (pl, plist)
1417 MInputMethodInfo *im_info;
1419 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1420 im_info = MPLIST_VAL (elt);
1421 free_im_info (im_info);
1423 M17N_OBJECT_UNREF (plist);
1426 static MInputMethodInfo *
1427 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1429 if (name == Mnil && extra == Mnil)
1430 language = Mt, extra = Mglobal;
1431 while ((plist = mplist__assq (plist, language)))
1433 MPlist *elt = MPLIST_PLIST (plist);
1435 plist = MPLIST_NEXT (plist);
1436 elt = MPLIST_NEXT (elt);
1437 if (MPLIST_SYMBOL (elt) != name)
1439 elt = MPLIST_NEXT (elt);
1440 if (MPLIST_SYMBOL (elt) != extra)
1442 elt = MPLIST_NEXT (elt);
1443 return MPLIST_VAL (elt);
1448 static void load_im_info (MPlist *, MInputMethodInfo *);
1450 #define get_custom_info(im_info) \
1452 ? lookup_im_info (im_custom_list, (im_info)->language, \
1453 (im_info)->name, (im_info)->extra) \
1456 #define get_config_info(im_info) \
1458 ? lookup_im_info (im_config_list, (im_info)->language, \
1459 (im_info)->name, (im_info)->extra) \
1463 update_custom_info (void)
1469 if (mdatabase__check (im_custom_mdb) > 0)
1474 MDatabaseInfo *custom_dir_info;
1475 char custom_path[PATH_MAX + 1];
1477 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1478 if (! custom_dir_info->filename
1479 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1481 strcpy (custom_path, custom_dir_info->filename);
1482 strcat (custom_path, CUSTOM_FILE);
1483 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1489 free_im_list (im_custom_list);
1490 im_custom_list = NULL;
1492 plist = mdatabase_load (im_custom_mdb);
1495 im_custom_list = mplist ();
1497 MPLIST_DO (pl, plist)
1499 MSymbol language, name, extra;
1500 MInputMethodInfo *im_info;
1501 MPlist *im_data, *p;
1503 if (! MPLIST_PLIST_P (pl))
1505 p = MPLIST_PLIST (pl);
1506 im_data = MPLIST_NEXT (p);
1507 if (! MPLIST_PLIST_P (p))
1509 p = MPLIST_PLIST (p);
1510 if (! MPLIST_SYMBOL_P (p)
1511 || MPLIST_SYMBOL (p) != Minput_method)
1513 p = MPLIST_NEXT (p);
1514 if (! MPLIST_SYMBOL_P (p))
1516 language = MPLIST_SYMBOL (p);
1517 p = MPLIST_NEXT (p);
1518 if (! MPLIST_SYMBOL_P (p))
1520 name = MPLIST_SYMBOL (p);
1521 p = MPLIST_NEXT (p);
1522 if (MPLIST_TAIL_P (p))
1524 else if (MPLIST_SYMBOL_P (p))
1525 extra = MPLIST_SYMBOL (p);
1526 if (language == Mnil || (name == Mnil && extra == Mnil))
1528 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1529 load_im_info (im_data, im_info);
1531 M17N_OBJECT_UNREF (plist);
1536 update_global_info (void)
1542 int ret = mdatabase__check (global_info->mdb);
1546 fini_im_info (global_info);
1550 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1554 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1556 if (! global_info->mdb
1557 || ! (plist = mdatabase_load (global_info->mdb)))
1560 load_im_info (plist, global_info);
1561 M17N_OBJECT_UNREF (plist);
1566 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1567 and EXTRA. KEY, if not Mnil, tells which kind of information about
1568 the input method is necessary, and the returned IM_INFO may contain
1569 only that information. */
1571 static MInputMethodInfo *
1572 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1575 MInputMethodInfo *im_info;
1578 if (name == Mnil && extra == Mnil)
1579 language = Mt, extra = Mglobal;
1580 im_info = lookup_im_info (im_info_list, language, name, extra);
1583 if (key == Mnil ? im_info->states != NULL
1584 : key == Mcommand ? im_info->cmds != NULL
1585 : key == Mvariable ? im_info->vars != NULL
1586 : key == Mtitle ? im_info->title != NULL
1587 : key == Mdescription ? im_info->description != NULL
1589 /* IM_INFO already contains required information. */
1591 /* We have not yet loaded required information. */
1595 mdb = mdatabase_find (Minput_method, language, name, extra);
1598 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1603 plist = mdatabase_load (im_info->mdb);
1607 mplist_push (load_im_info_keys, key, Mt);
1608 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1609 mplist_pop (load_im_info_keys);
1613 MERROR (MERROR_IM, im_info);
1614 update_global_info ();
1615 load_im_info (plist, im_info);
1616 M17N_OBJECT_UNREF (plist);
1619 if (! im_info->cmds)
1620 im_info->cmds = mplist ();
1621 if (! im_info->vars)
1622 im_info->vars = mplist ();
1623 if (! im_info->states)
1624 im_info->states = mplist ();
1626 if (! im_info->title
1627 && (key == Mnil || key == Mtitle))
1628 im_info->title = (name == Mnil ? mtext ()
1629 : mtext_from_data (MSYMBOL_NAME (name),
1630 MSYMBOL_NAMELEN (name),
1631 MTEXT_FORMAT_US_ASCII));
1635 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1636 If updated, but got unloadable, return -1. Otherwise, update
1637 contents of IM_INFO from the new database, and return 1. */
1640 reload_im_info (MInputMethodInfo *im_info)
1645 update_custom_info ();
1646 update_global_info ();
1647 check = mdatabase__check (im_info->mdb);
1650 plist = mdatabase_load (im_info->mdb);
1653 fini_im_info (im_info);
1654 load_im_info (plist, im_info);
1655 M17N_OBJECT_UNREF (plist);
1656 if (! im_info->cmds)
1657 im_info->cmds = mplist ();
1658 if (! im_info->vars)
1659 im_info->vars = mplist ();
1660 if (! im_info->title)
1662 MSymbol name = im_info->name;
1664 im_info->title = (name == Mnil ? mtext ()
1665 : mtext_from_data (MSYMBOL_NAME (name),
1666 MSYMBOL_NAMELEN (name),
1667 MTEXT_FORMAT_US_ASCII));
1672 static MInputMethodInfo *
1673 get_im_info_by_tags (MPlist *plist)
1678 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1679 i++, plist = MPLIST_NEXT (plist))
1680 tag[i] = MPLIST_SYMBOL (plist);
1685 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1690 check_description (MPlist *plist)
1694 if (MPLIST_MTEXT_P (plist))
1696 if (MPLIST_PLIST_P (plist))
1698 MPlist *pl = MPLIST_PLIST (plist);
1700 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1702 pl =MPLIST_NEXT (pl);
1703 if (MFAILP (MPLIST_MTEXT_P (pl)))
1705 mt = MPLIST_MTEXT (pl);
1706 M17N_OBJECT_REF (mt);
1709 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1711 if (translated == (char *) MTEXT_DATA (mt))
1712 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1713 if (translated != (char *) MTEXT_DATA (mt))
1715 M17N_OBJECT_UNREF (mt);
1716 mt = mtext__from_data (translated, strlen (translated),
1717 MTEXT_FORMAT_UTF_8, 1);
1721 mplist_set (plist, Mtext, mt);
1722 M17N_OBJECT_UNREF (mt);
1725 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1731 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1735 check_command_keyseq (MPlist *keyseq)
1737 if (MPLIST_PLIST_P (keyseq))
1739 MPlist *p = MPLIST_PLIST (keyseq);
1742 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1746 if (MPLIST_MTEXT_P (keyseq))
1748 MText *mt = MPLIST_MTEXT (keyseq);
1751 for (i = 0; i < mtext_nchars (mt); i++)
1752 if (mtext_ref_char (mt, i) >= 256)
1759 /* Load command defitions from PLIST into IM_INFO->cmds.
1761 PLIST is well-formed and has this form;
1762 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1763 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1764 M-text or a plist of symbols.
1766 The returned list has the same form, but for each element...
1768 (1) If DESCRIPTION and the rest are omitted, the element is not
1769 stored in the returned list.
1771 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1772 description in global_info->cmds (if any). */
1775 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1779 im_info->cmds = tail = mplist ();
1781 MPLIST_DO (plist, MPLIST_NEXT (plist))
1783 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1786 if (MFAILP (MPLIST_PLIST_P (plist)))
1788 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1789 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1791 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1792 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1794 if (MFAILP (im_info != global_info))
1795 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1799 if (! check_description (p))
1800 mplist_set (p, Msymbol, Mnil);
1801 p = MPLIST_NEXT (p);
1802 while (! MPLIST_TAIL_P (p))
1804 if (MFAILP (check_command_keyseq (p)))
1805 mplist__pop_unref (p);
1807 p = MPLIST_NEXT (p);
1810 tail = mplist_add (tail, Mplist, pl);
1815 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1816 MPlist *config_cmds)
1818 MPlist *global = NULL, *custom = NULL, *config = NULL;
1819 MSymbol name = MPLIST_SYMBOL (plist);
1821 MPlist *description, *keyseq;
1823 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1824 global = MPLIST_NEXT (MPLIST_PLIST (global));
1826 plist = MPLIST_NEXT (plist);
1827 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1829 description = plist;
1830 plist = MPLIST_NEXT (plist);
1834 description = global;
1835 if (! MPLIST_TAIL_P (plist))
1836 plist = MPLIST_NEXT (plist);
1838 if (MPLIST_TAIL_P (plist) && global)
1840 keyseq = MPLIST_NEXT (global);
1841 status = Minherited;
1849 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1851 status = Mconfigured;
1852 config = MPLIST_NEXT (MPLIST_PLIST (config));
1853 if (! MPLIST_TAIL_P (config))
1856 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1858 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1860 if (MPLIST_TAIL_P (this_keyseq))
1861 mplist__pop_unref (custom);
1864 status = Mcustomized;
1865 keyseq = this_keyseq;
1870 mplist_add (plist, Msymbol, name);
1872 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1874 mplist_add (plist, Msymbol, Mnil);
1875 mplist_add (plist, Msymbol, status);
1876 mplist__conc (plist, keyseq);
1881 config_all_commands (MInputMethodInfo *im_info)
1883 MPlist *global_cmds, *custom_cmds, *config_cmds;
1884 MInputMethodInfo *temp;
1885 MPlist *tail, *plist;
1887 M17N_OBJECT_UNREF (im_info->configured_cmds);
1889 if (MPLIST_TAIL_P (im_info->cmds)
1893 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1894 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1895 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1897 im_info->configured_cmds = tail = mplist ();
1898 MPLIST_DO (plist, im_info->cmds)
1900 MPlist *pl = config_command (MPLIST_PLIST (plist),
1901 global_cmds, custom_cmds, config_cmds);
1904 tail = mplist_add (tail, Mplist, pl);
1905 M17N_OBJECT_UNREF (pl);
1910 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1911 valid, return 0 if not. */
1914 check_variable_value (MPlist *val, MPlist *global)
1916 MSymbol type = MPLIST_KEY (val);
1917 MPlist *valids = MPLIST_NEXT (val);
1919 if (type != Minteger && type != Mtext && type != Msymbol)
1923 if (MPLIST_KEY (global) != Mt
1924 && MPLIST_KEY (global) != MPLIST_KEY (val))
1926 if (MPLIST_TAIL_P (valids))
1927 valids = MPLIST_NEXT (global);
1929 if (MPLIST_TAIL_P (valids))
1932 if (type == Minteger)
1934 int n = MPLIST_INTEGER (val);
1936 MPLIST_DO (valids, valids)
1938 if (MPLIST_INTEGER_P (valids))
1940 if (n == MPLIST_INTEGER (valids))
1943 else if (MPLIST_PLIST_P (valids))
1945 MPlist *p = MPLIST_PLIST (valids);
1946 int min_bound, max_bound;
1948 if (! MPLIST_INTEGER_P (p))
1949 MERROR (MERROR_IM, 0);
1950 min_bound = MPLIST_INTEGER (p);
1951 p = MPLIST_NEXT (p);
1952 if (! MPLIST_INTEGER_P (p))
1953 MERROR (MERROR_IM, 0);
1954 max_bound = MPLIST_INTEGER (p);
1955 if (n >= min_bound && n <= max_bound)
1960 else if (type == Msymbol)
1962 MSymbol sym = MPLIST_SYMBOL (val);
1964 MPLIST_DO (valids, valids)
1966 if (! MPLIST_SYMBOL_P (valids))
1967 MERROR (MERROR_IM, 0);
1968 if (sym == MPLIST_SYMBOL (valids))
1974 MText *mt = MPLIST_MTEXT (val);
1976 MPLIST_DO (valids, valids)
1978 if (! MPLIST_MTEXT_P (valids))
1979 MERROR (MERROR_IM, 0);
1980 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1985 return (! MPLIST_TAIL_P (valids));
1988 /* Load variable defitions from PLIST into IM_INFO->vars.
1990 PLIST is well-formed and has this form;
1991 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1993 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1995 The returned list has the same form, but for each element...
1997 (1) If DESCRIPTION and the rest are omitted, the element is not
1998 stored in the returned list.
2000 (2) If DESCRIPTION is nil, it is complemented by the corresponding
2001 description in global_info->vars (if any). */
2004 load_variables (MInputMethodInfo *im_info, MPlist *plist)
2006 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
2007 ? global_info->vars : NULL);
2010 im_info->vars = tail = mplist ();
2011 MPLIST_DO (plist, MPLIST_NEXT (plist))
2015 if (MFAILP (MPLIST_PLIST_P (plist)))
2017 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
2018 if (MFAILP (MPLIST_SYMBOL_P (pl)))
2020 if (im_info == global_info)
2022 /* Loading a global variable. */
2023 p = MPLIST_NEXT (pl);
2024 if (MPLIST_TAIL_P (p))
2025 mplist_add (p, Msymbol, Mnil);
2028 if (! check_description (p))
2029 mplist_set (p, Msymbol, Mnil);
2030 p = MPLIST_NEXT (p);
2031 if (MFAILP (! MPLIST_TAIL_P (p)
2032 && check_variable_value (p, NULL)))
2033 mplist_set (p, Mt, NULL);
2036 else if (im_info->mdb)
2038 /* Loading a local variable. */
2039 MSymbol name = MPLIST_SYMBOL (pl);
2040 MPlist *global = NULL;
2043 && (p = mplist__assq (global_vars, name)))
2045 /* P ::= ((NAME DESC ...) ...) */
2046 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2047 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2048 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2051 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2052 if (! MPLIST_TAIL_P (p))
2054 if (! check_description (p))
2055 mplist_set (p, Msymbol, Mnil);
2056 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2057 if (MFAILP (! MPLIST_TAIL_P (p)))
2058 mplist_set (p, Mt, NULL);
2061 MPlist *valid_values = MPLIST_NEXT (p);
2063 if (! MPLIST_TAIL_P (valid_values)
2064 ? MFAILP (check_variable_value (p, NULL))
2065 : global && MFAILP (check_variable_value (p, global)))
2066 mplist_set (p, Mt, NULL);
2072 /* Loading a variable customization. */
2073 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2074 if (MFAILP (! MPLIST_TAIL_P (p)))
2076 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2077 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2078 || MPLIST_MTEXT_P (p)))
2081 tail = mplist_add (tail, Mplist, pl);
2086 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2087 MPlist *config_vars)
2089 MPlist *global = NULL, *custom = NULL, *config = NULL;
2090 MSymbol name = MPLIST_SYMBOL (plist);
2092 MPlist *description = NULL, *value, *valids;
2096 global = mplist__assq (global_vars, name);
2098 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2101 plist = MPLIST_NEXT (plist);
2102 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2103 description = plist;
2105 description = global;
2107 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2109 if (MPLIST_TAIL_P (plist))
2111 /* Inherit from global (if any). */
2115 if (MPLIST_KEY (value) == Mt)
2117 valids = MPLIST_NEXT (global);
2118 status = Minherited;
2130 value = plist = MPLIST_NEXT (plist);
2131 valids = MPLIST_NEXT (value);
2132 if (MPLIST_KEY (value) == Mt)
2134 if (! MPLIST_TAIL_P (valids))
2137 valids = MPLIST_NEXT (global);
2141 if (config_vars && (config = mplist__assq (config_vars, name)))
2143 status = Mconfigured;
2144 config = MPLIST_NEXT (MPLIST_PLIST (config));
2145 if (! MPLIST_TAIL_P (config))
2148 if (MFAILP (check_variable_value (value, global ? global : plist)))
2152 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2154 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2156 if (MPLIST_TAIL_P (this_value))
2157 mplist__pop_unref (custom);
2161 if (MFAILP (check_variable_value (value, global ? global : plist)))
2163 status = Mcustomized;
2168 mplist_add (plist, Msymbol, name);
2170 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2172 mplist_add (plist, Msymbol, Mnil);
2173 mplist_add (plist, Msymbol, status);
2175 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2177 mplist_add (plist, Mt, NULL);
2178 if (valids && ! MPLIST_TAIL_P (valids))
2179 mplist__conc (plist, valids);
2183 /* Return a configured variable definition list based on
2184 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2185 get it from global_info->vars. */
2188 config_all_variables (MInputMethodInfo *im_info)
2190 MPlist *global_vars, *custom_vars, *config_vars;
2191 MInputMethodInfo *temp;
2192 MPlist *tail, *plist;
2194 M17N_OBJECT_UNREF (im_info->configured_vars);
2196 if (MPLIST_TAIL_P (im_info->vars)
2200 global_vars = im_info != global_info ? global_info->vars : NULL;
2201 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2202 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2204 im_info->configured_vars = tail = mplist ();
2205 MPLIST_DO (plist, im_info->vars)
2207 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2208 global_vars, custom_vars, config_vars);
2211 tail = mplist_add (tail, Mplist, pl);
2212 M17N_OBJECT_UNREF (pl);
2217 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2218 CONFIG contains configuration information of the input method. */
2221 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2225 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2227 load_commands (im_info, MPLIST_PLIST (pl));
2228 config_all_commands (im_info);
2229 pl = mplist_pop (pl);
2230 M17N_OBJECT_UNREF (pl);
2233 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2235 load_variables (im_info, MPLIST_PLIST (pl));
2236 config_all_variables (im_info);
2237 pl = mplist_pop (pl);
2238 M17N_OBJECT_UNREF (pl);
2241 MPLIST_DO (plist, plist)
2242 if (MPLIST_PLIST_P (plist))
2244 MPlist *elt = MPLIST_PLIST (plist);
2247 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2249 key = MPLIST_SYMBOL (elt);
2254 elt = MPLIST_NEXT (elt);
2255 if (MFAILP (MPLIST_MTEXT_P (elt)))
2257 im_info->title = MPLIST_MTEXT (elt);
2258 M17N_OBJECT_REF (im_info->title);
2260 else if (key == Mmap)
2262 pl = mplist__from_alist (MPLIST_NEXT (elt));
2265 if (! im_info->maps)
2269 mplist__conc (im_info->maps, pl);
2270 M17N_OBJECT_UNREF (pl);
2273 else if (key == Mmacro)
2275 if (! im_info->macros)
2276 im_info->macros = mplist ();
2277 MPLIST_DO (elt, MPLIST_NEXT (elt))
2279 if (MFAILP (MPLIST_PLIST_P (elt)))
2281 load_macros (im_info, MPLIST_PLIST (elt));
2284 else if (key == Mmodule)
2286 if (! im_info->externals)
2287 im_info->externals = mplist ();
2288 MPLIST_DO (elt, MPLIST_NEXT (elt))
2290 if (MFAILP (MPLIST_PLIST_P (elt)))
2292 load_external_module (im_info, MPLIST_PLIST (elt));
2295 else if (key == Mstate)
2297 MPLIST_DO (elt, MPLIST_NEXT (elt))
2301 if (MFAILP (MPLIST_PLIST_P (elt)))
2303 pl = MPLIST_PLIST (elt);
2304 if (! im_info->states)
2305 im_info->states = mplist ();
2306 state = load_state (im_info, MPLIST_PLIST (elt));
2309 mplist_put (im_info->states, state->name, state);
2312 else if (key == Minclude)
2314 /* elt ::= include (tag1 tag2 ...) key item ... */
2316 MInputMethodInfo *temp;
2318 elt = MPLIST_NEXT (elt);
2319 if (MFAILP (MPLIST_PLIST_P (elt)))
2321 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2324 elt = MPLIST_NEXT (elt);
2325 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2327 key = MPLIST_SYMBOL (elt);
2328 elt = MPLIST_NEXT (elt);
2331 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2333 if (! im_info->maps)
2334 im_info->maps = mplist ();
2335 MPLIST_DO (pl, temp->maps)
2337 p = MPLIST_VAL (pl);
2338 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2339 M17N_OBJECT_REF (p);
2342 else if (key == Mmacro)
2344 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2346 if (! im_info->macros)
2347 im_info->macros = mplist ();
2348 MPLIST_DO (pl, temp->macros)
2350 p = MPLIST_VAL (pl);
2351 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2352 M17N_OBJECT_REF (p);
2355 else if (key == Mstate)
2357 if (! temp->states || MPLIST_TAIL_P (temp->states))
2359 if (! im_info->states)
2360 im_info->states = mplist ();
2361 MPLIST_DO (pl, temp->states)
2363 MIMState *state = MPLIST_VAL (pl);
2365 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2366 M17N_OBJECT_REF (state);
2370 else if (key == Mdescription)
2372 if (im_info->description)
2374 elt = MPLIST_NEXT (elt);
2375 if (! check_description (elt))
2377 im_info->description = MPLIST_MTEXT (elt);
2378 M17N_OBJECT_REF (im_info->description);
2381 if (im_info->macros)
2383 MPLIST_DO (pl, im_info->macros)
2384 parse_action_list (MPLIST_PLIST (pl), im_info->macros);
2387 im_info->tick = time (NULL);
2392 static int take_action_list (MInputContext *ic, MPlist *action_list);
2393 static void preedit_commit (MInputContext *ic, int need_prefix);
2396 shift_state (MInputContext *ic, MSymbol state_name)
2398 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2399 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2400 MIMState *orig_state = ic_info->state, *state;
2402 /* Find a state to shift to. If not found, shift to the initial
2404 if (state_name == Mt)
2406 if (! ic_info->prev_state)
2408 state = ic_info->prev_state;
2410 else if (state_name == Mnil)
2412 state = (MIMState *) MPLIST_VAL (im_info->states);
2416 state = (MIMState *) mplist_get (im_info->states, state_name);
2418 state = (MIMState *) MPLIST_VAL (im_info->states);
2424 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2425 MSYMBOL_NAME (orig_state->name),
2426 MSYMBOL_NAME (state->name));
2428 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2431 /* Enter the new state. */
2432 ic_info->state = state;
2433 ic_info->map = state->map;
2434 ic_info->state_key_head = ic_info->key_head;
2435 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2437 /* We have shifted to the initial state. */
2438 preedit_commit (ic, 0);
2439 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2440 ic_info->state_pos = ic->cursor_pos;
2441 if (state != orig_state)
2443 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2445 /* Shifted to the initial state. */
2446 ic_info->prev_state = NULL;
2447 M17N_OBJECT_UNREF (ic_info->vars_saved);
2448 ic_info->vars_saved = mplist_copy (ic_info->vars);
2451 ic_info->prev_state = orig_state;
2454 ic->status = state->title;
2456 ic->status = im_info->title;
2457 ic->status_changed = 1;
2458 if (ic_info->map == ic_info->state->map
2459 && ic_info->map->map_actions)
2461 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2462 MSYMBOL_NAME (state->name));
2463 take_action_list (ic, ic_info->map->map_actions);
2468 /* Find a candidate group that contains a candidate number INDEX from
2469 PLIST. Set START_INDEX to the first candidate number of the group,
2470 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2471 candidate group number if they are non-NULL. If INDEX is -1, find
2472 the last candidate group. */
2475 find_candidates_group (MPlist *plist, int index,
2476 int *start_index, int *end_index, int *group_index)
2478 int i = 0, gidx = 0, len;
2480 MPLIST_DO (plist, plist)
2482 if (MPLIST_MTEXT_P (plist))
2483 len = mtext_nchars (MPLIST_MTEXT (plist));
2485 len = mplist_length (MPLIST_PLIST (plist));
2486 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2492 *end_index = i + len;
2494 *group_index = gidx;
2503 /* Adjust markers for the change of preedit text.
2504 If FROM == TO, the change is insertion of INS chars.
2505 If FROM < TO and INS == 0, the change is deletion of the range.
2506 If FROM < TO and INS > 0, the change is replacement. */
2509 adjust_markers (MInputContext *ic, int from, int to, int ins)
2511 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2516 MPLIST_DO (markers, ic_info->markers)
2517 if (MPLIST_INTEGER (markers) > from)
2518 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2519 if (ic->cursor_pos >= from)
2520 ic->cursor_pos += ins;
2524 MPLIST_DO (markers, ic_info->markers)
2526 if (MPLIST_INTEGER (markers) >= to)
2527 MPLIST_VAL (markers)
2528 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2529 else if (MPLIST_INTEGER (markers) > from)
2530 MPLIST_VAL (markers) = (void *) from;
2532 if (ic->cursor_pos >= to)
2533 ic->cursor_pos += ins - (to - from);
2534 else if (ic->cursor_pos > from)
2535 ic->cursor_pos = from;
2541 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2543 int nchars = mt ? mtext_nchars (mt) : 1;
2547 mtext_ins (ic->preedit, pos, mt);
2548 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2552 mtext_ins_char (ic->preedit, pos, c, 1);
2554 MDEBUG_PRINT1 ("('%c')", c);
2556 MDEBUG_PRINT1 ("(U+%04X)", c);
2558 adjust_markers (ic, pos, pos, nchars);
2559 ic->preedit_changed = 1;
2564 preedit_delete (MInputContext *ic, int from, int to)
2566 mtext_del (ic->preedit, from, to);
2567 adjust_markers (ic, from, to, 0);
2568 ic->preedit_changed = 1;
2572 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2576 mtext_del (ic->preedit, from, to);
2579 mtext_ins (ic->preedit, from, mt);
2580 ins = mtext_nchars (mt);
2584 mtext_ins_char (ic->preedit, from, c, 1);
2587 adjust_markers (ic, from, to, ins);
2588 ic->preedit_changed = 1;
2593 preedit_commit (MInputContext *ic, int need_prefix)
2595 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2596 int preedit_len = mtext_nchars (ic->preedit);
2598 if (preedit_len > 0)
2602 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2603 Mcandidate_list, NULL, 0);
2604 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2605 Mcandidate_index, NULL, 0);
2606 mtext_cat (ic->produced, ic->preedit);
2612 MDEBUG_PRINT1 ("\n [IM] [%s]",
2613 MSYMBOL_NAME (ic_info->state->name));
2614 MDEBUG_PRINT (" (commit");
2615 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2616 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2620 mtext_reset (ic->preedit);
2621 mtext_reset (ic_info->preedit_saved);
2622 MPLIST_DO (p, ic_info->markers)
2624 ic->cursor_pos = ic_info->state_pos = 0;
2625 ic->preedit_changed = 1;
2626 ic_info->commit_key_head = ic_info->key_head;
2628 if (ic->candidate_list)
2630 M17N_OBJECT_UNREF (ic->candidate_list);
2631 ic->candidate_list = NULL;
2632 ic->candidate_index = 0;
2633 ic->candidate_from = ic->candidate_to = 0;
2634 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2635 if (ic->candidate_show)
2637 ic->candidate_show = 0;
2638 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2644 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2646 int code = marker_code (sym, 0);
2648 if (mt && (code == '[' || code == ']'))
2652 if (code == '[' && current > 0)
2654 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2658 else if (code == ']' && current < mtext_nchars (mt))
2660 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2666 return (code == '<' ? 0
2667 : code == '>' ? limit
2668 : code == '-' ? current - 1
2669 : code == '+' ? current + 1
2670 : code == '=' ? current
2671 : code - '0' > limit ? limit
2675 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2679 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2681 int from = mtext_property_start (prop);
2682 int to = mtext_property_end (prop);
2684 MPlist *candidate_list = mtext_property_value (prop);
2685 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2687 int ingroup_index = idx - start;
2690 candidate_list = mplist_copy (candidate_list);
2691 if (MPLIST_MTEXT_P (group))
2693 mt = MPLIST_MTEXT (group);
2694 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2702 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2703 i++, plist = MPLIST_NEXT (plist));
2704 mt = MPLIST_MTEXT (plist);
2705 preedit_replace (ic, from, to, mt, 0);
2706 to = from + mtext_nchars (mt);
2708 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2709 M17N_OBJECT_UNREF (candidate_list);
2710 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2711 ic->cursor_pos = to;
2715 get_select_charset (MInputContextInfo * ic_info)
2717 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2720 if (! MPLIST_VAL (plist))
2722 sym = MPLIST_SYMBOL (plist);
2725 return MCHARSET (sym);
2728 /* The returned plist must be UNREFed. */
2731 adjust_candidates (MPlist *plist, MCharset *charset)
2735 /* plist ::= MTEXT ... | PLIST ... */
2736 plist = mplist_copy (plist);
2737 if (MPLIST_MTEXT_P (plist))
2740 while (! MPLIST_TAIL_P (pl))
2742 /* pl ::= MTEXT ... */
2743 MText *mt = MPLIST_MTEXT (pl);
2747 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2749 c = mtext_ref_char (mt, i);
2750 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2754 mt = mtext_dup (mt);
2755 mplist_set (pl, Mtext, mt);
2756 M17N_OBJECT_UNREF (mt);
2759 mtext_del (mt, i, i + 1);
2762 if (mtext_len (mt) > 0)
2763 pl = MPLIST_NEXT (pl);
2767 M17N_OBJECT_UNREF (mt);
2771 else /* MPLIST_PLIST_P (plist) */
2774 while (! MPLIST_TAIL_P (pl))
2776 /* pl ::= (MTEXT ...) ... */
2777 MPlist *p = MPLIST_PLIST (pl);
2779 /* p ::= MTEXT ... */
2783 while (! MPLIST_TAIL_P (p0))
2785 MText *mt = MPLIST_MTEXT (p0);
2788 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2790 c = mtext_ref_char (mt, i);
2791 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2796 p0 = MPLIST_NEXT (p0);
2803 p = mplist_copy (p);
2804 mplist_set (pl, Mplist, p);
2805 M17N_OBJECT_UNREF (p);
2809 p0 = MPLIST_NEXT (p0);
2812 M17N_OBJECT_UNREF (mt);
2815 if (! MPLIST_TAIL_P (p))
2816 pl = MPLIST_NEXT (pl);
2820 M17N_OBJECT_UNREF (p);
2824 if (MPLIST_TAIL_P (plist))
2826 M17N_OBJECT_UNREF (plist);
2832 /* The returned Plist must be UNREFed. */
2835 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2837 MCharset *charset = get_select_charset (ic_info);
2842 plist = resolve_variable (ic_info, Mcandidates_group_size);
2843 column = MPLIST_INTEGER (plist);
2845 plist = MPLIST_PLIST (args);
2850 plist = adjust_candidates (plist, charset);
2855 M17N_OBJECT_REF (plist);
2860 if (MPLIST_MTEXT_P (plist))
2862 MText *mt = MPLIST_MTEXT (plist);
2863 MPlist *next = MPLIST_NEXT (plist);
2865 if (MPLIST_TAIL_P (next))
2866 M17N_OBJECT_REF (mt);
2869 mt = mtext_dup (mt);
2870 while (! MPLIST_TAIL_P (next))
2872 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2873 next = MPLIST_NEXT (next);
2876 M17N_OBJECT_UNREF (plist);
2878 len = mtext_nchars (mt);
2880 mplist_add (plist, Mtext, mt);
2883 for (i = 0; i < len; i += column)
2885 int to = (i + column < len ? i + column : len);
2886 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2888 mplist_add (plist, Mtext, sub);
2889 M17N_OBJECT_UNREF (sub);
2892 M17N_OBJECT_UNREF (mt);
2894 else if (MPLIST_PLIST_P (plist))
2896 MPlist *tail = plist;
2897 MPlist *new = mplist ();
2898 MPlist *this = mplist ();
2901 MPLIST_DO (tail, tail)
2903 MPlist *p = MPLIST_PLIST (tail);
2907 MText *mt = MPLIST_MTEXT (p);
2909 if (count == column)
2911 mplist_add (new, Mplist, this);
2912 M17N_OBJECT_UNREF (this);
2916 mplist_add (this, Mtext, mt);
2920 mplist_add (new, Mplist, this);
2921 M17N_OBJECT_UNREF (this);
2922 mplist_set (plist, Mnil, NULL);
2923 MPLIST_DO (tail, new)
2925 MPlist *elt = MPLIST_PLIST (tail);
2927 mplist_add (plist, Mplist, elt);
2929 M17N_OBJECT_UNREF (new);
2937 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2939 MPlist *action = NULL;
2943 if (MPLIST_SYMBOL_P (action_list))
2945 MSymbol var = MPLIST_SYMBOL (action_list);
2948 MPLIST_DO (p, ic_info->vars)
2949 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2951 if (MPLIST_TAIL_P (p))
2953 action = MPLIST_NEXT (MPLIST_PLIST (p));
2954 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2957 if (MPLIST_PLIST_P (action_list))
2959 action = MPLIST_PLIST (action_list);
2960 if (MPLIST_SYMBOL_P (action))
2962 name = MPLIST_SYMBOL (action);
2963 args = MPLIST_NEXT (action);
2965 && MPLIST_PLIST_P (args))
2966 mplist_set (action, Msymbol, M_candidates);
2968 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2971 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2972 mplist_push (action, Msymbol, M_candidates);
2973 mplist_set (action_list, Mplist, action);
2974 M17N_OBJECT_UNREF (action);
2977 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2980 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2981 mplist_push (action, Msymbol, Minsert);
2982 mplist_set (action_list, Mplist, action);
2983 M17N_OBJECT_UNREF (action);
2988 /* Perform list of actions in ACTION_LIST for the current input
2989 context IC. If unhandle action was not performed, return 0.
2990 Otherwise, return -1. */
2993 take_action_list (MInputContext *ic, MPlist *action_list)
2995 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2996 MPlist *candidate_list = ic->candidate_list;
2997 int candidate_index = ic->candidate_index;
2998 int candidate_show = ic->candidate_show;
2999 MTextProperty *prop;
3001 MPLIST_DO (action_list, action_list)
3003 MPlist *action = regularize_action (action_list, ic_info);
3009 name = MPLIST_SYMBOL (action);
3010 args = MPLIST_NEXT (action);
3012 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
3013 if (name == Minsert)
3015 if (MPLIST_SYMBOL_P (args))
3017 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3018 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3021 if (MPLIST_MTEXT_P (args))
3022 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3023 else /* MPLIST_INTEGER_P (args)) */
3024 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3026 else if (name == M_candidates)
3028 MPlist *plist = get_candidate_list (ic_info, args);
3034 if (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist))
3036 M17N_OBJECT_UNREF (plist);
3039 if (MPLIST_MTEXT_P (plist))
3041 preedit_insert (ic, ic->cursor_pos, NULL,
3042 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3047 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3049 preedit_insert (ic, ic->cursor_pos, mt, 0);
3050 len = mtext_nchars (mt);
3052 pl = mplist_copy (plist);
3053 M17N_OBJECT_UNREF (plist);
3054 mtext_put_prop (ic->preedit,
3055 ic->cursor_pos - len, ic->cursor_pos,
3056 Mcandidate_list, pl);
3057 M17N_OBJECT_UNREF (pl);
3058 mtext_put_prop (ic->preedit,
3059 ic->cursor_pos - len, ic->cursor_pos,
3060 Mcandidate_index, (void *) 0);
3062 else if (name == Mselect)
3065 int code, idx, gindex;
3066 int pos = ic->cursor_pos;
3068 int idx_decided = 0;
3071 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3074 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3075 group = find_candidates_group (mtext_property_value (prop), idx,
3076 &start, &end, &gindex);
3077 if (MPLIST_SYMBOL_P (args))
3079 code = marker_code (MPLIST_SYMBOL (args), 0);
3082 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3083 if (! MPLIST_INTEGER_P (args))
3085 idx = start + MPLIST_INTEGER (args);
3086 if (idx < start || idx >= end)
3094 if (code != '[' && code != ']')
3099 ? new_index (NULL, ic->candidate_index - start,
3100 end - start - 1, MPLIST_SYMBOL (args),
3102 : MPLIST_INTEGER (args)));
3105 find_candidates_group (mtext_property_value (prop), -1,
3110 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3115 int ingroup_index = idx - start;
3118 group = mtext_property_value (prop);
3119 len = mplist_length (group);
3132 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3133 idx += (MPLIST_MTEXT_P (group)
3134 ? mtext_nchars (MPLIST_MTEXT (group))
3135 : mplist_length (MPLIST_PLIST (group)));
3136 len = (MPLIST_MTEXT_P (group)
3137 ? mtext_nchars (MPLIST_MTEXT (group))
3138 : mplist_length (MPLIST_PLIST (group)));
3139 if (ingroup_index >= len)
3140 ingroup_index = len - 1;
3141 idx += ingroup_index;
3143 update_candidate (ic, prop, idx);
3144 MDEBUG_PRINT1 ("(%d)", idx);
3146 else if (name == Mshow)
3147 ic->candidate_show = 1;
3148 else if (name == Mhide)
3149 ic->candidate_show = 0;
3150 else if (name == Mdelete)
3152 int len = mtext_nchars (ic->preedit);
3156 if (MPLIST_SYMBOL_P (args)
3157 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3159 to = ic->cursor_pos + pos;
3162 delete_surrounding_text (ic, to);
3167 delete_surrounding_text (ic, to - len);
3173 to = (MPLIST_SYMBOL_P (args)
3174 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3176 : MPLIST_INTEGER (args));
3181 pos = to - ic->cursor_pos;
3183 MDEBUG_PRINT1 ("(%d)", pos);
3184 if (to < ic->cursor_pos)
3185 preedit_delete (ic, to, ic->cursor_pos);
3186 else if (to > ic->cursor_pos)
3187 preedit_delete (ic, ic->cursor_pos, to);
3189 else if (name == Mmove)
3191 int len = mtext_nchars (ic->preedit);
3193 = (MPLIST_SYMBOL_P (args)
3194 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3196 : MPLIST_INTEGER (args));
3202 if (pos != ic->cursor_pos)
3204 ic->cursor_pos = pos;
3205 ic->preedit_changed = 1;
3207 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3209 else if (name == Mmark)
3211 int code = marker_code (MPLIST_SYMBOL (args), 0);
3215 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3216 (void *) ic->cursor_pos);
3217 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3220 else if (name == Mpushback)
3222 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3226 if (MPLIST_SYMBOL_P (args))
3228 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3229 if (MPLIST_INTEGER_P (args))
3230 num = MPLIST_INTEGER (args);
3235 num = MPLIST_INTEGER (args);
3238 ic_info->key_head -= num;
3240 ic_info->key_head = 0;
3242 ic_info->key_head = - num;
3243 if (ic_info->key_head > ic_info->used)
3244 ic_info->key_head = ic_info->used;
3246 else if (MPLIST_MTEXT_P (args))
3248 MText *mt = MPLIST_MTEXT (args);
3249 int i, len = mtext_nchars (mt);
3252 ic_info->key_head--;
3253 for (i = 0; i < len; i++)
3255 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3256 if (ic_info->key_head + i < ic_info->used)
3257 ic_info->keys[ic_info->key_head + i] = key;
3259 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3264 MPlist *plist = MPLIST_PLIST (args), *pl;
3268 ic_info->key_head--;
3270 MPLIST_DO (pl, plist)
3272 key = MPLIST_SYMBOL (pl);
3273 if (ic_info->key_head < ic_info->used)
3274 ic_info->keys[ic_info->key_head + i] = key;
3276 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3281 else if (name == Mpop)
3283 if (ic_info->key_head < ic_info->used)
3284 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3286 else if (name == Mcall)
3288 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3289 MIMExternalFunc func = NULL;
3290 MSymbol module, func_name;
3291 MPlist *func_args, *val;
3294 module = MPLIST_SYMBOL (args);
3295 args = MPLIST_NEXT (args);
3296 func_name = MPLIST_SYMBOL (args);
3298 if (im_info->externals)
3300 MIMExternalModule *external
3301 = (MIMExternalModule *) mplist_get (im_info->externals,
3304 func = ((MIMExternalFunc)
3305 mplist_get_func (external->func_list, func_name));
3309 func_args = mplist ();
3310 mplist_add (func_args, Mt, ic);
3311 MPLIST_DO (args, MPLIST_NEXT (args))
3315 if (MPLIST_KEY (args) == Msymbol
3316 && MPLIST_KEY (args) != Mnil
3317 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3319 code = new_index (ic, ic->cursor_pos,
3320 mtext_nchars (ic->preedit),
3321 MPLIST_SYMBOL (args), ic->preedit);
3322 mplist_add (func_args, Minteger, (void *) code);
3325 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3327 val = (func) (func_args);
3328 M17N_OBJECT_UNREF (func_args);
3329 if (val && ! MPLIST_TAIL_P (val))
3330 ret = take_action_list (ic, val);
3331 M17N_OBJECT_UNREF (val);
3335 else if (name == Mshift)
3337 shift_state (ic, MPLIST_SYMBOL (args));
3339 else if (name == Mundo)
3341 int intarg = (MPLIST_TAIL_P (args)
3343 : integer_value (ic, args, 0));
3345 mtext_reset (ic->preedit);
3346 mtext_reset (ic_info->preedit_saved);
3347 mtext_reset (ic->produced);
3348 M17N_OBJECT_UNREF (ic_info->vars);
3349 ic_info->vars = mplist_copy (ic_info->vars_saved);
3350 ic->cursor_pos = ic_info->state_pos = 0;
3351 ic_info->state_key_head = ic_info->key_head
3352 = ic_info->commit_key_head = 0;
3354 shift_state (ic, Mnil);
3357 if (MPLIST_TAIL_P (args))
3362 ic_info->used += intarg;
3365 ic_info->used = intarg;
3368 else if (name == Mset || name == Madd || name == Msub
3369 || name == Mmul || name == Mdiv)
3371 MSymbol sym = MPLIST_SYMBOL (args);
3372 MPlist *value = resolve_variable (ic_info, sym);
3376 val1 = MPLIST_INTEGER (value);
3377 args = MPLIST_NEXT (args);
3378 val2 = resolve_expression (ic, args);
3380 val1 = val2, op = "=";
3381 else if (name == Madd)
3382 val1 += val2, op = "+=";
3383 else if (name == Msub)
3384 val1 -= val2, op = "-=";
3385 else if (name == Mmul)
3386 val1 *= val2, op = "*=";
3388 val1 /= val2, op = "/=";
3389 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3390 MSYMBOL_NAME (sym), op, val1, val1);
3391 mplist_set (value, Minteger, (void *) val1);
3393 else if (name == Mequal || name == Mless || name == Mgreater
3394 || name == Mless_equal || name == Mgreater_equal)
3397 MPlist *actions1, *actions2;
3400 val1 = resolve_expression (ic, args);
3401 args = MPLIST_NEXT (args);
3402 val2 = resolve_expression (ic, args);
3403 args = MPLIST_NEXT (args);
3404 actions1 = MPLIST_PLIST (args);
3405 args = MPLIST_NEXT (args);
3406 if (MPLIST_TAIL_P (args))
3409 actions2 = MPLIST_PLIST (args);
3410 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3411 if (name == Mequal ? val1 == val2
3412 : name == Mless ? val1 < val2
3413 : name == Mgreater ? val1 > val2
3414 : name == Mless_equal ? val1 <= val2
3417 MDEBUG_PRINT ("ok");
3418 ret = take_action_list (ic, actions1);
3422 MDEBUG_PRINT ("no");
3424 ret = take_action_list (ic, actions2);
3429 else if (name == Mcond)
3433 MPLIST_DO (args, args)
3438 if (! MPLIST_PLIST (args))
3440 cond = MPLIST_PLIST (args);
3441 if (resolve_expression (ic, cond) != 0)
3443 MDEBUG_PRINT1 ("(%dth)", idx);
3444 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3450 else if (name == Mcommit)
3452 preedit_commit (ic, 0);
3454 else if (name == Munhandle)
3456 preedit_commit (ic, 0);
3461 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3465 && (actions = mplist_get (im_info->macros, name)))
3467 if (take_action_list (ic, actions) < 0)
3473 if (ic->candidate_list)
3475 M17N_OBJECT_UNREF (ic->candidate_list);
3476 ic->candidate_list = NULL;
3478 if (ic->cursor_pos > 0
3479 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3482 ic->candidate_list = mtext_property_value (prop);
3483 M17N_OBJECT_REF (ic->candidate_list);
3485 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3487 ic->candidate_from = mtext_property_start (prop);
3488 ic->candidate_to = mtext_property_end (prop);
3491 if (candidate_list != ic->candidate_list)
3492 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3493 if (candidate_index != ic->candidate_index)
3494 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3495 if (candidate_show != ic->candidate_show)
3496 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3501 /* Handle the input key KEY in the current state and map specified in
3502 the input context IC. If KEY is handled correctly, return 0.
3503 Otherwise, return -1. */
3506 handle_key (MInputContext *ic)
3508 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3509 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3510 MIMMap *map = ic_info->map;
3511 MIMMap *submap = NULL;
3512 MSymbol key = ic_info->keys[ic_info->key_head];
3513 MSymbol alias = Mnil;
3516 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3517 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3521 submap = mplist_get (map->submaps, key);
3524 && (alias = msymbol_get (alias, M_key_alias))
3526 submap = mplist_get (map->submaps, alias);
3531 if (! alias || alias == key)
3532 MDEBUG_PRINT (" submap-found");
3534 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3535 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3536 ic->preedit_changed = 1;
3537 ic->cursor_pos = ic_info->state_pos;
3538 ic_info->key_head++;
3539 ic_info->map = map = submap;
3540 if (map->map_actions)
3542 MDEBUG_PRINT (" map-actions:");
3543 if (take_action_list (ic, map->map_actions) < 0)
3545 MDEBUG_PRINT ("\n");
3549 else if (map->submaps)
3551 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3553 MSymbol key = ic_info->keys[i];
3554 char *name = msymbol_name (key);
3556 if (! name[0] || ! name[1])
3557 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3561 /* If this is the terminal map or we have shifted to another
3562 state, perform branch actions (if any). */
3563 if (! map->submaps || map != ic_info->map)
3565 if (map->branch_actions)
3567 MDEBUG_PRINT (" branch-actions:");
3568 if (take_action_list (ic, map->branch_actions) < 0)
3570 MDEBUG_PRINT ("\n");
3574 /* If MAP is still not the root map, shift to the current
3576 if (ic_info->map != ic_info->state->map)
3577 shift_state (ic, ic_info->state->name);
3582 /* MAP can not handle KEY. */
3584 /* Perform branch actions if any. */
3585 if (map->branch_actions)
3587 MDEBUG_PRINT (" branch-actions:");
3588 if (take_action_list (ic, map->branch_actions) < 0)
3590 MDEBUG_PRINT ("\n");
3595 if (map == ic_info->map)
3597 /* The above branch actions didn't change the state. */
3599 /* If MAP is the root map of the initial state, and there
3600 still exist an unhandled key, it means that the current
3601 input method can not handle it. */
3602 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3603 && ic_info->key_head < ic_info->used)
3605 MDEBUG_PRINT (" unhandled\n");
3609 if (map != ic_info->state->map)
3611 /* MAP is not the root map. Shift to the root map of the
3613 shift_state (ic, ic_info->state->name);
3615 else if (! map->branch_actions)
3617 /* MAP is the root map without any default branch
3618 actions. Shift to the initial state. */
3619 shift_state (ic, Mnil);
3623 MDEBUG_PRINT ("\n");
3627 /* Initialize IC->ic_info. */
3630 init_ic_info (MInputContext *ic)
3632 MInputMethodInfo *im_info = ic->im->info;
3633 MInputContextInfo *ic_info = ic->info;
3636 MLIST_INIT1 (ic_info, keys, 8);;
3638 ic_info->markers = mplist ();
3640 ic_info->vars = mplist ();
3641 if (im_info->configured_vars)
3642 MPLIST_DO (plist, im_info->configured_vars)
3644 MPlist *pl = MPLIST_PLIST (plist);
3645 MSymbol name = MPLIST_SYMBOL (pl);
3647 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3648 if (MPLIST_KEY (pl) != Mt)
3650 MPlist *p = mplist ();
3652 mplist_push (ic_info->vars, Mplist, p);
3653 M17N_OBJECT_UNREF (p);
3654 mplist_add (p, Msymbol, name);
3655 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3658 ic_info->vars_saved = mplist_copy (ic_info->vars);
3660 if (im_info->externals)
3662 MPlist *func_args = mplist (), *plist;
3664 mplist_add (func_args, Mt, ic);
3665 MPLIST_DO (plist, im_info->externals)
3667 MIMExternalModule *external = MPLIST_VAL (plist);
3668 MIMExternalFunc func
3669 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3674 M17N_OBJECT_UNREF (func_args);
3677 ic_info->preedit_saved = mtext ();
3678 ic_info->tick = im_info->tick;
3681 /* Finalize IC->ic_info. */
3684 fini_ic_info (MInputContext *ic)
3686 MInputMethodInfo *im_info = ic->im->info;
3687 MInputContextInfo *ic_info = ic->info;
3689 if (im_info->externals)
3691 MPlist *func_args = mplist (), *plist;
3693 mplist_add (func_args, Mt, ic);
3694 MPLIST_DO (plist, im_info->externals)
3696 MIMExternalModule *external = MPLIST_VAL (plist);
3697 MIMExternalFunc func
3698 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3703 M17N_OBJECT_UNREF (func_args);
3706 MLIST_FREE1 (ic_info, keys);
3707 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3708 M17N_OBJECT_UNREF (ic_info->markers);
3709 M17N_OBJECT_UNREF (ic_info->vars);
3710 M17N_OBJECT_UNREF (ic_info->vars_saved);
3711 M17N_OBJECT_UNREF (ic_info->preceding_text);
3712 M17N_OBJECT_UNREF (ic_info->following_text);
3714 memset (ic_info, 0, sizeof (MInputContextInfo));
3718 re_init_ic (MInputContext *ic, int reload)
3720 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3721 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3722 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3724 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3725 preedit_changed = mtext_nchars (ic->preedit) > 0;
3726 cursor_pos_changed = ic->cursor_pos > 0;
3727 candidates_changed = 0;
3728 if (ic->candidate_list)
3730 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3731 M17N_OBJECT_UNREF (ic->candidate_list);
3732 ic->candidate_list = NULL;
3734 if (ic->candidate_show)
3736 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3737 ic->candidate_show = 0;
3739 if (ic->candidate_index > 0)
3741 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3742 ic->candidate_index = 0;
3743 ic->candidate_from = ic->candidate_to = 0;
3745 if (mtext_nchars (ic->produced) > 0)
3746 mtext_reset (ic->produced);
3747 if (mtext_nchars (ic->preedit) > 0)
3748 mtext_reset (ic->preedit);
3750 M17N_OBJECT_UNREF (ic->plist);
3751 ic->plist = mplist ();
3755 reload_im_info (im_info);
3756 if (! im_info->states)
3758 struct MIMState *state;
3760 M17N_OBJECT (state, free_state, MERROR_IM);
3761 state->name = msymbol ("init");
3762 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3763 MSTRUCT_CALLOC (state->map, MERROR_IM);
3764 im_info->states = mplist ();
3765 mplist_add (im_info->states, state->name, state);
3768 shift_state (ic, Mnil);
3770 ic->status_changed = status_changed;
3771 ic->preedit_changed = preedit_changed;
3772 ic->cursor_pos_changed = cursor_pos_changed;
3773 ic->candidates_changed = candidates_changed;
3777 reset_ic (MInputContext *ic, MSymbol ignore)
3779 MDEBUG_PRINT ("\n [IM] reset\n");
3784 open_im (MInputMethod *im)
3786 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3788 if (! im_info || ! im_info->states)
3789 MERROR (MERROR_IM, -1);
3796 close_im (MInputMethod *im)
3802 create_ic (MInputContext *ic)
3804 MInputContextInfo *ic_info;
3806 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3809 shift_state (ic, Mnil);
3814 destroy_ic (MInputContext *ic)
3821 check_reload (MInputContext *ic, MSymbol key)
3823 MInputMethodInfo *im_info = ic->im->info;
3824 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3828 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3832 MPLIST_DO (plist, plist)
3834 MSymbol this_key, alias;
3836 if (MPLIST_MTEXT_P (plist))
3838 MText *mt = MPLIST_MTEXT (plist);
3839 int c = mtext_ref_char (mt, 0);
3843 this_key = one_char_symbol[c];
3847 MPlist *pl = MPLIST_PLIST (plist);
3849 this_key = MPLIST_SYMBOL (pl);
3853 && (alias = msymbol_get (alias, M_key_alias))
3854 && alias != this_key);
3858 if (MPLIST_TAIL_P (plist))
3861 MDEBUG_PRINT ("\n [IM] reload");
3867 /** Handle the input key KEY in the current state and map of IC->info.
3868 If KEY is handled but no text is produced, return 0, otherwise
3874 filter (MInputContext *ic, MSymbol key, void *arg)
3876 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3877 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3880 if (check_reload (ic, key))
3883 if (! ic_info->state)
3885 ic_info->key_unhandled = 1;
3888 mtext_reset (ic->produced);
3889 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3890 M17N_OBJECT_UNREF (ic_info->preceding_text);
3891 M17N_OBJECT_UNREF (ic_info->following_text);
3892 ic_info->preceding_text = ic_info->following_text = NULL;
3893 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3894 ic_info->key_unhandled = 0;
3897 if (handle_key (ic) < 0)
3899 /* KEY was not handled. Delete it from the current key sequence. */
3900 if (ic_info->used > 0)
3902 memmove (ic_info->keys, ic_info->keys + 1,
3903 sizeof (int) * (ic_info->used - 1));
3905 if (ic_info->state_key_head > 0)
3906 ic_info->state_key_head--;
3907 if (ic_info->commit_key_head > 0)
3908 ic_info->commit_key_head--;
3910 /* This forces returning 1. */
3911 ic_info->key_unhandled = 1;
3917 reset_ic (ic, Mnil);
3918 ic_info->key_unhandled = 1;
3921 /* Break the loop if all keys were handled. */
3922 } while (ic_info->key_head < ic_info->used);
3924 /* If the current map is the root of the initial state, we should
3925 produce any preedit text in ic->produced. */
3926 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3927 preedit_commit (ic, 1);
3929 if (mtext_nchars (ic->produced) > 0)
3933 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3934 MSYMBOL_NAME (ic_info->state->name));
3935 for (i = 0; i < mtext_nchars (ic->produced); i++)
3936 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3940 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3941 Mlanguage, ic->im->language);
3943 if (ic_info->commit_key_head > 0)
3945 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3946 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3947 ic_info->used -= ic_info->commit_key_head;
3948 ic_info->key_head -= ic_info->commit_key_head;
3949 ic_info->state_key_head -= ic_info->commit_key_head;
3950 ic_info->commit_key_head = 0;
3952 if (ic_info->key_unhandled)
3955 ic_info->key_head = ic_info->state_key_head
3956 = ic_info->commit_key_head = 0;
3959 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3963 /** Return 1 if the last event or key was not handled, otherwise
3966 There is no need of looking up because ic->produced should already
3967 contain the produced text (if any).
3972 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3974 mtext_cat (mt, ic->produced);
3975 mtext_reset (ic->produced);
3976 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3980 /* Input method command handler. */
3982 /* List of all (global and local) commands.
3983 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3984 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3985 Global commands are stored as (t (t COMMAND ...)) */
3988 /* Input method variable handler. */
3991 /* Support functions for mdebug_dump_im. */
3994 dump_im_map (MPlist *map_list, int indent)
3997 MSymbol key = MPLIST_KEY (map_list);
3998 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
4000 prefix = (char *) alloca (indent + 1);
4001 memset (prefix, 32, indent);
4002 prefix[indent] = '\0';
4004 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
4005 if (map->map_actions)
4006 mdebug_dump_plist (map->map_actions, indent + 2);
4009 MPLIST_DO (map_list, map->submaps)
4011 fprintf (stderr, "\n%s ", prefix);
4012 dump_im_map (map_list, indent + 2);
4015 if (map->branch_actions)
4017 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
4018 mdebug_dump_plist (map->branch_actions, indent + 4);
4019 fprintf (stderr, ")");
4021 fprintf (stderr, ")");
4026 dump_im_state (MIMState *state, int indent)
4031 prefix = (char *) alloca (indent + 1);
4032 memset (prefix, 32, indent);
4033 prefix[indent] = '\0';
4035 fprintf (stderr, "(%s", msymbol_name (state->name));
4036 if (state->map->submaps)
4038 MPLIST_DO (map_list, state->map->submaps)
4040 fprintf (stderr, "\n%s ", prefix);
4041 dump_im_map (map_list, indent + 2);
4044 fprintf (stderr, ")");
4052 Minput_driver = msymbol ("input-driver");
4054 Minput_preedit_start = msymbol ("input-preedit-start");
4055 Minput_preedit_done = msymbol ("input-preedit-done");
4056 Minput_preedit_draw = msymbol ("input-preedit-draw");
4057 Minput_status_start = msymbol ("input-status-start");
4058 Minput_status_done = msymbol ("input-status-done");
4059 Minput_status_draw = msymbol ("input-status-draw");
4060 Minput_candidates_start = msymbol ("input-candidates-start");
4061 Minput_candidates_done = msymbol ("input-candidates-done");
4062 Minput_candidates_draw = msymbol ("input-candidates-draw");
4063 Minput_set_spot = msymbol ("input-set-spot");
4064 Minput_focus_move = msymbol ("input-focus-move");
4065 Minput_focus_in = msymbol ("input-focus-in");
4066 Minput_focus_out = msymbol ("input-focus-out");
4067 Minput_toggle = msymbol ("input-toggle");
4068 Minput_reset = msymbol ("input-reset");
4069 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4070 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4071 Mcustomized = msymbol ("customized");
4072 Mconfigured = msymbol ("configured");
4073 Minherited = msymbol ("inherited");
4075 minput_default_driver.open_im = open_im;
4076 minput_default_driver.close_im = close_im;
4077 minput_default_driver.create_ic = create_ic;
4078 minput_default_driver.destroy_ic = destroy_ic;
4079 minput_default_driver.filter = filter;
4080 minput_default_driver.lookup = lookup;
4081 minput_default_driver.callback_list = mplist ();
4082 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4083 M17N_FUNC (reset_ic));
4084 minput_driver = &minput_default_driver;
4086 fully_initialized = 0;
4093 if (fully_initialized)
4095 free_im_list (im_info_list);
4097 free_im_list (im_custom_list);
4099 free_im_list (im_config_list);
4100 M17N_OBJECT_UNREF (load_im_info_keys);
4103 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4104 M17N_OBJECT_UNREF (minput_driver->callback_list);
4109 minput__char_to_key (int c)
4111 if (c < 0 || c >= 0x100)
4114 return one_char_symbol[c];
4118 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4123 /*** @addtogroup m17nInputMethod */
4128 @brief Symbol whose name is "input-method".
4131 @brief "input-method" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
4133 MSymbol Minput_method;
4136 @name Variables: Predefined symbols for callback commands. */
4138 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4141 These are the predefined symbols that are used as the @c COMMAND
4142 argument of callback functions of an input method driver (see
4143 #MInputDriver::callback_list).
4145 Most of them do not require extra argument nor return any value;
4146 exceptions are these:
4148 @b Minput_get_surrounding_text: When a callback function assigned for
4149 this command is called, the first element of #MInputContext::plist
4150 has key #Minteger and the value specifies which portion of the
4151 surrounding text should be retrieved. If the value is positive,
4152 it specifies the number of characters following the current cursor
4153 position. If the value is negative, the absolute value specifies
4154 the number of characters preceding the current cursor position.
4155 If the value is zero, it means that the caller just wants to know
4156 if the surrounding text is currently supported or not.
4158 If the surrounding text is currently supported, the callback
4159 function must set the key of this element to #Mtext and the value
4160 to the retrieved M-text. The length of the M-text may be shorter
4161 than the requested number of characters, if the available text is
4162 not that long. The length can be zero in the worst case. Or, the
4163 length may be longer if an application thinks it is more efficient
4164 to return that length.
4166 If the surrounding text is not currently supported, the callback
4167 function should return without changing the first element of
4168 #MInputContext::plist.
4170 @b Minput_delete_surrounding_text: When a callback function assigned
4171 for this command is called, the first element of
4172 #MInputContext::plist has key #Minteger and the value specifies
4173 which portion of the surrounding text should be deleted in the
4174 same way as the case of Minput_get_surrounding_text. The callback
4175 function must delete the specified text. It should not alter
4176 #MInputContext::plist. */
4178 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4179 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4181 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4183 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4184 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4185 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4186 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4187 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4188 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4189 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4191 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4192 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4193 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4194 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4195 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4197 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4198 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4200 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4201 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4202 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4203 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4204 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4205 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4206 MSymbol Minput_preedit_start;
4207 MSymbol Minput_preedit_done;
4208 MSymbol Minput_preedit_draw;
4209 MSymbol Minput_status_start;
4210 MSymbol Minput_status_done;
4211 MSymbol Minput_status_draw;
4212 MSymbol Minput_candidates_start;
4213 MSymbol Minput_candidates_done;
4214 MSymbol Minput_candidates_draw;
4215 MSymbol Minput_set_spot;
4216 MSymbol Minput_toggle;
4217 MSymbol Minput_reset;
4218 MSymbol Minput_get_surrounding_text;
4219 MSymbol Minput_delete_surrounding_text;
4225 @name Variables: Predefined symbols for special input events.
4227 These are the predefined symbols that are used as the @c KEY
4228 argument of minput_filter (). */
4230 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4232 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4237 MSymbol Minput_focus_out;
4238 MSymbol Minput_focus_in;
4239 MSymbol Minput_focus_move;
4245 @name Variables: Predefined symbols used in input method information. */
4247 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4251 These are the predefined symbols describing status of input method
4252 command and variable, and are used in a return value of
4253 minput_get_command () and minput_get_variable (). */
4255 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4256 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4258 MSymbol Mcustomized;
4259 MSymbol Mconfigured;
4265 @brief The default driver for internal input methods.
4267 The variable #minput_default_driver is the default driver for
4268 internal input methods.
4270 The member MInputDriver::open_im () searches the m17n database for
4271 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4272 $NAME\> and loads it.
4274 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4275 programmers responsibility to set it to a plist of proper callback
4276 functions. Otherwise, no feedback information (e.g. preedit text)
4277 can be shown to users.
4279 The macro M17N_INIT () sets the variable #minput_driver to the
4280 pointer to this driver so that all internal input methods use it.
4282 Therefore, unless @c minput_driver is set differently, the driver
4283 dependent arguments $ARG of the functions whose name begins with
4284 "minput_" are all ignored. */
4286 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4288 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4290 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4291 \< #Minput_method, $LANGUAGE, $NAME\>
4292 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4294 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4295 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4296 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4297 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4299 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4300 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4302 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4303 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4305 MInputDriver minput_default_driver;
4309 @brief The driver for internal input methods.
4311 The variable #minput_driver is a pointer to the input method
4312 driver that is used by internal input methods. The macro
4313 M17N_INIT () initializes it to a pointer to #minput_default_driver
4314 if <m17n<EM></EM>.h> is included. */
4316 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4318 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4319 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4320 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4321 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4323 MInputDriver *minput_driver;
4327 The variable #Minput_driver is a symbol for a foreign input method.
4328 See @ref foreign-input-method "foreign input method" for the detail. */
4329 MSymbol Minput_driver;
4344 @brief Open an input method.
4346 The minput_open_im () function opens an input method whose
4347 language and name match $LANGUAGE and $NAME, and returns a pointer
4348 to the input method object newly allocated.
4350 This function at first decides a driver for the input method as
4353 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4354 #minput_driver is used.
4356 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4357 driver pointed to by the property value is used to open the input
4358 method. If $NAME has no such a property, @c NULL is returned.
4360 Then, the member MInputDriver::open_im () of the driver is
4363 $ARG is set in the member @c arg of the structure MInputMethod so
4364 that the driver can refer to it. */
4366 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4368 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4369 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4371 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4373 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4374 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4376 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4377 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4378 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4380 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4382 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4384 @latexonly \IPAlabel{minput_open} @endlatexonly
4389 minput_open_im (MSymbol language, MSymbol name, void *arg)
4392 MInputDriver *driver;
4396 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4397 msymbol_name (language), msymbol_name (name));
4401 MERROR (MERROR_IM, NULL);
4402 driver = minput_driver;
4406 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4408 MERROR (MERROR_IM, NULL);
4411 MSTRUCT_CALLOC (im, MERROR_IM);
4412 im->language = language;
4415 im->driver = *driver;
4416 if ((*im->driver.open_im) (im) < 0)
4418 MDEBUG_PRINT (" failed\n");
4422 MDEBUG_PRINT (" ok\n");
4429 @brief Close an input method.
4431 The minput_close_im () function closes the input method $IM, which
4432 must have been created by minput_open_im (). */
4435 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4437 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4438 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4441 minput_close_im (MInputMethod *im)
4443 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4444 msymbol_name (im->name), msymbol_name (im->language));
4445 (*im->driver.close_im) (im);
4447 MDEBUG_PRINT (" done\n");
4453 @brief Create an input context.
4455 The minput_create_ic () function creates an input context object
4456 associated with input method $IM, and calls callback functions
4457 corresponding to @b Minput_preedit_start, @b Minput_status_start, and
4458 @b Minput_status_draw in this order.
4461 If an input context is successfully created, minput_create_ic ()
4462 returns a pointer to it. Otherwise it returns @c NULL. */
4465 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4467 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4468 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4469 @b Minput_preedit_start, @b Minput_status_start, @b Minput_status_draw
4470 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4473 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4474 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4478 minput_create_ic (MInputMethod *im, void *arg)
4482 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4483 msymbol_name (im->name), msymbol_name (im->language));
4484 MSTRUCT_CALLOC (ic, MERROR_IM);
4487 ic->preedit = mtext ();
4488 ic->candidate_list = NULL;
4489 ic->produced = mtext ();
4490 ic->spot.x = ic->spot.y = 0;
4492 ic->plist = mplist ();
4493 if ((*im->driver.create_ic) (ic) < 0)
4495 MDEBUG_PRINT (" failed\n");
4496 M17N_OBJECT_UNREF (ic->preedit);
4497 M17N_OBJECT_UNREF (ic->produced);
4498 M17N_OBJECT_UNREF (ic->plist);
4503 if (im->driver.callback_list)
4505 minput_callback (ic, Minput_preedit_start);
4506 minput_callback (ic, Minput_status_start);
4507 minput_callback (ic, Minput_status_draw);
4510 MDEBUG_PRINT (" ok\n");
4517 @brief Destroy an input context.
4519 The minput_destroy_ic () function destroys the input context $IC,
4520 which must have been created by minput_create_ic (). It calls
4521 callback functions corresponding to @b Minput_preedit_done,
4522 @b Minput_status_done, and @b Minput_candidates_done in this order. */
4525 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4527 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4528 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4529 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4530 @b Minput_preedit_done, @b Minput_status_done, @b Minput_candidates_done
4531 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4535 minput_destroy_ic (MInputContext *ic)
4537 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4538 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4539 if (ic->im->driver.callback_list)
4541 minput_callback (ic, Minput_preedit_done);
4542 minput_callback (ic, Minput_status_done);
4543 minput_callback (ic, Minput_candidates_done);
4545 (*ic->im->driver.destroy_ic) (ic);
4546 M17N_OBJECT_UNREF (ic->preedit);
4547 M17N_OBJECT_UNREF (ic->produced);
4548 M17N_OBJECT_UNREF (ic->plist);
4549 MDEBUG_PRINT (" done\n");
4556 @brief Filter an input key.
4558 The minput_filter () function filters input key $KEY according to
4559 input context $IC, and calls callback functions corresponding to
4560 @b Minput_preedit_draw, @b Minput_status_draw, and
4561 @b Minput_candidates_draw if the preedit text, the status, and the
4562 current candidate are changed respectively.
4564 To make the input method commit the current preedit text (if any)
4565 and shift to the initial state, call this function with #Mnil as
4568 To inform the input method about the focus-out event, call this
4569 function with @b Minput_focus_out as $KEY.
4571 To inform the input method about the focus-in event, call this
4572 function with @b Minput_focus_in as $KEY.
4574 To inform the input method about the focus-move event (i.e. input
4575 spot change within the same input context), call this function
4576 with @b Minput_focus_move as $KEY.
4579 If $KEY is filtered out, this function returns 1. In that case,
4580 the caller should discard the key. Otherwise, it returns 0, and
4581 the caller should handle the key, for instance, by calling the
4582 function minput_lookup () with the same key. */
4585 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4587 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4588 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4589 @b Minput_preedit_draw, @b Minput_status_draw,
4590 @b Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4593 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4594 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4595 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4596 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4598 @latexonly \IPAlabel{minput_filter} @endlatexonly
4602 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4609 if (ic->im->driver.callback_list
4610 && mtext_nchars (ic->preedit) > 0)
4611 minput_callback (ic, Minput_preedit_draw);
4613 ret = (*ic->im->driver.filter) (ic, key, arg);
4615 if (ic->im->driver.callback_list)
4617 if (ic->preedit_changed)
4618 minput_callback (ic, Minput_preedit_draw);
4619 if (ic->status_changed)
4620 minput_callback (ic, Minput_status_draw);
4621 if (ic->candidates_changed)
4622 minput_callback (ic, Minput_candidates_draw);
4631 @brief Look up a text produced in the input context.
4633 The minput_lookup () function looks up a text in the input context
4634 $IC. $KEY must be identical to the one that was used in the previous call of
4637 If a text was produced by the input method, it is concatenated
4640 This function calls #MInputDriver::lookup .
4643 If $KEY was correctly handled by the input method, this function
4644 returns 0. Otherwise, it returns -1, even though some text
4645 might be produced in $MT. */
4648 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4650 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4651 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4653 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4656 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4659 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4660 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4661 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4663 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4666 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4668 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4673 @brief Set the spot of the input context.
4675 The minput_set_spot () function sets the spot of input context $IC
4676 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4677 The semantics of these values depends on the input method driver.
4679 For instance, a driver designed to work in a CUI environment may
4680 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4681 $DESCENT . A driver designed to work in a window system may
4682 interpret $X and $Y as the pixel offsets relative to the origin of the
4683 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4684 descent pixels of the line at ($X . $Y ).
4686 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4688 $MT and $POS are the M-text and the character position at the spot.
4689 $MT may be @c NULL, in which case, the input method cannot get
4690 information about the text around the spot. */
4693 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4695 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4696 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4697 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4699 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4700 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4701 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4702 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4703 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4704 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4706 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4708 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4709 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4713 minput_set_spot (MInputContext *ic, int x, int y,
4714 int ascent, int descent, int fontsize,
4719 ic->spot.ascent = ascent;
4720 ic->spot.descent = descent;
4721 ic->spot.fontsize = fontsize;
4724 if (ic->im->driver.callback_list)
4725 minput_callback (ic, Minput_set_spot);
4730 @brief Toggle input method.
4732 The minput_toggle () function toggles the input method associated
4733 with input context $IC. */
4735 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4737 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4738 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4742 minput_toggle (MInputContext *ic)
4744 if (ic->im->driver.callback_list)
4745 minput_callback (ic, Minput_toggle);
4746 ic->active = ! ic->active;
4752 @brief Reset an input context.
4754 The minput_reset_ic () function resets input context $IC by
4755 calling a callback function corresponding to @b Minput_reset. It
4756 resets the status of $IC to its initial one. As the
4757 current preedit text is deleted without commitment, if necessary,
4758 call minput_filter () with the arg @b key #Mnil to force the input
4759 method to commit the preedit in advance. */
4762 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4764 ´Ø¿ô minput_reset_ic () ¤Ï @b Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4765 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4766 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4767 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4768 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @b key #Mnil ¤Ç¸Æ¤ó¤Ç
4769 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4772 minput_reset_ic (MInputContext *ic)
4774 if (ic->im->driver.callback_list)
4775 minput_callback (ic, Minput_reset);
4781 @brief Get title and icon filename of an input method.
4783 The minput_get_title_icon () function returns a plist containing a
4784 title and icon filename (if any) of an input method specified by
4785 $LANGUAGE and $NAME.
4787 The first element of the plist has key #Mtext and the value is an
4788 M-text of the title for identifying the input method. The second
4789 element (if any) has key #Mtext and the value is an M-text of the
4790 icon image (absolute) filename for the same purpose.
4793 If there exists a specified input method and it defines an title,
4794 a plist is returned. Otherwise, NULL is returned. The caller
4795 must free the plist by m17n_object_unref (). */
4797 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4799 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4800 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4803 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4804 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4805 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4808 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4809 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4810 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4813 minput_get_title_icon (MSymbol language, MSymbol name)
4815 MInputMethodInfo *im_info;
4822 im_info = get_im_info (language, name, Mnil, Mtitle);
4823 if (! im_info || !im_info->title)
4825 mt = mtext_get_prop (im_info->title, 0, Mtext);
4827 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4830 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4833 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4834 (char *) MSYMBOL_NAME (name));
4835 file = mdatabase__find_file (buf);
4836 if (! file && language == Mt)
4838 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4839 file = mdatabase__find_file (buf);
4844 mplist_add (plist, Mtext, im_info->title);
4847 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4849 mplist_add (plist, Mtext, mt);
4850 M17N_OBJECT_UNREF (mt);
4858 @brief Get description text of an input method.
4860 The minput_get_description () function returns an M-text that
4861 describes the input method specified by $LANGUAGE and $NAME.
4864 If the specified input method has a description text, a pointer to
4865 #MText is returned. The caller has to free it by m17n_object_unref ().
4866 If the input method does not have a description text, @c NULL is
4869 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4871 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4872 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4875 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4876 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4877 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4878 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4881 minput_get_description (MSymbol language, MSymbol name)
4883 MInputMethodInfo *im_info;
4891 extra = language, language = Mt;
4893 im_info = get_im_info (language, name, extra, Mdescription);
4894 if (! im_info || ! im_info->description)
4896 M17N_OBJECT_REF (im_info->description);
4897 return im_info->description;
4903 @brief Get information about input method command(s).
4905 The minput_get_command () function returns information about
4906 the command $COMMAND of the input method specified by $LANGUAGE and
4907 $NAME. An input method command is a pseudo key event to which one
4908 or more actual input key sequences are assigned.
4910 There are two kinds of commands, global and local. A global
4911 command has a global definition, and the description and the key
4912 assignment may be inherited by a local command. Each input method
4913 defines a local command which has a local key assignment. It may
4914 also declare a local command that inherits the definition of a
4915 global command of the same name.
4917 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4918 information about a global command. Otherwise information about a
4919 local command is returned.
4921 If $COMMAND is #Mnil, information about all commands is returned.
4923 The return value is a @e well-formed plist (@ref m17nPlist) of this
4926 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4928 @c NAME is a symbol representing the command name.
4930 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4931 command has no description.
4933 @c STATUS is a symbol representing how the key assignment is decided.
4934 The value is #Mnil (the default key assignment), @b Mcustomized (the
4935 key assignment is customized by per-user customization file), or
4936 @b Mconfigured (the key assignment is set by the call of
4937 minput_config_command ()). For a local command only, it may also
4938 be @b Minherited (the key assignment is inherited from the
4939 corresponding global command).
4941 @c KEYSEQ is a plist of one or more symbols representing a key
4942 sequence assigned to the command. If there's no KEYSEQ, the
4943 command is currently disabled (i.e. no key sequence can trigger
4944 actions of the command).
4946 If $COMMAND is not #Mnil, the first element of the returned plist
4947 contains the information about $COMMAND.
4951 If the requested information was found, a pointer to a non-empty
4952 plist is returned. As the plist is kept in the library, the
4953 caller must not modify nor free it.
4955 Otherwise (the specified input method or the specified command
4956 does not exist), @c NULL is returned. */
4958 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4960 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4961 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4962 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4963 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4965 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4966 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4967 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4968 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4969 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4971 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4972 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4975 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4977 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4980 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4982 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4984 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4987 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4988 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, @b Mcustomized ¡Ê¥æ¡¼
4989 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4990 @b Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4991 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4992 @b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4995 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4996 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4997 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4998 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
5000 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
5001 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5005 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5006 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5009 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5014 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
5016 /* Return a description of the command COMMAND of the input method
5017 specified by LANGUAGE and NAME. */
5018 MPlist *cmd = minput_get_command (langauge, name, command);
5023 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
5024 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
5025 return (mplist_key (plist) == Mtext
5026 ? (MText *) mplist_value (plist)
5032 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5034 MInputMethodInfo *im_info;
5038 im_info = get_im_info (language, name, Mnil, Mcommand);
5040 || ! im_info->configured_cmds
5041 || MPLIST_TAIL_P (im_info->configured_cmds))
5043 if (command == Mnil)
5044 return im_info->configured_cmds;
5045 return mplist__assq (im_info->configured_cmds, command);
5051 @brief Configure the key sequence of an input method command.
5053 The minput_config_command () function assigns a list of key
5054 sequences $KEYSEQLIST to the command $COMMAND of the input method
5055 specified by $LANGUAGE and $NAME.
5057 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5058 sequences, and each key sequence must be a plist of symbols.
5060 If $KEYSEQLIST is an empty plist, any configuration and
5061 customization of the command are cancelled, and default key
5062 sequences become effective.
5064 If $KEYSEQLIST is NULL, the configuration of the command is
5065 canceled, and the original key sequences (what saved in per-user
5066 customization file, or the default one) become effective.
5068 In the latter two cases, $COMMAND can be #Mnil to make all the
5069 commands of the input method the target of the operation.
5071 If $NAME is #Mnil, this function configures the key assignment of a
5072 global command, not that of a specific input method.
5074 The configuration takes effect for input methods opened or
5075 re-opened later in the current session. In order to make the
5076 configuration take effect for the future session, it must be saved
5077 in a per-user customization file by the function
5078 minput_save_config ().
5081 If the operation was successful, this function returns 0,
5082 otherwise returns -1. The operation fails in these cases:
5084 <li>$KEYSEQLIST is not in a valid form.
5085 <li>$COMMAND is not available for the input method.
5086 <li>$LANGUAGE and $NAME do not specify an existing input method.
5090 minput_get_commands (), minput_save_config ().
5093 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5095 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5096 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5097 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5099 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5100 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5102 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5103 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5105 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5106 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5107 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5109 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5110 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5112 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5113 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5115 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5116 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5117 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5118 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5122 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5124 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5125 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5126 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5130 minput_get_commands (), minput_save_config ().
5134 /* Add "C-x u" to the "start" command of Unicode input method. */
5136 MSymbol start_command = msymbol ("start");
5137 MSymbol unicode = msymbol ("unicode");
5138 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5140 /* At first get the current key-sequence assignment. */
5141 cmd = minput_get_command (Mt, unicode, start_command);
5144 /* The input method does not have the command "start". Here
5145 should come some error handling code. */
5147 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5148 Extract the part (KEY-SEQUENCE ...). */
5149 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5150 /* Copy it because we should not modify it directly. */
5151 key_seq_list = mplist_copy (plist);
5153 key_seq = mplist ();
5154 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5155 mplist_add (key_seq, Msymbol, msymbol ("u"));
5156 mplist_add (key_seq_list, Mplist, key_seq);
5157 m17n_object_unref (key_seq);
5159 minput_config_command (Mt, unicode, start_command, key_seq_list);
5160 m17n_object_unref (key_seq_list);
5165 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5168 MInputMethodInfo *im_info, *config;
5173 im_info = get_im_info (language, name, Mnil, Mcommand);
5175 MERROR (MERROR_IM, -1);
5176 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5178 || ! mplist__assq (im_info->configured_cmds, command)))
5179 MERROR (MERROR_IM, -1);
5180 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5182 MPLIST_DO (plist, keyseqlist)
5183 if (! check_command_keyseq (plist))
5184 MERROR (MERROR_IM, -1);
5187 config = get_config_info (im_info);
5190 if (! im_config_list)
5191 im_config_list = mplist ();
5192 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5193 config->cmds = mplist ();
5194 config->vars = mplist ();
5197 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5198 /* Nothing to do. */
5201 if (command == Mnil)
5205 /* Cancal the configuration. */
5206 if (MPLIST_TAIL_P (config->cmds))
5208 mplist_set (config->cmds, Mnil, NULL);
5212 /* Cancal the customization. */
5213 MInputMethodInfo *custom = get_custom_info (im_info);
5215 if (MPLIST_TAIL_P (config->cmds)
5216 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5217 /* Nothing to do. */
5219 mplist_set (config->cmds, Mnil, NULL);
5220 MPLIST_DO (plist, custom->cmds)
5222 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5224 mplist_add (plist, Msymbol, command);
5225 mplist_push (config->cmds, Mplist, plist);
5226 M17N_OBJECT_UNREF (plist);
5232 plist = mplist__assq (config->cmds, command);
5235 /* Cancel the configuration. */
5238 mplist__pop_unref (plist);
5240 else if (MPLIST_TAIL_P (keyseqlist))
5242 /* Cancel the customization. */
5243 MInputMethodInfo *custom = get_custom_info (im_info);
5244 int no_custom = (! custom || ! custom->cmds
5245 || ! mplist__assq (custom->cmds, command));
5251 mplist_add (config->cmds, Mplist, plist);
5252 M17N_OBJECT_UNREF (plist);
5253 plist = mplist_add (plist, Msymbol, command);
5258 mplist__pop_unref (plist);
5261 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5262 plist = MPLIST_NEXT (plist);
5263 mplist_set (plist, Mnil, NULL);
5273 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5274 if (! MPLIST_TAIL_P (plist))
5275 mplist_set (plist, Mnil, NULL);
5280 mplist_add (config->cmds, Mplist, plist);
5281 M17N_OBJECT_UNREF (plist);
5282 plist = mplist_add (plist, Msymbol, command);
5283 plist = MPLIST_NEXT (plist);
5285 MPLIST_DO (keyseqlist, keyseqlist)
5287 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5288 plist = mplist_add (plist, Mplist, pl);
5289 M17N_OBJECT_UNREF (pl);
5293 config_all_commands (im_info);
5294 im_info->tick = time (NULL);
5301 @brief Get information about input method variable(s).
5303 The minput_get_variable () function returns information about
5304 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5305 An input method variable controls behavior of an input method.
5307 There are two kinds of variables, global and local. A global
5308 variable has a global definition, and the description and the value
5309 may be inherited by a local variable. Each input method defines a
5310 local variable which has local value. It may also declare a
5311 local variable that inherits definition of a global variable of
5314 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5315 variable is returned. Otherwise information about a local variable
5318 If $VARIABLE is #Mnil, information about all variables is
5321 The return value is a @e well-formed plist (@ref m17nPlist) of this
5324 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5326 @c NAME is a symbol representing the variable name.
5328 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5329 variable has no description.
5331 @c STATUS is a symbol representing how the value is decided. The
5332 value is #Mnil (the default value), @b Mcustomized (the value is
5333 customized by per-user customization file), or @b Mconfigured (the
5334 value is set by the call of minput_config_variable ()). For a
5335 local variable only, it may also be @b Minherited (the value is
5336 inherited from the corresponding global variable).
5338 @c VALUE is the initial value of the variable. If the key of this
5339 element is #Mt, the variable has no initial value. Otherwise, the
5340 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5343 @c VALID-VALUEs (if any) specify which values the variable can have.
5344 They have the same type (i.e. having the same key) as @c VALUE except
5345 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5346 may be a plist of two integers specifying the range of possible
5349 If there no @c VALID-VALUE, the variable can have any value as long
5350 as the type is the same as @c VALUE.
5352 If $VARIABLE is not #Mnil, the first element of the returned plist
5353 contains the information about $VARIABLE.
5357 If the requested information was found, a pointer to a non-empty
5358 plist is returned. As the plist is kept in the library, the
5359 caller must not modify nor free it.
5361 Otherwise (the specified input method or the specified variable
5362 does not exist), @c NULL is returned. */
5364 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5366 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5367 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5368 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5370 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5371 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5372 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5373 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5376 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5377 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5379 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5381 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5383 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5386 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5388 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5391 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5392 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, @b Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5393 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, @b Mconfigured
5394 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5395 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢@b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5396 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5398 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5399 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5400 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5402 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5403 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5404 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5405 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5407 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5410 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5411 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5415 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5416 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5419 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5423 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5425 MInputMethodInfo *im_info;
5429 im_info = get_im_info (language, name, Mnil, Mvariable);
5430 if (! im_info || ! im_info->configured_vars)
5432 if (variable == Mnil)
5433 return im_info->configured_vars;
5434 return mplist__assq (im_info->configured_vars, variable);
5440 @brief Configure the value of an input method variable.
5442 The minput_config_variable () function assigns $VALUE to the
5443 variable $VARIABLE of the input method specified by $LANGUAGE and
5446 If $VALUE is a non-empty plist, it must be a plist of one element
5447 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5448 the corresponding type. That value is assigned to the variable.
5450 If $VALUE is an empty plist, any configuration and customization
5451 of the variable are canceled, and the default value is assigned to
5454 If $VALUE is NULL, the configuration of the variable is canceled,
5455 and the original value (what saved in per-user customization file,
5456 or the default value) is assigned to the variable.
5458 In the latter two cases, $VARIABLE can be #Mnil to make all the
5459 variables of the input method the target of the operation.
5461 If $NAME is #Mnil, this function configures the value of global
5462 variable, not that of a specific input method.
5464 The configuration takes effect for input methods opened or
5465 re-opened later in the current session. To make the configuration
5466 take effect for the future session, it must be saved in a per-user
5467 customization file by the function minput_save_config ().
5471 If the operation was successful, this function returns 0,
5472 otherwise returns -1. The operation fails in these cases:
5474 <li>$VALUE is not in a valid form, the type does not match the
5475 definition, or the value is our of range.
5476 <li>$VARIABLE is not available for the input method.
5477 <li>$LANGUAGE and $NAME do not specify an existing input method.
5481 minput_get_variable (), minput_save_config (). */
5483 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5485 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5486 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5488 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5489 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5490 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5492 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5493 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5495 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5496 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5498 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5499 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5501 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5502 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5504 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5505 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5506 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5507 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5511 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5513 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5514 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5515 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5519 minput_get_commands (), minput_save_config ().
5522 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5525 MInputMethodInfo *im_info, *config;
5530 im_info = get_im_info (language, name, Mnil, Mvariable);
5532 MERROR (MERROR_IM, -1);
5533 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5535 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5536 MERROR (MERROR_IM, -1);
5538 if (value && ! MPLIST_TAIL_P (value))
5540 plist = MPLIST_PLIST (plist);
5541 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5542 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5543 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5544 if (MPLIST_KEY (plist) != Mt
5545 && ! check_variable_value (value, plist))
5546 MERROR (MERROR_IM, -1);
5549 config = get_config_info (im_info);
5552 if (! im_config_list)
5553 im_config_list = mplist ();
5554 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5555 config->cmds = mplist ();
5556 config->vars = mplist ();
5559 if (! value && MPLIST_TAIL_P (config->vars))
5560 /* Nothing to do. */
5563 if (variable == Mnil)
5567 /* Cancel the configuration. */
5568 if (MPLIST_TAIL_P (config->vars))
5570 mplist_set (config->vars, Mnil, NULL);
5574 /* Cancel the customization. */
5575 MInputMethodInfo *custom = get_custom_info (im_info);
5577 if (MPLIST_TAIL_P (config->vars)
5578 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5579 /* Nothing to do. */
5581 mplist_set (config->vars, Mnil, NULL);
5582 MPLIST_DO (plist, custom->vars)
5584 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5586 mplist_add (plist, Msymbol, variable);
5587 mplist_push (config->vars, Mplist, plist);
5588 M17N_OBJECT_UNREF (plist);
5594 plist = mplist__assq (config->vars, variable);
5597 /* Cancel the configuration. */
5600 mplist__pop_unref (plist);
5602 else if (MPLIST_TAIL_P (value))
5604 /* Cancel the customization. */
5605 MInputMethodInfo *custom = get_custom_info (im_info);
5606 int no_custom = (! custom || ! custom->vars
5607 || ! mplist__assq (custom->vars, variable));
5613 mplist_add (config->vars, Mplist, plist);
5614 M17N_OBJECT_UNREF (plist);
5615 plist = mplist_add (plist, Msymbol, variable);
5620 mplist__pop_unref (plist);
5623 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5624 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5625 mplist_set (plist, Mnil ,NULL);
5633 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5634 if (! MPLIST_TAIL_P (plist))
5635 mplist_set (plist, Mnil, NULL);
5640 mplist_add (config->vars, Mplist, plist);
5641 M17N_OBJECT_UNREF (plist);
5642 plist = mplist_add (plist, Msymbol, variable);
5643 plist = MPLIST_NEXT (plist);
5645 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5648 config_all_variables (im_info);
5649 im_info->tick = time (NULL);
5656 @brief Get the name of per-user customization file.
5658 The minput_config_file () function returns the absolute path name
5659 of per-user customization file into which minput_save_config ()
5660 save configurations. It is usually @c config.mic under the
5661 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5662 directory). It is not assured that the file of the returned name
5663 exists nor is readable/writable. If minput_save_config () fails
5664 and returns -1, an application program might check the file, make
5665 it writable (if possible), and try minput_save_config () again.
5669 This function returns a string. As the string is kept in the
5670 library, the caller must not modify nor free it.
5673 minput_save_config ()
5676 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5678 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5679 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5680 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5681 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5682 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5683 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5684 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5689 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5690 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5693 minput_save_config ()
5697 minput_config_file ()
5701 return mdatabase__file (im_custom_mdb);
5707 @brief Save configurations in per-user customization file.
5709 The minput_save_config () function saves the configurations done
5710 so far in the current session into the per-user customization
5715 If the operation was successful, 1 is returned. If the per-user
5716 customization file is currently locked, 0 is returned. In that
5717 case, the caller may wait for a while and try again. If the
5718 configuration file is not writable, -1 is returned. In that case,
5719 the caller may check the name of the file by calling
5720 minput_config_file (), make it writable if possible, and try
5724 minput_config_file () */
5726 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5728 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5729 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5733 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5734 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5735 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5736 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5740 minput_config_file () */
5743 minput_save_config (void)
5745 MPlist *data, *tail, *plist, *p, *elt;
5749 ret = mdatabase__lock (im_custom_mdb);
5752 if (! im_config_list)
5754 update_custom_info ();
5755 if (! im_custom_list)
5756 im_custom_list = mplist ();
5758 /* At first, reflect configuration in customization. */
5759 MPLIST_DO (plist, im_config_list)
5761 MPlist *pl = MPLIST_PLIST (plist);
5762 MSymbol language, name, extra, command, variable;
5763 MInputMethodInfo *custom, *config;
5765 language = MPLIST_SYMBOL (pl);
5766 pl = MPLIST_NEXT (pl);
5767 name = MPLIST_SYMBOL (pl);
5768 pl = MPLIST_NEXT (pl);
5769 extra = MPLIST_SYMBOL (pl);
5770 pl = MPLIST_NEXT (pl);
5771 config = MPLIST_VAL (pl);
5772 custom = get_custom_info (config);
5774 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5776 MPLIST_DO (pl, config->cmds)
5778 elt = MPLIST_PLIST (pl);
5779 command = MPLIST_SYMBOL (elt);
5781 p = mplist__assq (custom->cmds, command);
5783 custom->cmds = mplist (), p = NULL;
5784 elt = MPLIST_NEXT (elt);
5787 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5788 mplist_set (p, Mnil, NULL);
5793 mplist_add (custom->cmds, Mplist, p);
5794 M17N_OBJECT_UNREF (p);
5795 mplist_add (p, Msymbol, command);
5796 p = mplist_add (p, Msymbol, Mnil);
5797 p = MPLIST_NEXT (p);
5799 mplist__conc (p, elt);
5802 MPLIST_DO (pl, config->vars)
5804 elt = MPLIST_PLIST (pl);
5805 variable = MPLIST_SYMBOL (elt);
5807 p = mplist__assq (custom->vars, variable);
5809 custom->vars = mplist (), p = NULL;
5810 elt = MPLIST_NEXT (elt);
5813 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5814 mplist_set (p, Mnil, NULL);
5819 mplist_add (custom->vars, Mplist, p);
5820 M17N_OBJECT_UNREF (p);
5821 mplist_add (p, Msymbol, variable);
5822 p = mplist_add (p, Msymbol, Mnil);
5823 p = MPLIST_NEXT (p);
5825 mplist__conc (p, elt);
5828 free_im_list (im_config_list);
5829 im_config_list = NULL;
5831 /* Next, reflect customization to the actual plist to be written. */
5832 data = tail = mplist ();
5833 MPLIST_DO (plist, im_custom_list)
5835 MPlist *pl = MPLIST_PLIST (plist);
5836 MSymbol language, name, extra;
5837 MInputMethodInfo *custom, *im_info;
5839 language = MPLIST_SYMBOL (pl);
5840 pl = MPLIST_NEXT (pl);
5841 name = MPLIST_SYMBOL (pl);
5842 pl = MPLIST_NEXT (pl);
5843 extra = MPLIST_SYMBOL (pl);
5844 pl = MPLIST_NEXT (pl);
5845 custom = MPLIST_VAL (pl);
5846 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5847 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5849 im_info = lookup_im_info (im_info_list, language, name, extra);
5853 config_all_commands (im_info);
5855 config_all_variables (im_info);
5859 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5861 MPLIST_DO (p, custom->cmds)
5862 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5864 if (! MPLIST_TAIL_P (p))
5868 mplist_add (elt, Mplist, pl);
5869 M17N_OBJECT_UNREF (pl);
5870 pl = mplist_add (pl, Msymbol, Mcommand);
5871 MPLIST_DO (p, custom->cmds)
5872 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5873 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5876 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5878 MPLIST_DO (p, custom->vars)
5879 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5881 if (! MPLIST_TAIL_P (p))
5886 mplist_add (elt, Mplist, pl);
5887 M17N_OBJECT_UNREF (pl);
5888 pl = mplist_add (pl, Msymbol, Mvariable);
5889 MPLIST_DO (p, custom->vars)
5890 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5891 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5897 mplist_push (elt, Mplist, pl);
5898 M17N_OBJECT_UNREF (pl);
5899 pl = mplist_add (pl, Msymbol, Minput_method);
5900 pl = mplist_add (pl, Msymbol, language);
5901 pl = mplist_add (pl, Msymbol, name);
5903 pl = mplist_add (pl, Msymbol, extra);
5904 tail = mplist_add (tail, Mplist, elt);
5905 M17N_OBJECT_UNREF (elt);
5909 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5910 ret = mdatabase__save (im_custom_mdb, data);
5911 mdatabase__unlock (im_custom_mdb);
5912 M17N_OBJECT_UNREF (data);
5913 return (ret < 0 ? -1 : 1);
5920 @name Obsolete functions
5923 @name Obsolete ¤Ê´Ø¿ô
5929 @brief Get a list of variables of an input method (obsolete).
5931 This function is obsolete. Use minput_get_variable () instead.
5933 The minput_get_variables () function returns a plist (#MPlist) of
5934 variables used to control the behavior of the input method
5935 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5936 (@ref m17nPlist) of the following format:
5939 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5940 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5944 @c VARNAME is a symbol representing the variable name.
5946 @c DOC-MTEXT is an M-text describing the variable.
5948 @c DEFAULT-VALUE is the default value of the variable. It is a
5949 symbol, integer, or M-text.
5951 @c VALUEs (if any) specifies the possible values of the variable.
5952 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5953 @c TO), where @c FROM and @c TO specifies a range of possible
5956 For instance, suppose an input method has the variables:
5958 @li name:intvar, description:"value is an integer",
5959 initial value:0, value-range:0..3,10,20
5961 @li name:symvar, description:"value is a symbol",
5962 initial value:nil, value-range:a, b, c, nil
5964 @li name:txtvar, description:"value is an M-text",
5965 initial value:empty text, no value-range (i.e. any text)
5967 Then, the returned plist is as follows.
5970 (intvar ("value is an integer" 0 (0 3) 10 20)
5971 symvar ("value is a symbol" nil a b c nil)
5972 txtvar ("value is an M-text" ""))
5976 If the input method uses any variables, a pointer to #MPlist is
5977 returned. As the plist is kept in the library, the caller must not
5978 modify nor free it. If the input method does not use any
5979 variable, @c NULL is returned. */
5981 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5983 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5984 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5985 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5989 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5990 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5994 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5996 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5998 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
6001 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
6002 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
6003 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
6005 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
6007 @li name:intvar, ÀâÌÀ:"value is an integer",
6008 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
6010 @li name:symvar, ÀâÌÀ:"value is a symbol",
6011 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
6013 @li name:txtvar, ÀâÌÀ:"value is an M-text",
6014 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
6016 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
6019 (intvar ("value is an integer" 0 (0 3) 10 20)
6020 symvar ("value is a symbol" nil a b c nil)
6021 txtvar ("value is an M-text" ""))
6025 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
6026 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6027 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
6030 minput_get_variables (MSymbol language, MSymbol name)
6032 MInputMethodInfo *im_info;
6037 im_info = get_im_info (language, name, Mnil, Mvariable);
6038 if (! im_info || ! im_info->configured_vars)
6041 M17N_OBJECT_UNREF (im_info->bc_vars);
6042 im_info->bc_vars = mplist ();
6043 MPLIST_DO (vars, im_info->configured_vars)
6045 MPlist *plist = MPLIST_PLIST (vars);
6046 MPlist *elt = mplist ();
6048 mplist_push (im_info->bc_vars, Mplist, elt);
6049 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6050 elt = MPLIST_NEXT (elt);
6051 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6052 M17N_OBJECT_UNREF (elt);
6054 return im_info->bc_vars;
6060 @brief Set the initial value of an input method variable.
6062 The minput_set_variable () function sets the initial value of
6063 input method variable $VARIABLE to $VALUE for the input method
6064 specified by $LANGUAGE and $NAME.
6066 By default, the initial value is 0.
6068 This setting gets effective in a newly opened input method.
6071 If the operation was successful, 0 is returned. Otherwise -1 is
6072 returned, and #merror_code is set to @c MERROR_IM. */
6074 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6076 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6077 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6078 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6080 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6082 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6085 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6086 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6089 minput_set_variable (MSymbol language, MSymbol name,
6090 MSymbol variable, void *value)
6093 MInputMethodInfo *im_info;
6098 if (variable == Mnil)
6099 MERROR (MERROR_IM, -1);
6100 plist = minput_get_variable (language, name, variable);
6101 plist = MPLIST_PLIST (plist);
6102 plist = MPLIST_NEXT (plist);
6104 mplist_add (pl, MPLIST_KEY (plist), value);
6105 ret = minput_config_variable (language, name, variable, pl);
6106 M17N_OBJECT_UNREF (pl);
6109 im_info = get_im_info (language, name, Mnil, Mvariable);
6118 @brief Get information about input method commands.
6120 The minput_get_commands () function returns information about
6121 input method commands of the input method specified by $LANGUAGE
6122 and $NAME. An input method command is a pseudo key event to which
6123 one or more actual input key sequences are assigned.
6125 There are two kinds of commands, global and local. Global
6126 commands are used by multiple input methods for the same purpose,
6127 and have global key assignments. Local commands are used only by
6128 a specific input method, and have only local key assignments.
6130 Each input method may locally change key assignments for global
6131 commands. The global key assignment for a global command is
6132 effective only when the current input method does not have local
6133 key assignments for that command.
6135 If $NAME is #Mnil, information about global commands is returned.
6136 In this case $LANGUAGE is ignored.
6138 If $NAME is not #Mnil, information about those commands that have
6139 local key assignments in the input method specified by $LANGUAGE
6140 and $NAME is returned.
6143 If no input method commands are found, this function returns @c NULL.
6145 Otherwise, a pointer to a plist is returned. The key of each
6146 element in the plist is a symbol representing a command, and the
6147 value is a plist of the form COMMAND-INFO described below.
6149 The first element of COMMAND-INFO has the key #Mtext, and the
6150 value is an M-text describing the command.
6152 If there are no more elements, that means no key sequences are
6153 assigned to the command. Otherwise, each of the remaining
6154 elements has the key #Mplist, and the value is a plist whose keys are
6155 #Msymbol and values are symbols representing input keys, which are
6156 currently assigned to the command.
6158 As the returned plist is kept in the library, the caller must not
6159 modify nor free it. */
6161 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6163 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6164 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6165 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6166 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6168 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6169 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6170 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6171 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6173 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6174 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6175 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6178 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6179 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6181 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6182 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6186 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6188 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6189 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6190 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6192 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6193 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6194 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6197 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6198 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6199 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6200 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6201 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6203 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6204 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6207 minput_get_commands (MSymbol language, MSymbol name)
6209 MInputMethodInfo *im_info;
6214 im_info = get_im_info (language, name, Mnil, Mcommand);
6215 if (! im_info || ! im_info->configured_vars)
6217 M17N_OBJECT_UNREF (im_info->bc_cmds);
6218 im_info->bc_cmds = mplist ();
6219 MPLIST_DO (cmds, im_info->configured_cmds)
6221 MPlist *plist = MPLIST_PLIST (cmds);
6222 MPlist *elt = mplist ();
6224 mplist_push (im_info->bc_cmds, Mplist, elt);
6225 mplist_add (elt, MPLIST_SYMBOL (plist),
6226 mplist_copy (MPLIST_NEXT (plist)));
6227 M17N_OBJECT_UNREF (elt);
6229 return im_info->bc_cmds;
6235 @brief Assign a key sequence to an input method command (obsolete).
6237 This function is obsolete. Use minput_config_command () instead.
6239 The minput_assign_command_keys () function assigns input key
6240 sequence $KEYSEQ to input method command $COMMAND for the input
6241 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6242 key sequence is assigned globally no matter what $LANGUAGE is.
6243 Otherwise the key sequence is assigned locally.
6245 Each element of $KEYSEQ must have the key $Msymbol and the value
6246 must be a symbol representing an input key.
6248 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6249 globally or locally.
6251 This assignment gets effective in a newly opened input method.
6254 If the operation was successful, 0 is returned. Otherwise -1 is
6255 returned, and #merror_code is set to @c MERROR_IM. */
6257 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6259 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6260 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6261 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6262 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6263 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6265 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6266 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6268 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6269 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6271 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6275 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6276 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6279 minput_assign_command_keys (MSymbol language, MSymbol name,
6280 MSymbol command, MPlist *keyseq)
6286 if (command == Mnil)
6287 MERROR (MERROR_IM, -1);
6292 if (! check_command_keyseq (keyseq))
6293 MERROR (MERROR_IM, -1);
6295 mplist_add (plist, Mplist, keyseq);
6300 ret = minput_config_command (language, name, command, keyseq);
6301 M17N_OBJECT_UNREF (keyseq);
6308 @brief Call a callback function
6310 The minput_callback () functions calls a callback function
6311 $COMMAND assigned for the input context $IC. The caller must set
6312 specific elements in $IC->plist if the callback function requires.
6315 If there exists a specified callback function, 0 is returned.
6316 Otherwise -1 is returned. By side effects, $IC->plist may be
6320 minput_callback (MInputContext *ic, MSymbol command)
6322 MInputCallbackFunc func;
6324 if (! ic->im->driver.callback_list)
6326 func = ((MInputCallbackFunc)
6327 mplist_get_func (ic->im->driver.callback_list, command));
6330 (func) (ic, command);
6337 /*** @addtogroup m17nDebug */
6343 @brief Dump an input method.
6345 The mdebug_dump_im () function prints the input method $IM in a
6346 human readable way to the stderr. $INDENT specifies how many
6347 columns to indent the lines but the first one.
6350 This function returns $IM. */
6352 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6354 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6355 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6358 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6361 mdebug_dump_im (MInputMethod *im, int indent)
6363 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6366 prefix = (char *) alloca (indent + 1);
6367 memset (prefix, 32, indent);
6368 prefix[indent] = '\0';
6370 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6371 msymbol_name (im->name));
6372 mdebug_dump_mtext (im_info->title, 0, 0);
6373 if (im->name != Mnil)
6377 MPLIST_DO (state, im_info->states)
6379 fprintf (stderr, "\n%s ", prefix);
6380 dump_im_state (MPLIST_VAL (state), indent + 2);
6383 fprintf (stderr, ")");